diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 84b1da16d75817b502bfaeee3372cb22a36d53fd..33ae1bddbaebc73f29f9aa5acf1a2b068e0ffd99 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -157,10 +157,7 @@ obj-$(CONFIG_MSM_DALRPC) += dal.o obj-$(CONFIG_MSM_DALRPC_TEST) += dal_remotetest.o obj-$(CONFIG_ARCH_MSM7X30) += dal_axi.o obj-$(CONFIG_ARCH_MSM7X27A) += dal_axi.o -obj-$(CONFIG_MSM_ADSP) += qdsp5/ -obj-$(CONFIG_MSM7KV2_AUDIO) += qdsp5v2/ obj-$(CONFIG_MSM_RPCSERVER_HANDSET) += rpc_server_handset.o -obj-$(CONFIG_MSM_QDSP6) += qdsp6/ obj-$(CONFIG_MSM8X60_AUDIO) += qdsp6v2/ obj-$(CONFIG_MSM_AUDIO_QDSP6) += qdsp6v2/ obj-$(CONFIG_MSM_AUDIO_QDSP6V2) += qdsp6v2/ diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaycmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaycmdi.h deleted file mode 100644 index 67ee5490486a6aaeda2ac538966fa2a35bcaea52..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaycmdi.h +++ /dev/null @@ -1,129 +0,0 @@ -#ifndef QDSP5AUDPLAYCMDI_H -#define QDSP5AUDPLAYCMDI_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - - Q D S P 5 A U D I O P L A Y T A S K C O M M A N D S - -GENERAL DESCRIPTION - Command Interface for AUDPLAYTASK on QDSP5 - -REFERENCES - None - -EXTERNALIZED FUNCTIONS - - audplay_cmd_dec_data_avail - Send buffer to AUDPLAY task - - -Copyright (c) 1992-2009, The Linux Foundation. All rights reserved. - -This software is licensed under the terms of the GNU General Public -License version 2, as published by the Free Software Foundation, and -may be copied, distributed, and modified under those terms. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ -/*=========================================================================== - - EDIT HISTORY FOR FILE - -This section contains comments describing changes made to this file. -Notice that changes are listed in reverse chronological order. - -$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audplaycmdi.h#2 $ - -===========================================================================*/ - -#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL 0x0000 -#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_LEN \ - sizeof(audplay_cmd_bitstream_data_avail) - -/* Type specification of dec_data_avail message sent to AUDPLAYTASK -*/ -typedef struct { - /*command ID*/ - unsigned int cmd_id; - - /* Decoder ID for which message is being sent */ - unsigned int decoder_id; - - /* Start address of data in ARM global memory */ - unsigned int buf_ptr; - - /* Number of 16-bit words of bit-stream data contiguously available at the - * above-mentioned address - */ - unsigned int buf_size; - - /* Partition number used by audPlayTask to communicate with DSP's RTOS - * kernel - */ - unsigned int partition_number; - -} __attribute__((packed)) audplay_cmd_bitstream_data_avail; - -#define AUDPLAY_CMD_HPCM_BUF_CFG 0x0003 -#define AUDPLAY_CMD_HPCM_BUF_CFG_LEN \ - sizeof(struct audplay_cmd_hpcm_buf_cfg) - -struct audplay_cmd_hpcm_buf_cfg { - unsigned int cmd_id; - unsigned int hostpcm_config; - unsigned int feedback_frequency; - unsigned int byte_swap; - unsigned int max_buffers; - unsigned int partition_number; -} __attribute__((packed)); - -#define AUDPLAY_CMD_BUFFER_REFRESH 0x0004 -#define AUDPLAY_CMD_BUFFER_REFRESH_LEN \ - sizeof(struct audplay_cmd_buffer_update) - -struct audplay_cmd_buffer_refresh { - unsigned int cmd_id; - unsigned int num_buffers; - unsigned int buf_read_count; - unsigned int buf0_address; - unsigned int buf0_length; - unsigned int buf1_address; - unsigned int buf1_length; -} __attribute__((packed)); - -#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2 0x0005 -#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2_LEN \ - sizeof(audplay_cmd_bitstream_data_avail_nt2) - -/* Type specification of dec_data_avail message sent to AUDPLAYTASK - * for NT2 */ -struct audplay_cmd_bitstream_data_avail_nt2 { - /*command ID*/ - unsigned int cmd_id; - - /* Decoder ID for which message is being sent */ - unsigned int decoder_id; - - /* Start address of data in ARM global memory */ - unsigned int buf_ptr; - - /* Number of 16-bit words of bit-stream data contiguously available at the - * above-mentioned address - */ - unsigned int buf_size; - - /* Partition number used by audPlayTask to communicate with DSP's RTOS - * kernel - */ - unsigned int partition_number; - - /* bitstream write pointer */ - unsigned int dspBitstreamWritePtr; - -} __attribute__((packed)); - -#endif /* QDSP5AUDPLAYCMD_H */ diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaymsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaymsg.h deleted file mode 100644 index e79554afb955b5ef41a71dc04c40e90667723f1a..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaymsg.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef QDSP5AUDPLAYMSG_H -#define QDSP5AUDPLAYMSG_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - - Q D S P 5 A U D I O P L A Y T A S K M S G - -GENERAL DESCRIPTION - Message sent by AUDPLAY task - -REFERENCES - None - - -Copyright (c) 1992-2009, The Linux Foundation. All rights reserved. - -This software is licensed under the terms of the GNU General Public -License version 2, as published by the Free Software Foundation, and -may be copied, distributed, and modified under those terms. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ -/*=========================================================================== - - EDIT HISTORY FOR FILE - -This section contains comments describing changes made to this file. -Notice that changes are listed in reverse chronological order. - -$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audplaymsg.h#3 $ - -===========================================================================*/ -#define AUDPLAY_MSG_DEC_NEEDS_DATA 0x0001 -#define AUDPLAY_MSG_DEC_NEEDS_DATA_MSG_LEN \ - sizeof(audplay_msg_dec_needs_data) - -typedef struct{ - /* reserved*/ - unsigned int dec_id; - - /*The read pointer offset of external memory till which bitstream - has been dme’d in*/ - unsigned int adecDataReadPtrOffset; - - /* The buffer size of external memory. */ - unsigned int adecDataBufSize; - - unsigned int bitstream_free_len; - unsigned int bitstream_write_ptr; - unsigned int bitstarem_buf_start; - unsigned int bitstream_buf_len; -} __attribute__((packed)) audplay_msg_dec_needs_data; - -#define AUDPLAY_UP_STREAM_INFO 0x0003 -#define AUDPLAY_UP_STREAM_INFO_LEN \ - sizeof(struct audplay_msg_stream_info) - -struct audplay_msg_stream_info { - unsigned int decoder_id; - unsigned int channel_info; - unsigned int sample_freq; - unsigned int bitstream_info; - unsigned int bit_rate; -} __attribute__((packed)); - -#define AUDPLAY_MSG_BUFFER_UPDATE 0x0004 -#define AUDPLAY_MSG_BUFFER_UPDATE_LEN \ - sizeof(struct audplay_msg_buffer_update) - -struct audplay_msg_buffer_update { - unsigned int buffer_write_count; - unsigned int num_of_buffer; - unsigned int buf0_address; - unsigned int buf0_length; - unsigned int buf1_address; - unsigned int buf1_length; -} __attribute__((packed)); - -#define ADSP_MESSAGE_ID 0xFFFF -#endif /* QDSP5AUDPLAYMSG_H */ diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppcmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppcmdi.h deleted file mode 100644 index 83fea39c232084dd1b28bb20a8bdab665092f9ff..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppcmdi.h +++ /dev/null @@ -1,1051 +0,0 @@ -#ifndef QDSP5AUDPPCMDI_H -#define QDSP5AUDPPCMDI_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - - A U D I O P O S T P R O C E S S I N G I N T E R N A L C O M M A N D S - -GENERAL DESCRIPTION - This file contains defintions of format blocks of commands - that are accepted by AUDPP Task - -REFERENCES - None - -EXTERNALIZED FUNCTIONS - None - -Copyright(c) 1992-2009, 2012 The Linux Foundation. All rights reserved. - -This software is licensed under the terms of the GNU General Public -License version 2, as published by the Free Software Foundation, and -may be copied, distributed, and modified under those terms. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ -/*=========================================================================== - - EDIT HISTORY FOR FILE - -This section contains comments describing changes made to this file. -Notice that changes are listed in reverse chronological order. - -$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audppcmdi.h#2 $ - -===========================================================================*/ - -/* - * ARM to AUDPPTASK Commands - * - * ARM uses three command queues to communicate with AUDPPTASK - * 1)uPAudPPCmd1Queue : Used for more frequent and shorter length commands - * Location : MEMA - * Buffer Size : 6 words - * No of buffers in a queue : 20 for gaming audio and 5 for other images - * 2)uPAudPPCmd2Queue : Used for commands which are not much lengthier - * Location : MEMA - * Buffer Size : 23 - * No of buffers in a queue : 2 - * 3)uPAudOOCmd3Queue : Used for lengthier and more frequent commands - * Location : MEMA - * Buffer Size : 145 - * No of buffers in a queue : 3 - */ - -/* - * Commands Related to uPAudPPCmd1Queue - */ - -/* - * Command Structure to enable or disable the active decoders - */ - -#define AUDPP_CMD_CFG_DEC_TYPE 0x0001 -#define AUDPP_CMD_CFG_DEC_TYPE_LEN sizeof(audpp_cmd_cfg_dec_type) - -/* Enable the decoder */ -#define AUDPP_CMD_DEC_TYPE_M 0x000F - -#define AUDPP_CMD_ENA_DEC_V 0x4000 -#define AUDPP_CMD_DIS_DEC_V 0x0000 -#define AUDPP_CMD_DEC_STATE_M 0x4000 -#define AUDPP_CMD_LPA_MODE 0x2000 - -#define AUDPP_CMD_UPDATDE_CFG_DEC 0x8000 -#define AUDPP_CMD_DONT_UPDATE_CFG_DEC 0x0000 - - -/* Type specification of cmd_cfg_dec */ - -typedef struct { - unsigned short cmd_id; - unsigned short dec0_cfg; - unsigned short dec1_cfg; - unsigned short dec2_cfg; - unsigned short dec3_cfg; - unsigned short dec4_cfg; -} __attribute__((packed)) audpp_cmd_cfg_dec_type; - -/* - * Command Structure to Pause , Resume and flushes the selected audio decoders - */ - -#define AUDPP_CMD_DEC_CTRL 0x0002 -#define AUDPP_CMD_DEC_CTRL_LEN sizeof(audpp_cmd_dec_ctrl) - -/* Decoder control commands for pause, resume and flush */ -#define AUDPP_CMD_FLUSH_V 0x2000 - -#define AUDPP_CMD_PAUSE_V 0x4000 -#define AUDPP_CMD_RESUME_V 0x0000 - -#define AUDPP_CMD_UPDATE_V 0x8000 -#define AUDPP_CMD_IGNORE_V 0x0000 - - -/* Type Spec for decoder control command*/ - -typedef struct { - unsigned short cmd_id; - unsigned short dec0_ctrl; - unsigned short dec1_ctrl; - unsigned short dec2_ctrl; - unsigned short dec3_ctrl; - unsigned short dec4_ctrl; -} __attribute__((packed)) audpp_cmd_dec_ctrl; - -/* - * Command Structure to Configure the AVSync FeedBack Mechanism - */ - -#define AUDPP_CMD_AVSYNC 0x0003 -#define AUDPP_CMD_AVSYNC_LEN sizeof(audpp_cmd_avsync) - -typedef struct { - unsigned short cmd_id; - unsigned short object_number; - unsigned short interrupt_interval_lsw; - unsigned short interrupt_interval_msw; -} __attribute__((packed)) audpp_cmd_avsync; - -/* - * Command Structure to enable or disable(sleep) the AUDPPTASK - */ - -#define AUDPP_CMD_CFG 0x0004 -#define AUDPP_CMD_CFG_LEN sizeof(audpp_cmd_cfg) - -#define AUDPP_CMD_CFG_SLEEP 0x0000 -#define AUDPP_CMD_CFG_ENABLE 0xFFFF - -typedef struct { - unsigned short cmd_id; - unsigned short cfg; -} __attribute__((packed)) audpp_cmd_cfg; - -/* - * Command Structure to Inject or drop the specified no of samples - */ - -#define AUDPP_CMD_ADJUST_SAMP 0x0005 -#define AUDPP_CMD_ADJUST_SAMP_LEN sizeof(audpp_cmd_adjust_samp) - -#define AUDPP_CMD_SAMP_DROP -1 -#define AUDPP_CMD_SAMP_INSERT 0x0001 - -#define AUDPP_CMD_NUM_SAMPLES 0x0001 - -typedef struct { - unsigned short cmd_id; - unsigned short object_no; - signed short sample_insert_or_drop; - unsigned short num_samples; -} __attribute__((packed)) audpp_cmd_adjust_samp; - -/* - * Command Structure to Configure AVSync Feedback Mechanism - */ - -#define AUDPP_CMD_AVSYNC_CMD_2 0x0006 -#define AUDPP_CMD_AVSYNC_CMD_2_LEN sizeof(audpp_cmd_avsync_cmd_2) - -typedef struct { - unsigned short cmd_id; - unsigned short object_number; - unsigned short interrupt_interval_lsw; - unsigned short interrupt_interval_msw; - unsigned short sample_counter_dlsw; - unsigned short sample_counter_dmsw; - unsigned short sample_counter_msw; - unsigned short byte_counter_dlsw; - unsigned short byte_counter_dmsw; - unsigned short byte_counter_msw; -} __attribute__((packed)) audpp_cmd_avsync_cmd_2; - -/* - * Command Structure to Configure AVSync Feedback Mechanism - */ - -#define AUDPP_CMD_AVSYNC_CMD_3 0x0007 -#define AUDPP_CMD_AVSYNC_CMD_3_LEN sizeof(audpp_cmd_avsync_cmd_3) - -typedef struct { - unsigned short cmd_id; - unsigned short object_number; - unsigned short interrupt_interval_lsw; - unsigned short interrupt_interval_msw; - unsigned short sample_counter_dlsw; - unsigned short sample_counter_dmsw; - unsigned short sample_counter_msw; - unsigned short byte_counter_dlsw; - unsigned short byte_counter_dmsw; - unsigned short byte_counter_msw; -} __attribute__((packed)) audpp_cmd_avsync_cmd_3; - -#define AUDPP_CMD_ROUTING_MODE 0x0008 -#define AUDPP_CMD_ROUTING_MODE_LEN \ -sizeof(struct audpp_cmd_routing_mode) - -struct audpp_cmd_routing_mode { - unsigned short cmd_id; - unsigned short object_number; - unsigned short routing_mode; -} __attribute__((packed)); - -/* - * Commands Related to uPAudPPCmd2Queue - */ - -/* - * Command Structure to configure Per decoder Parameters (Common) - */ - -#define AUDPP_CMD_CFG_ADEC_PARAMS 0x0000 -#define AUDPP_CMD_CFG_ADEC_PARAMS_COMMON_LEN \ - sizeof(audpp_cmd_cfg_adec_params_common) - -#define AUDPP_CMD_STATUS_MSG_FLAG_ENA_FCM 0x4000 -#define AUDPP_CMD_STATUS_MSG_FLAG_DIS_FCM 0x0000 - -#define AUDPP_CMD_STATUS_MSG_FLAG_ENA_DCM 0x8000 -#define AUDPP_CMD_STATUS_MSG_FLAG_DIS_DCM 0x0000 - -/* Sampling frequency*/ -#define AUDPP_CMD_SAMP_RATE_96000 0x0000 -#define AUDPP_CMD_SAMP_RATE_88200 0x0001 -#define AUDPP_CMD_SAMP_RATE_64000 0x0002 -#define AUDPP_CMD_SAMP_RATE_48000 0x0003 -#define AUDPP_CMD_SAMP_RATE_44100 0x0004 -#define AUDPP_CMD_SAMP_RATE_32000 0x0005 -#define AUDPP_CMD_SAMP_RATE_24000 0x0006 -#define AUDPP_CMD_SAMP_RATE_22050 0x0007 -#define AUDPP_CMD_SAMP_RATE_16000 0x0008 -#define AUDPP_CMD_SAMP_RATE_12000 0x0009 -#define AUDPP_CMD_SAMP_RATE_11025 0x000A -#define AUDPP_CMD_SAMP_RATE_8000 0x000B - - -/* - * Type specification of cmd_adec_cfg sent to all decoder - */ - -typedef struct { - unsigned short cmd_id; - unsigned short length; - unsigned short dec_id; - unsigned short status_msg_flag; - unsigned short decoder_frame_counter_msg_period; - unsigned short input_sampling_frequency; -} __attribute__((packed)) audpp_cmd_cfg_adec_params_common; - -/* - * Command Structure to configure Per decoder Parameters (Wav) - */ - -#define AUDPP_CMD_CFG_ADEC_PARAMS_WAV_LEN \ - sizeof(audpp_cmd_cfg_adec_params_wav) - - -#define AUDPP_CMD_WAV_STEREO_CFG_MONO 0x0001 -#define AUDPP_CMD_WAV_STEREO_CFG_STEREO 0x0002 - -#define AUDPP_CMD_WAV_PCM_WIDTH_8 0x0000 -#define AUDPP_CMD_WAV_PCM_WIDTH_16 0x0001 -#define AUDPP_CMD_WAV_PCM_WIDTH_24 0x0002 - -typedef struct { - audpp_cmd_cfg_adec_params_common common; - unsigned short stereo_cfg; - unsigned short pcm_width; - unsigned short sign; -} __attribute__((packed)) audpp_cmd_cfg_adec_params_wav; - -/* - * Command Structure to configure Per decoder Parameters (ADPCM) - */ - -#define AUDPP_CMD_CFG_ADEC_PARAMS_ADPCM_LEN \ - sizeof(audpp_cmd_cfg_adec_params_adpcm) - - -#define AUDPP_CMD_ADPCM_STEREO_CFG_MONO 0x0001 -#define AUDPP_CMD_ADPCM_STEREO_CFG_STEREO 0x0002 - -typedef struct { - audpp_cmd_cfg_adec_params_common common; - unsigned short stereo_cfg; - unsigned short block_size; -} __attribute__((packed)) audpp_cmd_cfg_adec_params_adpcm; - -/* - * Command Structure to configure Per decoder Parameters (WMA) - */ - -#define AUDPP_CMD_CFG_ADEC_PARAMS_WMA_LEN \ - sizeof(struct audpp_cmd_cfg_adec_params_wma) - -struct audpp_cmd_cfg_adec_params_wma { - audpp_cmd_cfg_adec_params_common common; - unsigned short armdatareqthr; - unsigned short channelsdecoded; - unsigned short wmabytespersec; - unsigned short wmasamplingfreq; - unsigned short wmaencoderopts; -} __attribute__((packed)); - -/* - * Command Structure to configure Per decoder Parameters (WMAPRO) - */ - -#define AUDPP_CMD_CFG_ADEC_PARAMS_WMAPRO_LEN \ - sizeof(struct audpp_cmd_cfg_adec_params_wmapro) - -struct audpp_cmd_cfg_adec_params_wmapro { - audpp_cmd_cfg_adec_params_common common; - unsigned short armdatareqthr; - uint8_t validbitspersample; - uint8_t numchannels; - unsigned short formattag; - unsigned short samplingrate; - unsigned short avgbytespersecond; - unsigned short asfpacketlength; - unsigned short channelmask; - unsigned short encodeopt; - unsigned short advancedencodeopt; - uint32_t advancedencodeopt2; -} __attribute__((packed)); - -/* - * Command Structure to configure Per decoder Parameters (MP3) - */ - -#define AUDPP_CMD_CFG_ADEC_PARAMS_MP3_LEN \ - sizeof(audpp_cmd_cfg_adec_params_mp3) - -typedef struct { - audpp_cmd_cfg_adec_params_common common; -} __attribute__((packed)) audpp_cmd_cfg_adec_params_mp3; - - -/* - * Command Structure to configure Per decoder Parameters (AAC) - */ - -#define AUDPP_CMD_CFG_ADEC_PARAMS_AAC_LEN \ - sizeof(audpp_cmd_cfg_adec_params_aac) - - -#define AUDPP_CMD_AAC_FORMAT_ADTS -1 -#define AUDPP_CMD_AAC_FORMAT_RAW 0x0000 -#define AUDPP_CMD_AAC_FORMAT_PSUEDO_RAW 0x0001 -#define AUDPP_CMD_AAC_FORMAT_LOAS 0x0002 - -#define AUDPP_CMD_AAC_AUDIO_OBJECT_LC 0x0002 -#define AUDPP_CMD_AAC_AUDIO_OBJECT_LTP 0x0004 -#define AUDPP_CMD_AAC_AUDIO_OBJECT_ERLC 0x0011 - -#define AUDPP_CMD_AAC_SBR_ON_FLAG_ON 0x0001 -#define AUDPP_CMD_AAC_SBR_ON_FLAG_OFF 0x0000 - -#define AUDPP_CMD_AAC_SBR_PS_ON_FLAG_ON 0x0001 -#define AUDPP_CMD_AAC_SBR_PS_ON_FLAG_OFF 0x0000 - -typedef struct { - audpp_cmd_cfg_adec_params_common common; - signed short format; - unsigned short audio_object; - unsigned short ep_config; - unsigned short aac_section_data_resilience_flag; - unsigned short aac_scalefactor_data_resilience_flag; - unsigned short aac_spectral_data_resilience_flag; - unsigned short sbr_on_flag; - unsigned short sbr_ps_on_flag; - unsigned short channel_configuration; -} __attribute__((packed)) audpp_cmd_cfg_adec_params_aac; - -/* - * Command Structure to configure Per decoder Parameters (V13K) - */ - -#define AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN \ - sizeof(struct audpp_cmd_cfg_adec_params_v13k) - - -#define AUDPP_CMD_STEREO_CFG_MONO 0x0001 -#define AUDPP_CMD_STEREO_CFG_STEREO 0x0002 - -struct audpp_cmd_cfg_adec_params_v13k { - audpp_cmd_cfg_adec_params_common common; - unsigned short stereo_cfg; -} __attribute__((packed)); - -#define AUDPP_CMD_CFG_ADEC_PARAMS_EVRC_LEN \ - sizeof(struct audpp_cmd_cfg_adec_params_evrc) - -struct audpp_cmd_cfg_adec_params_evrc { - audpp_cmd_cfg_adec_params_common common; - unsigned short stereo_cfg; -} __attribute__ ((packed)); - -/* - * Command Structure to configure Per decoder Parameters (AMRWB) - */ -#define ADEC_PARAMS_AC3_INDEX 14 - -struct audpp_cmd_cfg_adec_params_amrwb { - audpp_cmd_cfg_adec_params_common common; - unsigned short stereo_cfg; -} __attribute__((packed)) ; - -#define AUDPP_CMD_CFG_ADEC_PARAMS_AMRWB_LEN \ - sizeof(struct audpp_cmd_cfg_adec_params_amrwb) - -/* - * Command Structure to configure Per decoder Parameters (AC3) - */ - -struct audpp_cmd_cfg_adec_params_ac3 { - audpp_cmd_cfg_adec_params_common common; - unsigned short index[ADEC_PARAMS_AC3_INDEX]; -} __packed; - -#define AUDPP_CMD_CFG_ADEC_PARAMS_AC3_LEN \ - sizeof(struct audpp_cmd_cfg_adec_params_ac3) - -/* - * Command Structure to configure the HOST PCM interface - */ - -#define AUDPP_CMD_PCM_INTF 0x0001 -#define AUDPP_CMD_PCM_INTF_2 0x0002 -#define AUDPP_CMD_PCM_INTF_LEN sizeof(audpp_cmd_pcm_intf) - -#define AUDPP_CMD_PCM_INTF_MONO_V 0x0001 -#define AUDPP_CMD_PCM_INTF_STEREO_V 0x0002 - -/* These two values differentiate the two types of commands that could be issued - * Interface configuration command and Buffer update command */ - -#define AUDPP_CMD_PCM_INTF_CONFIG_CMD_V 0x0000 -#define AUDPP_CMD_PCM_INTF_BUFFER_CMD_V -1 - -#define AUDPP_CMD_PCM_INTF_RX_ENA_M 0x000F -#define AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V 0x0008 -#define AUDPP_CMD_PCM_INTF_RX_ENA_DSPTOARM_V 0x0004 - -/* These flags control the enabling and disabling of the interface together - * with host interface bit mask. */ - -#define AUDPP_CMD_PCM_INTF_ENA_V -1 -#define AUDPP_CMD_PCM_INTF_DIS_V 0x0000 - - -#define AUDPP_CMD_PCM_INTF_FULL_DUPLEX 0x0 -#define AUDPP_CMD_PCM_INTF_HALF_DUPLEX_TODSP 0x1 - - -#define AUDPP_CMD_PCM_INTF_OBJECT_NUM 0x5 -#define AUDPP_CMD_PCM_INTF_COMMON_OBJECT_NUM 0x6 - - -typedef struct { - unsigned short cmd_id; - unsigned short object_num; - signed short config; - unsigned short intf_type; - - /* DSP -> ARM Configuration */ - unsigned short read_buf1LSW; - unsigned short read_buf1MSW; - unsigned short read_buf1_len; - - unsigned short read_buf2LSW; - unsigned short read_buf2MSW; - unsigned short read_buf2_len; - /* 0:HOST_PCM_INTF disable - ** 0xFFFF: HOST_PCM_INTF enable - */ - signed short dsp_to_arm_flag; - unsigned short partition_number; - - /* ARM -> DSP Configuration */ - unsigned short write_buf1LSW; - unsigned short write_buf1MSW; - unsigned short write_buf1_len; - - unsigned short write_buf2LSW; - unsigned short write_buf2MSW; - unsigned short write_buf2_len; - - /* 0:HOST_PCM_INTF disable - ** 0xFFFF: HOST_PCM_INTF enable - */ - signed short arm_to_rx_flag; - unsigned short weight_decoder_to_rx; - unsigned short weight_arm_to_rx; - - unsigned short partition_number_arm_to_dsp; - unsigned short sample_rate; - unsigned short channel_mode; -} __attribute__((packed)) audpp_cmd_pcm_intf; - -/* - ** BUFFER UPDATE COMMAND - */ -#define AUDPP_CMD_PCM_INTF_SEND_BUF_PARAMS_LEN \ - sizeof(audpp_cmd_pcm_intf_send_buffer) - -typedef struct { - unsigned short cmd_id; - unsigned short host_pcm_object; - /* set config = 0xFFFF for configuration*/ - signed short config; - unsigned short intf_type; - unsigned short dsp_to_arm_buf_id; - unsigned short arm_to_dsp_buf_id; - unsigned short arm_to_dsp_buf_len; -} __attribute__((packed)) audpp_cmd_pcm_intf_send_buffer; - - -/* - * Commands Related to uPAudPPCmd3Queue - */ - -/* - * Command Structure to configure post processing params (Commmon) - */ - -#define AUDPP_CMD_CFG_OBJECT_PARAMS 0x0000 -#define AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN \ - sizeof(audpp_cmd_cfg_object_params_common) - -#define AUDPP_CMD_OBJ0_UPDATE 0x8000 -#define AUDPP_CMD_OBJ0_DONT_UPDATE 0x0000 - -#define AUDPP_CMD_OBJ1_UPDATE 0x8000 -#define AUDPP_CMD_OBJ1_DONT_UPDATE 0x0000 - -#define AUDPP_CMD_OBJ2_UPDATE 0x8000 -#define AUDPP_CMD_OBJ2_DONT_UPDATE 0x0000 - -#define AUDPP_CMD_OBJ3_UPDATE 0x8000 -#define AUDPP_CMD_OBJ3_DONT_UPDATE 0x0000 - -#define AUDPP_CMD_OBJ4_UPDATE 0x8000 -#define AUDPP_CMD_OBJ4_DONT_UPDATE 0x0000 - -#define AUDPP_CMD_HPCM_UPDATE 0x8000 -#define AUDPP_CMD_HPCM_DONT_UPDATE 0x0000 - -#define AUDPP_CMD_COMMON_CFG_UPDATE 0x8000 -#define AUDPP_CMD_COMMON_CFG_DONT_UPDATE 0x0000 - -typedef struct { - unsigned short cmd_id; - unsigned short obj0_cfg; - unsigned short obj1_cfg; - unsigned short obj2_cfg; - unsigned short obj3_cfg; - unsigned short obj4_cfg; - unsigned short host_pcm_obj_cfg; - unsigned short comman_cfg; - unsigned short command_type; -} __attribute__((packed)) audpp_cmd_cfg_object_params_common; - -/* - * Command Structure to configure post processing params (Volume) - */ - -#define AUDPP_CMD_CFG_OBJECT_PARAMS_VOLUME_LEN \ - sizeof(audpp_cmd_cfg_object_params_volume) - -typedef struct { - audpp_cmd_cfg_object_params_common common; - unsigned short volume; - unsigned short pan; -} __attribute__((packed)) audpp_cmd_cfg_object_params_volume; - -/* - * Command Structure to configure post processing params (PCM Filter) --DOUBT - */ - -typedef struct { - unsigned short numerator_b0_filter_lsw; - unsigned short numerator_b0_filter_msw; - unsigned short numerator_b1_filter_lsw; - unsigned short numerator_b1_filter_msw; - unsigned short numerator_b2_filter_lsw; - unsigned short numerator_b2_filter_msw; -} __attribute__((packed)) numerator; - -typedef struct { - unsigned short denominator_a0_filter_lsw; - unsigned short denominator_a0_filter_msw; - unsigned short denominator_a1_filter_lsw; - unsigned short denominator_a1_filter_msw; -} __attribute__((packed)) denominator; - -typedef struct { - unsigned short shift_factor_0; -} __attribute__((packed)) shift_factor; - -typedef struct { - unsigned short pan_filter_0; -} __attribute__((packed)) pan; - -typedef struct { - numerator numerator_filter; - denominator denominator_filter; - shift_factor shift_factor_filter; - pan pan_filter; -} __attribute__((packed)) filter_1; - -typedef struct { - numerator numerator_filter[2]; - denominator denominator_filter[2]; - shift_factor shift_factor_filter[2]; - pan pan_filter[2]; -} __attribute__((packed)) filter_2; - -typedef struct { - numerator numerator_filter[3]; - denominator denominator_filter[3]; - shift_factor shift_factor_filter[3]; - pan pan_filter[3]; -} __attribute__((packed)) filter_3; - -typedef struct { - numerator numerator_filter[4]; - denominator denominator_filter[4]; - shift_factor shift_factor_filter[4]; - pan pan_filter[4]; -} __attribute__((packed)) filter_4; - -#define AUDPP_CMD_CFG_OBJECT_PARAMS_PCM_LEN \ - sizeof(audpp_cmd_cfg_object_params_pcm) - - -typedef struct { - audpp_cmd_cfg_object_params_common common; - unsigned short active_flag; - unsigned short num_bands; - union { - filter_1 filter_1_params; - filter_2 filter_2_params; - filter_3 filter_3_params; - filter_4 filter_4_params; - } __attribute__((packed)) params_filter; -} __attribute__((packed)) audpp_cmd_cfg_object_params_pcm; - - -/* - * Command Structure to configure post processing parameters (equalizer) - */ - -#define AUDPP_CMD_CFG_OBJECT_PARAMS_EQALIZER_LEN \ - sizeof(audpp_cmd_cfg_object_params_eqalizer) - -typedef struct { - unsigned short numerator_coeff_0_lsw; - unsigned short numerator_coeff_0_msw; - unsigned short numerator_coeff_1_lsw; - unsigned short numerator_coeff_1_msw; - unsigned short numerator_coeff_2_lsw; - unsigned short numerator_coeff_2_msw; -} __attribute__((packed)) eq_numerator; - -typedef struct { - unsigned short denominator_coeff_0_lsw; - unsigned short denominator_coeff_0_msw; - unsigned short denominator_coeff_1_lsw; - unsigned short denominator_coeff_1_msw; -} __attribute__((packed)) eq_denominator; - -typedef struct { - unsigned short shift_factor; -} __attribute__((packed)) eq_shiftfactor; - -typedef struct { - eq_numerator numerator; - eq_denominator denominator; - eq_shiftfactor shiftfactor; -} __attribute__((packed)) eq_coeff_1; - -typedef struct { - eq_numerator numerator[2]; - eq_denominator denominator[2]; - eq_shiftfactor shiftfactor[2]; -} __attribute__((packed)) eq_coeff_2; - -typedef struct { - eq_numerator numerator[3]; - eq_denominator denominator[3]; - eq_shiftfactor shiftfactor[3]; -} __attribute__((packed)) eq_coeff_3; - -typedef struct { - eq_numerator numerator[4]; - eq_denominator denominator[4]; - eq_shiftfactor shiftfactor[4]; -} __attribute__((packed)) eq_coeff_4; - -typedef struct { - eq_numerator numerator[5]; - eq_denominator denominator[5]; - eq_shiftfactor shiftfactor[5]; -} __attribute__((packed)) eq_coeff_5; - -typedef struct { - eq_numerator numerator[6]; - eq_denominator denominator[6]; - eq_shiftfactor shiftfactor[6]; -} __attribute__((packed)) eq_coeff_6; - -typedef struct { - eq_numerator numerator[7]; - eq_denominator denominator[7]; - eq_shiftfactor shiftfactor[7]; -} __attribute__((packed)) eq_coeff_7; - -typedef struct { - eq_numerator numerator[8]; - eq_denominator denominator[8]; - eq_shiftfactor shiftfactor[8]; -} __attribute__((packed)) eq_coeff_8; - -typedef struct { - eq_numerator numerator[9]; - eq_denominator denominator[9]; - eq_shiftfactor shiftfactor[9]; -} __attribute__((packed)) eq_coeff_9; - -typedef struct { - eq_numerator numerator[10]; - eq_denominator denominator[10]; - eq_shiftfactor shiftfactor[10]; -} __attribute__((packed)) eq_coeff_10; - -typedef struct { - eq_numerator numerator[11]; - eq_denominator denominator[11]; - eq_shiftfactor shiftfactor[11]; -} __attribute__((packed)) eq_coeff_11; - -typedef struct { - eq_numerator numerator[12]; - eq_denominator denominator[12]; - eq_shiftfactor shiftfactor[12]; -} __attribute__((packed)) eq_coeff_12; - - -typedef struct { - audpp_cmd_cfg_object_params_common common; - unsigned short eq_flag; - unsigned short num_bands; - union { - eq_coeff_1 eq_coeffs_1; - eq_coeff_2 eq_coeffs_2; - eq_coeff_3 eq_coeffs_3; - eq_coeff_4 eq_coeffs_4; - eq_coeff_5 eq_coeffs_5; - eq_coeff_6 eq_coeffs_6; - eq_coeff_7 eq_coeffs_7; - eq_coeff_8 eq_coeffs_8; - eq_coeff_9 eq_coeffs_9; - eq_coeff_10 eq_coeffs_10; - eq_coeff_11 eq_coeffs_11; - eq_coeff_12 eq_coeffs_12; - } __attribute__((packed)) eq_coeff; -} __attribute__((packed)) audpp_cmd_cfg_object_params_eqalizer; - - -/* - * Command Structure to configure post processing parameters (ADRC) - */ - -#define AUDPP_CMD_CFG_OBJECT_PARAMS_ADRC_LEN \ - sizeof(audpp_cmd_cfg_object_params_adrc) - - -#define AUDPP_CMD_ADRC_FLAG_DIS 0x0000 -#define AUDPP_CMD_ADRC_FLAG_ENA -1 - -#define AUDPP_MAX_MBADRC_BANDS 5 -#define AUDPP_MBADRC_EXTERNAL_BUF_SIZE 196 - -struct adrc_config { - uint16_t subband_enable; - uint16_t adrc_sub_mute; - uint16_t rms_time; - uint16_t compression_th; - uint16_t compression_slope; - uint16_t attack_const_lsw; - uint16_t attack_const_msw; - uint16_t release_const_lsw; - uint16_t release_const_msw; - uint16_t makeup_gain; -}; - -typedef struct { - audpp_cmd_cfg_object_params_common common; - uint16_t enable; - uint16_t num_bands; - uint16_t down_samp_level; - uint16_t adrc_delay; - uint16_t ext_buf_size; - uint16_t ext_partition; - uint16_t ext_buf_msw; - uint16_t ext_buf_lsw; - struct adrc_config adrc_band[AUDPP_MAX_MBADRC_BANDS]; -} __attribute__((packed)) audpp_cmd_cfg_object_params_mbadrc; - -struct audpp_cmd_cfg_object_params_adrc { - unsigned short adrc_flag; - unsigned short compression_th; - unsigned short compression_slope; - unsigned short rms_time; - unsigned short attack_const_lsw; - unsigned short attack_const_msw; - unsigned short release_const_lsw; - unsigned short release_const_msw; - unsigned short adrc_delay; -}; - -/* - * Command Structure to configure post processing parameters(Spectrum Analizer) - */ - -#define AUDPP_CMD_CFG_OBJECT_PARAMS_SPECTRAM_LEN \ - sizeof(audpp_cmd_cfg_object_params_spectram) - - -typedef struct { - audpp_cmd_cfg_object_params_common common; - unsigned short sample_interval; - unsigned short num_coeff; -} __attribute__((packed)) audpp_cmd_cfg_object_params_spectram; - -/* - * Command Structure to configure post processing parameters (QConcert) - */ - -#define AUDPP_CMD_CFG_OBJECT_PARAMS_QCONCERT_LEN \ - sizeof(audpp_cmd_cfg_object_params_qconcert) - - -#define AUDPP_CMD_QCON_ENA_FLAG_ENA -1 -#define AUDPP_CMD_QCON_ENA_FLAG_DIS 0x0000 - -#define AUDPP_CMD_QCON_OP_MODE_HEADPHONE -1 -#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_FRONT 0x0000 -#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_SIDE 0x0001 -#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_DESKTOP 0x0002 - -#define AUDPP_CMD_QCON_GAIN_UNIT 0x7FFF -#define AUDPP_CMD_QCON_GAIN_SIX_DB 0x4027 - - -#define AUDPP_CMD_QCON_EXPANSION_MAX 0x7FFF - - -typedef struct { - audpp_cmd_cfg_object_params_common common; - signed short enable_flag; - signed short op_mode; - signed short gain; - signed short expansion; - signed short delay; - unsigned short stages_per_mode; - unsigned short reverb_enable; - unsigned short decay_msw; - unsigned short decay_lsw; - unsigned short decay_time_ratio_msw; - unsigned short decay_time_ratio_lsw; - unsigned short reflection_delay_time; - unsigned short late_reverb_gain; - unsigned short late_reverb_delay; - unsigned short delay_buff_size_msw; - unsigned short delay_buff_size_lsw; - unsigned short partition_num; - unsigned short delay_buff_start_msw; - unsigned short delay_buff_start_lsw; -} __attribute__((packed)) audpp_cmd_cfg_object_params_qconcert; - -/* - * Command Structure to configure post processing parameters (Side Chain) - */ - -#define AUDPP_CMD_CFG_OBJECT_PARAMS_SIDECHAIN_LEN \ - sizeof(audpp_cmd_cfg_object_params_sidechain) - - -#define AUDPP_CMD_SIDECHAIN_ACTIVE_FLAG_DIS 0x0000 -#define AUDPP_CMD_SIDECHAIN_ACTIVE_FLAG_ENA -1 - -typedef struct { - audpp_cmd_cfg_object_params_common common; - signed short active_flag; - unsigned short num_bands; - union { - filter_1 filter_1_params; - filter_2 filter_2_params; - filter_3 filter_3_params; - filter_4 filter_4_params; - } __attribute__((packed)) params_filter; -} __attribute__((packed)) audpp_cmd_cfg_object_params_sidechain; - - -/* - * Command Structure to configure post processing parameters (QAFX) - */ - -#define AUDPP_CMD_CFG_OBJECT_PARAMS_QAFX_LEN \ - sizeof(audpp_cmd_cfg_object_params_qafx) - -#define AUDPP_CMD_QAFX_ENA_DISA 0x0000 -#define AUDPP_CMD_QAFX_ENA_ENA_CFG -1 -#define AUDPP_CMD_QAFX_ENA_DIS_CFG 0x0001 - -#define AUDPP_CMD_QAFX_CMD_TYPE_ENV 0x0100 -#define AUDPP_CMD_QAFX_CMD_TYPE_OBJ 0x0010 -#define AUDPP_CMD_QAFX_CMD_TYPE_QUERY 0x1000 - -#define AUDPP_CMD_QAFX_CMDS_ENV_OP_MODE 0x0100 -#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_POS 0x0101 -#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_ORI 0x0102 -#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_VEL 0X0103 -#define AUDPP_CMD_QAFX_CMDS_ENV_ENV_RES 0x0107 - -#define AUDPP_CMD_QAFX_CMDS_OBJ_SAMP_FREQ 0x0010 -#define AUDPP_CMD_QAFX_CMDS_OBJ_VOL 0x0011 -#define AUDPP_CMD_QAFX_CMDS_OBJ_DIST 0x0012 -#define AUDPP_CMD_QAFX_CMDS_OBJ_POS 0x0013 -#define AUDPP_CMD_QAFX_CMDS_OBJ_VEL 0x0014 - - -typedef struct { - audpp_cmd_cfg_object_params_common common; - signed short enable; - unsigned short command_type; - unsigned short num_commands; - unsigned short commands; -} __attribute__((packed)) audpp_cmd_cfg_object_params_qafx; - -/* - * Command Structure to enable , disable or configure the reverberation effect - * (Common) - */ - -#define AUDPP_CMD_REVERB_CONFIG 0x0001 -#define AUDPP_CMD_REVERB_CONFIG_COMMON_LEN \ - sizeof(audpp_cmd_reverb_config_common) - -#define AUDPP_CMD_ENA_ENA 0xFFFF -#define AUDPP_CMD_ENA_DIS 0x0000 -#define AUDPP_CMD_ENA_CFG 0x0001 - -#define AUDPP_CMD_CMD_TYPE_ENV 0x0104 -#define AUDPP_CMD_CMD_TYPE_OBJ 0x0015 -#define AUDPP_CMD_CMD_TYPE_QUERY 0x1000 - -#define SRS_PARAMS_MAX_G 8 -#define SRS_PARAMS_MAX_W 55 -#define SRS_PARAMS_MAX_C 51 -#define SRS_PARAMS_MAX_H 53 -#define SRS_PARAMS_MAX_P 116 -#define SRS_PARAMS_MAX_L 8 - -typedef struct { - unsigned short cmd_id; - unsigned short enable; - unsigned short cmd_type; -} __attribute__((packed)) audpp_cmd_reverb_config_common; - -/* - * Command Structure to enable , disable or configure the reverberation effect - * (ENV-0x0104) - */ - -#define AUDPP_CMD_REVERB_CONFIG_ENV_104_LEN \ - sizeof(audpp_cmd_reverb_config_env_104) - -typedef struct { - audpp_cmd_reverb_config_common common; - unsigned short env_gain; - unsigned short decay_msw; - unsigned short decay_lsw; - unsigned short decay_timeratio_msw; - unsigned short decay_timeratio_lsw; - unsigned short delay_time; - unsigned short reverb_gain; - unsigned short reverb_delay; -} __attribute__((packed)) audpp_cmd_reverb_config_env_104; - -/* - * Command Structure to enable , disable or configure the reverberation effect - * (ENV-0x0015) - */ - -#define AUDPP_CMD_REVERB_CONFIG_ENV_15_LEN \ - sizeof(audpp_cmd_reverb_config_env_15) - -typedef struct { - audpp_cmd_reverb_config_common common; - unsigned short object_num; - unsigned short absolute_gain; -} __attribute__((packed)) audpp_cmd_reverb_config_env_15; - -/* - * Command Structure to configure post processing params (SRS TruMedia) - */ -struct audpp_cmd_cfg_object_params_srstm_g { - audpp_cmd_cfg_object_params_common common; - unsigned short v[SRS_PARAMS_MAX_G]; -} __packed; -struct audpp_cmd_cfg_object_params_srstm_w { - audpp_cmd_cfg_object_params_common common; - unsigned short v[SRS_PARAMS_MAX_W]; -} __packed; -struct audpp_cmd_cfg_object_params_srstm_c { - audpp_cmd_cfg_object_params_common common; - unsigned short v[SRS_PARAMS_MAX_C]; -} __packed; -struct audpp_cmd_cfg_object_params_srstm_h { - audpp_cmd_cfg_object_params_common common; - unsigned short v[SRS_PARAMS_MAX_H]; -} __packed; -struct audpp_cmd_cfg_object_params_srstm_p { - audpp_cmd_cfg_object_params_common common; - unsigned short v[SRS_PARAMS_MAX_P]; -} __packed; -struct audpp_cmd_cfg_object_params_srstm_l { - audpp_cmd_cfg_object_params_common common; - unsigned short v[SRS_PARAMS_MAX_L]; -} __packed; - -#endif /* QDSP5AUDPPCMDI_H */ - diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppmsg.h deleted file mode 100644 index 746b98e7a2188703f4b34ec97df14a9f59e4b967..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppmsg.h +++ /dev/null @@ -1,321 +0,0 @@ -#ifndef QDSP5AUDPPMSG_H -#define QDSP5AUDPPMSG_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - - Q D S P 5 A U D I O P O S T P R O C E S S I N G M S G - -GENERAL DESCRIPTION - Messages sent by AUDPPTASK to ARM - -REFERENCES - None - -EXTERNALIZED FUNCTIONS - None - -Copyright (c) 1992-2009, The Linux Foundation. All rights reserved. - -This software is licensed under the terms of the GNU General Public -License version 2, as published by the Free Software Foundation, and -may be copied, distributed, and modified under those terms. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ -/*=========================================================================== - - EDIT HISTORY FOR FILE - -This section contains comments describing changes made to this file. -Notice that changes are listed in reverse chronological order. - - $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audppmsg.h#4 $ - -===========================================================================*/ - -/* - * AUDPPTASK uses audPPuPRlist to send messages to the ARM - * Location : MEMA - * Buffer Size : 45 - * No of Buffers in a queue : 5 for gaming audio and 1 for other images - */ - -/* - * MSG to Informs the ARM os Success/Failure of bringing up the decoder - */ - -#define AUDPP_MSG_STATUS_MSG 0x0001 -#define AUDPP_MSG_STATUS_MSG_LEN \ - sizeof(audpp_msg_status_msg) - -#define AUDPP_MSG_STATUS_SLEEP 0x0000 -#define AUDPP_MSG_STATUS_INIT 0x0001 -#define AUDPP_MSG_STATUS_CFG 0x0002 -#define AUDPP_MSG_STATUS_PLAY 0x0003 - -#define AUDPP_MSG_REASON_NONE 0x0000 -#define AUDPP_MSG_REASON_MEM 0x0001 -#define AUDPP_MSG_REASON_NODECODER 0x0002 - -typedef struct{ - unsigned short dec_id; - unsigned short status; - unsigned short reason; -} __attribute__((packed)) audpp_msg_status_msg; - -/* - * MSG to communicate the spectrum analyzer output bands to the ARM - */ -#define AUDPP_MSG_SPA_BANDS 0x0002 -#define AUDPP_MSG_SPA_BANDS_LEN \ - sizeof(audpp_msg_spa_bands) - -typedef struct { - unsigned short current_object; - unsigned short spa_band_1; - unsigned short spa_band_2; - unsigned short spa_band_3; - unsigned short spa_band_4; - unsigned short spa_band_5; - unsigned short spa_band_6; - unsigned short spa_band_7; - unsigned short spa_band_8; - unsigned short spa_band_9; - unsigned short spa_band_10; - unsigned short spa_band_11; - unsigned short spa_band_12; - unsigned short spa_band_13; - unsigned short spa_band_14; - unsigned short spa_band_15; - unsigned short spa_band_16; - unsigned short spa_band_17; - unsigned short spa_band_18; - unsigned short spa_band_19; - unsigned short spa_band_20; - unsigned short spa_band_21; - unsigned short spa_band_22; - unsigned short spa_band_23; - unsigned short spa_band_24; - unsigned short spa_band_25; - unsigned short spa_band_26; - unsigned short spa_band_27; - unsigned short spa_band_28; - unsigned short spa_band_29; - unsigned short spa_band_30; - unsigned short spa_band_31; - unsigned short spa_band_32; -} __attribute__((packed)) audpp_msg_spa_bands; - -/* - * MSG to communicate the PCM I/O buffer status to ARM - */ -#define AUDPP_MSG_HOST_PCM_INTF_MSG 0x0003 -#define AUDPP_MSG_HOST_PCM_INTF_MSG_LEN \ - sizeof(audpp_msg_host_pcm_intf_msg) - -#define AUDPP_MSG_HOSTPCM_ID_TX_ARM 0x0000 -#define AUDPP_MSG_HOSTPCM_ID_ARM_TX 0x0001 -#define AUDPP_MSG_HOSTPCM_ID_RX_ARM 0x0002 -#define AUDPP_MSG_HOSTPCM_ID_ARM_RX 0x0003 - -#define AUDPP_MSG_SAMP_FREQ_INDX_96000 0x0000 -#define AUDPP_MSG_SAMP_FREQ_INDX_88200 0x0001 -#define AUDPP_MSG_SAMP_FREQ_INDX_64000 0x0002 -#define AUDPP_MSG_SAMP_FREQ_INDX_48000 0x0003 -#define AUDPP_MSG_SAMP_FREQ_INDX_44100 0x0004 -#define AUDPP_MSG_SAMP_FREQ_INDX_32000 0x0005 -#define AUDPP_MSG_SAMP_FREQ_INDX_24000 0x0006 -#define AUDPP_MSG_SAMP_FREQ_INDX_22050 0x0007 -#define AUDPP_MSG_SAMP_FREQ_INDX_16000 0x0008 -#define AUDPP_MSG_SAMP_FREQ_INDX_12000 0x0009 -#define AUDPP_MSG_SAMP_FREQ_INDX_11025 0x000A -#define AUDPP_MSG_SAMP_FREQ_INDX_8000 0x000B - -#define AUDPP_MSG_CHANNEL_MODE_MONO 0x0001 -#define AUDPP_MSG_CHANNEL_MODE_STEREO 0x0002 - -typedef struct{ - unsigned short obj_num; - unsigned short numbers_of_samples; - unsigned short host_pcm_id; - unsigned short buf_indx; - unsigned short samp_freq_indx; - unsigned short channel_mode; -} __attribute__((packed)) audpp_msg_host_pcm_intf_msg; - - -/* - * MSG to communicate 3D position of the source and listener , source volume - * source rolloff, source orientation - */ - -#define AUDPP_MSG_QAFX_POS 0x0004 -#define AUDPP_MSG_QAFX_POS_LEN \ - sizeof(audpp_msg_qafx_pos) - -typedef struct { - unsigned short current_object; - unsigned short x_pos_lis_msw; - unsigned short x_pos_lis_lsw; - unsigned short y_pos_lis_msw; - unsigned short y_pos_lis_lsw; - unsigned short z_pos_lis_msw; - unsigned short z_pos_lis_lsw; - unsigned short x_fwd_msw; - unsigned short x_fwd_lsw; - unsigned short y_fwd_msw; - unsigned short y_fwd_lsw; - unsigned short z_fwd_msw; - unsigned short z_fwd_lsw; - unsigned short x_up_msw; - unsigned short x_up_lsw; - unsigned short y_up_msw; - unsigned short y_up_lsw; - unsigned short z_up_msw; - unsigned short z_up_lsw; - unsigned short x_vel_lis_msw; - unsigned short x_vel_lis_lsw; - unsigned short y_vel_lis_msw; - unsigned short y_vel_lis_lsw; - unsigned short z_vel_lis_msw; - unsigned short z_vel_lis_lsw; - unsigned short threed_enable_flag; - unsigned short volume; - unsigned short x_pos_source_msw; - unsigned short x_pos_source_lsw; - unsigned short y_pos_source_msw; - unsigned short y_pos_source_lsw; - unsigned short z_pos_source_msw; - unsigned short z_pos_source_lsw; - unsigned short max_dist_0_msw; - unsigned short max_dist_0_lsw; - unsigned short min_dist_0_msw; - unsigned short min_dist_0_lsw; - unsigned short roll_off_factor; - unsigned short mute_after_max_flag; - unsigned short x_vel_source_msw; - unsigned short x_vel_source_lsw; - unsigned short y_vel_source_msw; - unsigned short y_vel_source_lsw; - unsigned short z_vel_source_msw; - unsigned short z_vel_source_lsw; -} __attribute__((packed)) audpp_msg_qafx_pos; - -/* - * MSG to provide AVSYNC feedback from DSP to ARM - */ - -#define AUDPP_MSG_AVSYNC_MSG 0x0005 -#define AUDPP_MSG_AVSYNC_MSG_LEN \ - sizeof(audpp_msg_avsync_msg) - -typedef struct { - unsigned short active_flag; - unsigned short num_samples_counter0_HSW; - unsigned short num_samples_counter0_MSW; - unsigned short num_samples_counter0_LSW; - unsigned short num_bytes_counter0_HSW; - unsigned short num_bytes_counter0_MSW; - unsigned short num_bytes_counter0_LSW; - unsigned short samp_freq_obj_0; - unsigned short samp_freq_obj_1; - unsigned short samp_freq_obj_2; - unsigned short samp_freq_obj_3; - unsigned short samp_freq_obj_4; - unsigned short samp_freq_obj_5; - unsigned short samp_freq_obj_6; - unsigned short samp_freq_obj_7; - unsigned short samp_freq_obj_8; - unsigned short samp_freq_obj_9; - unsigned short samp_freq_obj_10; - unsigned short samp_freq_obj_11; - unsigned short samp_freq_obj_12; - unsigned short samp_freq_obj_13; - unsigned short samp_freq_obj_14; - unsigned short samp_freq_obj_15; - unsigned short num_samples_counter4_HSW; - unsigned short num_samples_counter4_MSW; - unsigned short num_samples_counter4_LSW; - unsigned short num_bytes_counter4_HSW; - unsigned short num_bytes_counter4_MSW; - unsigned short num_bytes_counter4_LSW; -} __attribute__((packed)) audpp_msg_avsync_msg; - -/* - * MSG to provide PCM DMA Missed feedback from the DSP to ARM - */ - -#define AUDPP_MSG_PCMDMAMISSED 0x0006 -#define AUDPP_MSG_PCMDMAMISSED_LEN \ - sizeof(audpp_msg_pcmdmamissed); - -typedef struct{ - /* - ** Bit 0 0 = PCM DMA not missed for object 0 - ** 1 = PCM DMA missed for object0 - ** Bit 1 0 = PCM DMA not missed for object 1 - ** 1 = PCM DMA missed for object1 - ** Bit 2 0 = PCM DMA not missed for object 2 - ** 1 = PCM DMA missed for object2 - ** Bit 3 0 = PCM DMA not missed for object 3 - ** 1 = PCM DMA missed for object3 - ** Bit 4 0 = PCM DMA not missed for object 4 - ** 1 = PCM DMA missed for object4 - */ - unsigned short pcmdmamissed; -} __attribute__((packed)) audpp_msg_pcmdmamissed; - -/* - * MSG to AUDPP enable or disable feedback form DSP to ARM - */ - -#define AUDPP_MSG_CFG_MSG 0x0007 -#define AUDPP_MSG_CFG_MSG_LEN \ - sizeof(audpp_msg_cfg_msg) - -#define AUDPP_MSG_ENA_ENA 0xFFFF -#define AUDPP_MSG_ENA_DIS 0x0000 - -typedef struct{ - /* Enabled - 0xffff - ** Disabled - 0 - */ - unsigned short enabled; -} __attribute__((packed)) audpp_msg_cfg_msg; - -/* - * MSG to communicate the reverb per object volume - */ - -#define AUDPP_MSG_QREVERB_VOLUME 0x0008 -#define AUDPP_MSG_QREVERB_VOLUME_LEN \ - sizeof(audpp_msg_qreverb_volume) - - -typedef struct { - unsigned short obj_0_gain; - unsigned short obj_1_gain; - unsigned short obj_2_gain; - unsigned short obj_3_gain; - unsigned short obj_4_gain; - unsigned short hpcm_obj_volume; -} __attribute__((packed)) audpp_msg_qreverb_volume; - -#define AUDPP_MSG_ROUTING_ACK 0x0009 -#define AUDPP_MSG_ROUTING_ACK_LEN \ - sizeof(struct audpp_msg_routing_ack) - -struct audpp_msg_routing_ack { - unsigned short dec_id; - unsigned short routing_mode; -} __attribute__((packed)); - -#define AUDPP_MSG_FLUSH_ACK 0x000A - -#define ADSP_MESSAGE_ID 0xFFFF - -#endif /* QDSP5AUDPPMSG_H */ diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproc.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproc.h deleted file mode 100644 index ae1bc27e7aadad02b196186e483bb81908760d80..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproc.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (c) 2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef QDSP5AUDPREPROC_H -#define _QDSP5AUDPREPROC_H - -#include -#include - -#define MSM_AUD_ENC_MODE_TUNNEL 0x00000100 -#define MSM_AUD_ENC_MODE_NONTUNNEL 0x00000200 - -#define AUDPREPROC_CODEC_MASK 0x00FF -#define AUDPREPROC_MODE_MASK 0xFF00 - -#define MSM_ADSP_ENC_MODE_TUNNEL 24 -#define MSM_ADSP_ENC_MODE_NON_TUNNEL 25 - -/* Exported common api's from audpreproc layer */ -int audpreproc_aenc_alloc(unsigned enc_type, const char **module_name, - unsigned *queue_id); -void audpreproc_aenc_free(int enc_id); - -#endif /* QDSP5AUDPREPROC_H */ diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproccmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproccmdi.h deleted file mode 100644 index fd3b3d933762f575cb9ad3e5a3f8e17c09803aa6..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproccmdi.h +++ /dev/null @@ -1,256 +0,0 @@ -#ifndef QDSP5AUDPREPROCCMDI_H -#define QDSP5AUDPREPROCCMDI_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - - A U D I O P R E P R O C E S S I N G I N T E R N A L C O M M A N D S - -GENERAL DESCRIPTION - This file contains defintions of format blocks of commands - that are accepted by AUDPREPROC Task - -REFERENCES - None - -EXTERNALIZED FUNCTIONS - None - -Copyright (c) 1992-2009, The Linux Foundation. All rights reserved. - -This software is licensed under the terms of the GNU General Public -License version 2, as published by the Free Software Foundation, and -may be copied, distributed, and modified under those terms. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ -/*=========================================================================== - - EDIT HISTORY FOR FILE - -This section contains comments describing changes made to this file. -Notice that changes are listed in reverse chronological order. - -$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audpreproccmdi.h#2 $ - -===========================================================================*/ - -/* - * AUDIOPREPROC COMMANDS: - * ARM uses uPAudPreProcCmdQueue to communicate with AUDPREPROCTASK - * Location : MEMB - * Buffer size : 51 - * Number of buffers in a queue : 3 - */ - -/* - * Command to configure the parameters of AGC - */ - -#define AUDPREPROC_CMD_CFG_AGC_PARAMS 0x0000 -#define AUDPREPROC_CMD_CFG_AGC_PARAMS_LEN \ - sizeof(audpreproc_cmd_cfg_agc_params) - -#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_SLOPE 0x0009 -#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_TH 0x000A -#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_SLOPE 0x000B -#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_TH 0x000C -#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_AIG_FLAG 0x000D -#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_STATIC_GAIN 0x000E -#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG 0x000F - -#define AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA -1 -#define AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS 0x0000 - -#define AUDPREPROC_CMD_ADP_GAIN_FLAG_ENA_ADP_GAIN -1 -#define AUDPREPROC_CMD_ADP_GAIN_FLAG_ENA_STATIC_GAIN 0x0000 - -#define AUDPREPROC_CMD_PARAM_MASK_RMS_TAY 0x0004 -#define AUDPREPROC_CMD_PARAM_MASK_RELEASEK 0x0005 -#define AUDPREPROC_CMD_PARAM_MASK_DELAY 0x0006 -#define AUDPREPROC_CMD_PARAM_MASK_ATTACKK 0x0007 -#define AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_SLOW 0x0008 -#define AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_FAST 0x0009 -#define AUDPREPROC_CMD_PARAM_MASK_AIG_RELEASEK 0x000A -#define AUDPREPROC_CMD_PARAM_MASK_AIG_MIN 0x000B -#define AUDPREPROC_CMD_PARAM_MASK_AIG_MAX 0x000C -#define AUDPREPROC_CMD_PARAM_MASK_LEAK_UP 0x000D -#define AUDPREPROC_CMD_PARAM_MASK_LEAK_DOWN 0x000E -#define AUDPREPROC_CMD_PARAM_MASK_AIG_ATTACKK 0x000F - -typedef struct { - unsigned short cmd_id; - unsigned short tx_agc_param_mask; - unsigned short tx_agc_enable_flag; - unsigned short static_gain; - signed short adaptive_gain_flag; - unsigned short expander_th; - unsigned short expander_slope; - unsigned short compressor_th; - unsigned short compressor_slope; - unsigned short param_mask; - unsigned short aig_attackk; - unsigned short aig_leak_down; - unsigned short aig_leak_up; - unsigned short aig_max; - unsigned short aig_min; - unsigned short aig_releasek; - unsigned short aig_leakrate_fast; - unsigned short aig_leakrate_slow; - unsigned short attackk_msw; - unsigned short attackk_lsw; - unsigned short delay; - unsigned short releasek_msw; - unsigned short releasek_lsw; - unsigned short rms_tav; -} __attribute__((packed)) audpreproc_cmd_cfg_agc_params; - - -/* - * Command to configure the params of Advanved AGC - */ - -#define AUDPREPROC_CMD_CFG_AGC_PARAMS_2 0x0001 -#define AUDPREPROC_CMD_CFG_AGC_PARAMS_2_LEN \ - sizeof(audpreproc_cmd_cfg_agc_params_2) - -#define AUDPREPROC_CMD_2_TX_AGC_ENA_FLAG_ENA -1; -#define AUDPREPROC_CMD_2_TX_AGC_ENA_FLAG_DIS 0x0000; - -typedef struct { - unsigned short cmd_id; - unsigned short agc_param_mask; - signed short tx_agc_enable_flag; - unsigned short comp_static_gain; - unsigned short exp_th; - unsigned short exp_slope; - unsigned short comp_th; - unsigned short comp_slope; - unsigned short comp_rms_tav; - unsigned short comp_samp_mask; - unsigned short comp_attackk_msw; - unsigned short comp_attackk_lsw; - unsigned short comp_releasek_msw; - unsigned short comp_releasek_lsw; - unsigned short comp_delay; - unsigned short comp_makeup_gain; -} __attribute__((packed)) audpreproc_cmd_cfg_agc_params_2; - -/* - * Command to configure params for ns - */ - -#define AUDPREPROC_CMD_CFG_NS_PARAMS 0x0002 -#define AUDPREPROC_CMD_CFG_NS_PARAMS_LEN \ - sizeof(audpreproc_cmd_cfg_ns_params) - -#define AUDPREPROC_CMD_EC_MODE_NEW_NLMS_ENA 0x0001 -#define AUDPREPROC_CMD_EC_MODE_NEW_NLMS_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_NEW_DES_ENA 0x0002 -#define AUDPREPROC_CMD_EC_MODE_NEW_DES_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_NEW_NS_ENA 0x0004 -#define AUDPREPROC_CMD_EC_MODE_NEW_NS_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_NEW_CNI_ENA 0x0008 -#define AUDPREPROC_CMD_EC_MODE_NEW_CNI_DIS 0x0000 - -#define AUDPREPROC_CMD_EC_MODE_NEW_NLES_ENA 0x0010 -#define AUDPREPROC_CMD_EC_MODE_NEW_NLES_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_NEW_HB_ENA 0x0020 -#define AUDPREPROC_CMD_EC_MODE_NEW_HB_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_NEW_VA_ENA 0x0040 -#define AUDPREPROC_CMD_EC_MODE_NEW_VA_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_NEW_PCD_ENA 0x0080 -#define AUDPREPROC_CMD_EC_MODE_NEW_PCD_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_NEW_FEHI_ENA 0x0100 -#define AUDPREPROC_CMD_EC_MODE_NEW_FEHI_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_NEW_NEHI_ENA 0x0200 -#define AUDPREPROC_CMD_EC_MODE_NEW_NEHI_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_NEW_NLPP_ENA 0x0400 -#define AUDPREPROC_CMD_EC_MODE_NEW_NLPP_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_NEW_FNE_ENA 0x0800 -#define AUDPREPROC_CMD_EC_MODE_NEW_FNE_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_ENA 0x1000 -#define AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_DIS 0x0000 - -typedef struct { - unsigned short cmd_id; - unsigned short ec_mode_new; - unsigned short dens_gamma_n; - unsigned short dens_nfe_block_size; - unsigned short dens_limit_ns; - unsigned short dens_limit_ns_d; - unsigned short wb_gamma_e; - unsigned short wb_gamma_n; -} __attribute__((packed)) audpreproc_cmd_cfg_ns_params; - -/* - * Command to configure parameters for IIR tuning filter - */ - -#define AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS 0x0003 -#define AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS_LEN \ - sizeof(audpreproc_cmd_cfg_iir_tuning_filter_params) - -#define AUDPREPROC_CMD_IIR_ACTIVE_FLAG_DIS 0x0000 -#define AUDPREPROC_CMD_IIR_ACTIVE_FLAG_ENA 0x0001 - -typedef struct { - unsigned short cmd_id; - unsigned short active_flag; - unsigned short num_bands; - unsigned short numerator_coeff_b0_filter0_lsw; - unsigned short numerator_coeff_b0_filter0_msw; - unsigned short numerator_coeff_b1_filter0_lsw; - unsigned short numerator_coeff_b1_filter0_msw; - unsigned short numerator_coeff_b2_filter0_lsw; - unsigned short numerator_coeff_b2_filter0_msw; - unsigned short numerator_coeff_b0_filter1_lsw; - unsigned short numerator_coeff_b0_filter1_msw; - unsigned short numerator_coeff_b1_filter1_lsw; - unsigned short numerator_coeff_b1_filter1_msw; - unsigned short numerator_coeff_b2_filter1_lsw; - unsigned short numerator_coeff_b2_filter1_msw; - unsigned short numerator_coeff_b0_filter2_lsw; - unsigned short numerator_coeff_b0_filter2_msw; - unsigned short numerator_coeff_b1_filter2_lsw; - unsigned short numerator_coeff_b1_filter2_msw; - unsigned short numerator_coeff_b2_filter2_lsw; - unsigned short numerator_coeff_b2_filter2_msw; - unsigned short numerator_coeff_b0_filter3_lsw; - unsigned short numerator_coeff_b0_filter3_msw; - unsigned short numerator_coeff_b1_filter3_lsw; - unsigned short numerator_coeff_b1_filter3_msw; - unsigned short numerator_coeff_b2_filter3_lsw; - unsigned short numerator_coeff_b2_filter3_msw; - unsigned short denominator_coeff_a0_filter0_lsw; - unsigned short denominator_coeff_a0_filter0_msw; - unsigned short denominator_coeff_a1_filter0_lsw; - unsigned short denominator_coeff_a1_filter0_msw; - unsigned short denominator_coeff_a0_filter1_lsw; - unsigned short denominator_coeff_a0_filter1_msw; - unsigned short denominator_coeff_a1_filter1_lsw; - unsigned short denominator_coeff_a1_filter1_msw; - unsigned short denominator_coeff_a0_filter2_lsw; - unsigned short denominator_coeff_a0_filter2_msw; - unsigned short denominator_coeff_a1_filter2_lsw; - unsigned short denominator_coeff_a1_filter2_msw; - unsigned short denominator_coeff_a0_filter3_lsw; - unsigned short denominator_coeff_a0_filter3_msw; - unsigned short denominator_coeff_a1_filter3_lsw; - unsigned short denominator_coeff_a1_filter3_msw; - - unsigned short shift_factor_filter0; - unsigned short shift_factor_filter1; - unsigned short shift_factor_filter2; - unsigned short shift_factor_filter3; - - unsigned short channel_selected0; - unsigned short channel_selected1; - unsigned short channel_selected2; - unsigned short channel_selected3; -} __attribute__((packed))audpreproc_cmd_cfg_iir_tuning_filter_params; - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreprocmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreprocmsg.h deleted file mode 100644 index d91b046043d393897da0b97ecb380dc1dd11a834..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreprocmsg.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef QDSP5AUDPREPROCMSG_H -#define QDSP5AUDPREPROCMSG_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - - A U D I O P R E P R O C E S S I N G M E S S A G E S - -GENERAL DESCRIPTION - This file contains defintions of format blocks of messages - that are rcvd by AUDPREPROC Task - -REFERENCES - None - -EXTERNALIZED FUNCTIONS - None - -Copyright (c) 1992-2009, The Linux Foundation. All rights reserved. - -This software is licensed under the terms of the GNU General Public -License version 2, as published by the Free Software Foundation, and -may be copied, distributed, and modified under those terms. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ -/*=========================================================================== - - EDIT HISTORY FOR FILE - -This section contains comments describing changes made to this file. -Notice that changes are listed in reverse chronological order. - - $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audpreprocmsg.h#3 $ - -===========================================================================*/ - -/* - * ADSPREPROCTASK Messages - * AUDPREPROCTASK uses audPreProcUpRlist to communicate with ARM - * Location : MEMA - * Message Length : 2 - */ - -/* - * Message to indicate particular feature has been enabled or disabled - */ - - -#define AUDPREPROC_MSG_CMD_CFG_DONE_MSG 0x0001 -#define AUDPREPROC_MSG_CMD_CFG_DONE_MSG_LEN \ - sizeof(audpreproc_msg_cmd_cfg_done_msg) - -#define AUDPREPROC_MSG_TYPE_AGC 0x0000 -#define AUDPREPROC_MSG_TYPE_NOISE_REDUCTION 0x0001 -#define AUDPREPROC_MSG_TYPE_IIR_FILTER 0x0002 - - -#define AUDPREPROC_MSG_STATUS_FLAG_ENA -1 -#define AUDPREPROC_MSG_STATUS_FLAG_DIS 0x0000 - -typedef struct { - unsigned short type; - signed short status_flag; -} __attribute__((packed)) audpreproc_msg_cmd_cfg_done_msg; - - -/* - * Message to indicate particular feature has selected for wrong samp freq - */ - -#define AUDPREPROC_MSG_ERROR_MSG_ID 0x0002 -#define AUDPREPROC_MSG_ERROR_MSG_ID_LEN \ - sizeof(audpreproc_msg_error_msg_id) - -#define AUDPREPROC_MSG_ERR_INDEX_NS 0x0000 - -typedef struct { - unsigned short err_index; -} __attribute__((packed)) audpreproc_msg_error_msg_id; - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audreccmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audreccmdi.h deleted file mode 100644 index 72f12c955fd8a9596290acbfee675069873c394f..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audreccmdi.h +++ /dev/null @@ -1,401 +0,0 @@ -#ifndef QDSP5AUDRECCMDI_H -#define QDSP5AUDRECCMDI_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - * - * A U D I O R E C O R D I N T E R N A L C O M M A N D S - * - * GENERAL DESCRIPTION - * This file contains defintions of format blocks of commands - * that are accepted by AUDREC Task - * - * REFERENCES - * None - * - * EXTERNALIZED FUNCTIONS - * None - * - * Copyright (c) 1992-2009, 2011 The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - *====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ - -/*=========================================================================== - - EDIT HISTORY FOR FILE - -This section contains comments describing changes made to this file. -Notice that changes are listed in reverse chronological order. - - $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audreccmdi.h#3 $ - -============================================================================*/ - -/* - * AUDRECTASK COMMANDS - * ARM uses 2 queues to communicate with the AUDRECTASK - * 1.uPAudRecCmdQueue - * Location :MEMC - * Buffer Size : 8 - * No of Buffers in a queue : 3 - * 2.audRecUpBitStreamQueue - * Location : MEMC - * Buffer Size : 4 - * No of buffers in a queue : 2 - */ - -/* - * Commands on uPAudRecCmdQueue - */ - -/* - * Command to initiate and terminate the audio recording section - */ - -#define AUDREC_CMD_CFG 0x0000 -#define AUDREC_CMD_CFG_LEN sizeof(audrec_cmd_cfg) - -#define AUDREC_CMD_TYPE_0_INDEX_WAV 0x0000 -#define AUDREC_CMD_TYPE_0_INDEX_AAC 0x0001 -#define AUDREC_CMD_TYPE_0_INDEX_AMRNB 0x000A -#define AUDREC_CMD_TYPE_0_INDEX_EVRC 0x000B -#define AUDREC_CMD_TYPE_0_INDEX_QCELP 0x000C - -#define AUDREC_CMD_TYPE_0_ENA 0x4000 -#define AUDREC_CMD_TYPE_0_DIS 0x0000 - -#define AUDREC_CMD_TYPE_0_NOUPDATE 0x0000 -#define AUDREC_CMD_TYPE_0_UPDATE 0x8000 - -#define AUDREC_CMD_TYPE_1_INDEX_SBC 0x0002 - -#define AUDREC_CMD_TYPE_1_ENA 0x4000 -#define AUDREC_CMD_TYPE_1_DIS 0x0000 - -#define AUDREC_CMD_TYPE_1_NOUPDATE 0x0000 -#define AUDREC_CMD_TYPE_1_UPDATE 0x8000 - -typedef struct { - unsigned short cmd_id; - unsigned short type_0; - unsigned short type_1; -} __attribute__((packed)) audrec_cmd_cfg; - - -/* - * Command to configure the recording parameters for RecType0(AAC/WAV) encoder - */ - -#define AUDREC_CMD_AREC0PARAM_CFG 0x0001 -#define AUDREC_CMD_AREC0PARAM_CFG_LEN \ - sizeof(audrec_cmd_arec0param_cfg) - -#define AUDREC_CMD_SAMP_RATE_INDX_8000 0x000B -#define AUDREC_CMD_SAMP_RATE_INDX_11025 0x000A -#define AUDREC_CMD_SAMP_RATE_INDX_12000 0x0009 -#define AUDREC_CMD_SAMP_RATE_INDX_16000 0x0008 -#define AUDREC_CMD_SAMP_RATE_INDX_22050 0x0007 -#define AUDREC_CMD_SAMP_RATE_INDX_24000 0x0006 -#define AUDREC_CMD_SAMP_RATE_INDX_32000 0x0005 -#define AUDREC_CMD_SAMP_RATE_INDX_44100 0x0004 -#define AUDREC_CMD_SAMP_RATE_INDX_48000 0x0003 - -#define AUDREC_CMD_STEREO_MODE_MONO 0x0000 -#define AUDREC_CMD_STEREO_MODE_STEREO 0x0001 - -typedef struct { - unsigned short cmd_id; - unsigned short ptr_to_extpkt_buffer_msw; - unsigned short ptr_to_extpkt_buffer_lsw; - unsigned short buf_len; - unsigned short samp_rate_index; - unsigned short stereo_mode; - unsigned short rec_quality; -} __attribute__((packed)) audrec_cmd_arec0param_cfg; - -/* - * Command to configure the recording parameters for RecType1(SBC) encoder - */ - -#define AUDREC_CMD_AREC1PARAM_CFG 0x0002 -#define AUDREC_CMD_AREC1PARAM_CFG_LEN \ - sizeof(audrec_cmd_arec1param_cfg) - -#define AUDREC_CMD_PARAM_BUF_BLOCKS_4 0x0000 -#define AUDREC_CMD_PARAM_BUF_BLOCKS_8 0x0001 -#define AUDREC_CMD_PARAM_BUF_BLOCKS_12 0x0002 -#define AUDREC_CMD_PARAM_BUF_BLOCKS_16 0x0003 - -#define AUDREC_CMD_PARAM_BUF_SUB_BANDS_8 0x0010 -#define AUDREC_CMD_PARAM_BUF_MODE_MONO 0x0000 -#define AUDREC_CMD_PARAM_BUF_MODE_DUAL 0x0040 -#define AUDREC_CMD_PARAM_BUF_MODE_STEREO 0x0050 -#define AUDREC_CMD_PARAM_BUF_MODE_JSTEREO 0x0060 -#define AUDREC_CMD_PARAM_BUF_LOUDNESS 0x0000 -#define AUDREC_CMD_PARAM_BUF_SNR 0x0100 -#define AUDREC_CMD_PARAM_BUF_BASIC_VER 0x0000 - -typedef struct { - unsigned short cmd_id; - unsigned short ptr_to_extpkt_buffer_msw; - unsigned short ptr_to_extpkt_buffer_lsw; - unsigned short buf_len; - unsigned short param_buf; - unsigned short bit_rate_0; - unsigned short bit_rate_1; -} __attribute__((packed)) audrec_cmd_arec1param_cfg; - -/* - * Command to enable encoder for the recording - */ - -#define AUDREC_CMD_ENC_CFG 0x0003 -#define AUDREC_CMD_ENC_CFG_LEN \ - sizeof(struct audrec_cmd_enc_cfg) - - -#define AUDREC_CMD_ENC_ENA 0x8000 -#define AUDREC_CMD_ENC_DIS 0x0000 - -#define AUDREC_CMD_ENC_TYPE_MASK 0x001F - -struct audrec_cmd_enc_cfg { - unsigned short cmd_id; - unsigned short audrec_enc_type; - unsigned short audrec_obj_idx; -} __attribute__((packed)); - -/* - * Command to set external memory config for the selected encoder - */ - -#define AUDREC_CMD_ARECMEM_CFG 0x0004 -#define AUDREC_CMD_ARECMEM_CFG_LEN \ - sizeof(struct audrec_cmd_arecmem_cfg) - - -struct audrec_cmd_arecmem_cfg { - unsigned short cmd_id; - unsigned short audrec_obj_idx; - unsigned short audrec_up_pkt_intm_cnt; - unsigned short audrec_extpkt_buffer_msw; - unsigned short audrec_extpkt_buffer_lsw; - unsigned short audrec_extpkt_buffer_num; -} __attribute__((packed)); - -/* - * Command to configure the recording parameters for selected encoder - */ - -#define AUDREC_CMD_ARECPARAM_CFG 0x0005 -#define AUDREC_CMD_ARECPARAM_COMMON_CFG_LEN \ - sizeof(struct audrec_cmd_arecparam_common_cfg) - - -struct audrec_cmd_arecparam_common_cfg { - unsigned short cmd_id; - unsigned short audrec_obj_idx; -} __attribute__((packed)); - -#define AUDREC_CMD_ARECPARAM_WAV_CFG_LEN \ - sizeof(struct audrec_cmd_arecparam_wav_cfg) - - -struct audrec_cmd_arecparam_wav_cfg { - struct audrec_cmd_arecparam_common_cfg common; - unsigned short samp_rate_idx; - unsigned short stereo_mode; -} __attribute__((packed)); - -#define AUDREC_CMD_ARECPARAM_AAC_CFG_LEN \ - sizeof(struct audrec_cmd_arecparam_aac_cfg) - - -struct audrec_cmd_arecparam_aac_cfg { - struct audrec_cmd_arecparam_common_cfg common; - unsigned short samp_rate_idx; - unsigned short stereo_mode; - unsigned short rec_quality; -} __attribute__((packed)); - -#define AUDREC_CMD_ARECPARAM_SBC_CFG_LEN \ - sizeof(struct audrec_cmd_arecparam_sbc_cfg) - - -struct audrec_cmd_arecparam_sbc_cfg { - struct audrec_cmd_arecparam_common_cfg common; - unsigned short param_buf; - unsigned short bit_rate_0; - unsigned short bit_rate_1; -} __attribute__((packed)); - -#define AUDREC_CMD_ARECPARAM_AMRNB_CFG_LEN \ - sizeof(struct audrec_cmd_arecparam_amrnb_cfg) - - -struct audrec_cmd_arecparam_amrnb_cfg { - struct audrec_cmd_arecparam_common_cfg common; - unsigned short samp_rate_idx; - unsigned short voicememoencweight1; - unsigned short voicememoencweight2; - unsigned short voicememoencweight3; - unsigned short voicememoencweight4; - unsigned short update_mode; - unsigned short dtx_mode; - unsigned short test_mode; - unsigned short used_mode; -} __attribute__((packed)); - -#define AUDREC_CMD_ARECPARAM_EVRC_CFG_LEN \ - sizeof(struct audrec_cmd_arecparam_evrc_cfg) - - -struct audrec_cmd_arecparam_evrc_cfg { - struct audrec_cmd_arecparam_common_cfg common; - unsigned short samp_rate_idx; - unsigned short voicememoencweight1; - unsigned short voicememoencweight2; - unsigned short voicememoencweight3; - unsigned short voicememoencweight4; - unsigned short update_mode; - unsigned short enc_min_rate; - unsigned short enc_max_rate; - unsigned short rate_modulation_cmd; -} __attribute__((packed)); - -#define AUDREC_CMD_ARECPARAM_QCELP_CFG_LEN \ - sizeof(struct audrec_cmd_arecparam_qcelp_cfg) - - -struct audrec_cmd_arecparam_qcelp_cfg { - struct audrec_cmd_arecparam_common_cfg common; - unsigned short samp_rate_idx; - unsigned short voicememoencweight1; - unsigned short voicememoencweight2; - unsigned short voicememoencweight3; - unsigned short voicememoencweight4; - unsigned short update_mode; - unsigned short enc_min_rate; - unsigned short enc_max_rate; - unsigned short rate_modulation_cmd; - unsigned short reduced_rate_level; -} __attribute__((packed)); - -#define AUDREC_CMD_ARECPARAM_FGVNB_CFG_LEN \ - sizeof(struct audrec_cmd_arecparam_fgvnb_cfg) - - -struct audrec_cmd_arecparam_fgvnb_cfg { - struct audrec_cmd_arecparam_common_cfg common; - unsigned short samp_rate_idx; - unsigned short voicememoencweight1; - unsigned short voicememoencweight2; - unsigned short voicememoencweight3; - unsigned short voicememoencweight4; - unsigned short update_mode; - unsigned short fgv_min_rate; - unsigned short fgv_max_rate; - unsigned short reduced_rate_level; -} __attribute__((packed)); - -/* - * Command to configure Tunnel(RT) or Non-Tunnel(FTRT) mode - */ - -#define AUDREC_CMD_ROUTING_MODE 0x0006 -#define AUDREC_CMD_ROUTING_MODE_LEN \ - sizeof(struct audpreproc_audrec_cmd_routing_mode) - -#define AUDIO_ROUTING_MODE_FTRT 0x0001 -#define AUDIO_ROUTING_MODE_RT 0x0002 - -struct audrec_cmd_routing_mode { - unsigned short cmd_id; - unsigned short routing_mode; -} __packed; - -/* - * Command to configure pcm input memory - */ - -#define AUDREC_CMD_PCM_CFG_ARM_TO_ENC 0x0007 -#define AUDREC_CMD_PCM_CFG_ARM_TO_ENC_LEN \ - sizeof(struct audrec_cmd_pcm_cfg_arm_to_enc) - -struct audrec_cmd_pcm_cfg_arm_to_enc { - unsigned short cmd_id; - unsigned short config_update_flag; - unsigned short enable_flag; - unsigned short sampling_freq; - unsigned short channels; - unsigned short frequency_of_intimation; - unsigned short max_number_of_buffers; -} __packed; - -#define AUDREC_PCM_CONFIG_UPDATE_FLAG_ENABLE -1 -#define AUDREC_PCM_CONFIG_UPDATE_FLAG_DISABLE 0 - -#define AUDREC_ENABLE_FLAG_VALUE -1 -#define AUDREC_DISABLE_FLAG_VALUE 0 - -/* - * Command to intimate available pcm buffer - */ - -#define AUDREC_CMD_PCM_BUFFER_PTR_REFRESH_ARM_TO_ENC 0x0008 -#define AUDREC_CMD_PCM_BUFFER_PTR_REFRESH_ARM_TO_ENC_LEN \ - sizeof(struct audrec_cmd_pcm_buffer_ptr_refresh_arm_enc) - -struct audrec_cmd_pcm_buffer_ptr_refresh_arm_enc { - unsigned short cmd_id; - unsigned short num_buffers; - unsigned short buffer_write_cnt_msw; - unsigned short buffer_write_cnt_lsw; - unsigned short buf_address_length[8];/*this array holds address - and length details of - two buffers*/ -} __packed; - -/* - * Command to flush - */ - -#define AUDREC_CMD_FLUSH 0x009 -#define AUDREC_CMD_FLUSH_LEN \ - sizeof(struct audrec_cmd_flush) - -struct audrec_cmd_flush { - unsigned short cmd_id; -} __packed; - -/* - * Commands on audRecUpBitStreamQueue - */ - -/* - * Command to indicate the current packet read count - */ - -#define AUDREC_CMD_PACKET_EXT_PTR 0x0000 -#define AUDREC_CMD_PACKET_EXT_PTR_LEN \ - sizeof(audrec_cmd_packet_ext_ptr) - -#define AUDREC_CMD_TYPE_0 0x0000 -#define AUDREC_CMD_TYPE_1 0x0001 - -typedef struct { - unsigned short cmd_id; - unsigned short type; /* audrec_obj_idx */ - unsigned short curr_rec_count_msw; - unsigned short curr_rec_count_lsw; -} __attribute__((packed)) audrec_cmd_packet_ext_ptr; - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audrecmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audrecmsg.h deleted file mode 100644 index 22bdaa23ad39fd8585858e54952e94616ce0282b..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audrecmsg.h +++ /dev/null @@ -1,223 +0,0 @@ -#ifndef QDSP5AUDRECMSGI_H -#define QDSP5AUDRECMSGI_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - * - * A U D I O R E C O R D M E S S A G E S - * - * GENERAL DESCRIPTION - * This file contains defintions of format blocks of messages - * that are sent by AUDREC Task - * - * REFERENCES - * None - * - * EXTERNALIZED FUNCTIONS - * None - * - * Copyright (c) 1992-2009, 2011 The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - *====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ - -/*=========================================================================== - - EDIT HISTORY FOR FILE - -This section contains comments describing changes made to this file. -Notice that changes are listed in reverse chronological order. - - $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audrecmsg.h#3 $ - -============================================================================*/ - -/* - * AUDRECTASK MESSAGES - * AUDRECTASK uses audRecUpRlist to communicate with ARM - * Location : MEMC - * Buffer size : 4 - * No of buffers in a queue : 2 - */ - -/* - * Message to notify that config command is done - */ - -#define AUDREC_MSG_CMD_CFG_DONE_MSG 0x0002 -#define AUDREC_MSG_CMD_CFG_DONE_MSG_LEN \ - sizeof(struct audrec_msg_cmd_cfg_done_msg) - - -#define AUDREC_MSG_CFG_DONE_TYPE_0_ENA 0x4000 -#define AUDREC_MSG_CFG_DONE_TYPE_0_DIS 0x0000 - -#define AUDREC_MSG_CFG_DONE_TYPE_0_NO_UPDATE 0x0000 -#define AUDREC_MSG_CFG_DONE_TYPE_0_UPDATE 0x8000 - -#define AUDREC_MSG_CFG_DONE_TYPE_1_ENA 0x4000 -#define AUDREC_MSG_CFG_DONE_TYPE_1_DIS 0x0000 - -#define AUDREC_MSG_CFG_DONE_TYPE_1_NO_UPDATE 0x0000 -#define AUDREC_MSG_CFG_DONE_TYPE_1_UPDATE 0x8000 - -#define AUDREC_MSG_CFG_DONE_ENC_ENA 0x8000 -#define AUDREC_MSG_CFG_DONE_ENC_DIS 0x0000 - -struct audrec_msg_cmd_cfg_done_msg { - unsigned short audrec_enc_type; - unsigned short audrec_obj_idx; -} __attribute__((packed)); - -/* - * Message to notify arec0/1 or concurrent encoder cfg done - * and recording params recieved by task - */ - -#define AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG 0x0003 -#define AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG_LEN \ - sizeof(struct audrec_msg_cmd_arec_param_cfg_done_msg) - - -#define AUDREC_MSG_AREC_PARAM_TYPE_0 0x0000 -#define AUDREC_MSG_AREC_PARAM_TYPE_1 0x0001 - -struct audrec_msg_cmd_arec_param_cfg_done_msg { - unsigned short audrec_obj_idx; -} __attribute__((packed)); - -/* - * Message to notify no more buffers are available in ext mem to DME - * Or no concurrent encoder supported - */ -/* for 7x27 */ -#define AUDREC_MSG_FATAL_ERR_MSG 0x0004 -#define AUDREC_MSG_FATAL_ERR_MSG_LEN \ - sizeof(struct audrec_msg_fatal_err_msg) - - -#define AUDREC_MSG_FATAL_ERR_TYPE_0 0x0000 -#define AUDREC_MSG_FATAL_ERR_TYPE_1 0x0001 - -struct audrec_msg_fatal_err_msg { - unsigned short audrec_obj_idx; - unsigned short audrec_err_id; -} __attribute__((packed)); - -/* for 7x27A */ -#define AUDREC_MSG_NO_EXT_PKT_AVAILABLE_MSG 0x0004 -#define AUDREC_MSG_NO_EXT_PKT_AVAILABLE_MSG_LEN \ - sizeof(struct audrec_msg_no_ext_pkt_avail_msg) - -#define AUDREC_MSG_NO_EXT_PKT_AVAILABLE_TYPE_0 0x0000 -#define AUDREC_MSG_NO_EXT_PKT_AVAILABLE_TYPE_1 0x0001 - -struct audrec_msg_no_ext_pkt_avail_msg { - unsigned short audrec_obj_idx; - unsigned short audrec_err_id; -} __packed; - -/* - * Message to notify DME deliverd the encoded pkt to ext pkt buffer - */ - -#define AUDREC_MSG_PACKET_READY_MSG 0x0005 -#define AUDREC_MSG_PACKET_READY_MSG_LEN \ - sizeof(struct audrec_msg_packet_ready_msg) - - -#define AUDREC_MSG_PACKET_READY_TYPE_0 0x0000 -#define AUDREC_MSG_PACKET_READY_TYPE_1 0x0001 - -struct audrec_msg_packet_ready_msg { - unsigned short audrec_obj_idx; - unsigned short pkt_counter_msw; - unsigned short pkt_counter_lsw; - unsigned short pkt_read_cnt_msw; - unsigned short pkt_read_cnt_lsw; -} __attribute__((packed)); - -/* - * Message to notify external memory cfg done and recieved by task - */ - -#define AUDREC_MSG_CMD_AREC_MEM_CFG_DONE_MSG 0x0006 -#define AUDREC_MSG_CMD_AREC_MEM_CFG_DONE_MSG_LEN \ - sizeof(struct audrec_msg_cmd_arec_mem_cfg_done_msg) - - -struct audrec_msg_cmd_arec_mem_cfg_done_msg { - unsigned short audrec_obj_idx; -} __attribute__((packed)); - -/* - * Message to indicate Routing mode - * configuration success or failure - */ - -#define AUDREC_MSG_CMD_ROUTING_MODE_DONE_MSG 0x0007 -#define AUDREC_MSG_CMD_ROUTING_MODE_DONE_MSG_LEN \ - sizeof(struct audrec_msg_cmd_routing_mode_done_msg) - -struct audrec_msg_cmd_routing_mode_done_msg { - unsigned short configuration; -} __packed; - -/* - * Message to indicate pcm buffer configured - */ - -#define AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG 0x0008 -#define AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG_LEN \ - sizeof(struct audrec_cmd_pcm_cfg_arm_to_enc_msg) - -struct audrec_cmd_pcm_cfg_arm_to_enc_msg { - unsigned short configuration; -} __packed; - -/* - * Message to indicate encoded packet is delivered to external buffer in FTRT - */ - -#define AUDREC_UP_NT_PACKET_READY_MSG 0x0009 -#define AUDREC_UP_NT_PACKET_READY_MSG_LEN \ - sizeof(struct audrec_up_nt_packet_ready_msg) - -struct audrec_up_nt_packet_ready_msg { - unsigned short audrec_packetwrite_cnt_lsw; - unsigned short audrec_packetwrite_cnt_msw; - unsigned short audrec_upprev_readcount_lsw; - unsigned short audrec_upprev_readcount_msw; -} __packed; - -/* - * Message to indicate pcm buffer is consumed - */ - -#define AUDREC_CMD_PCM_BUFFER_PTR_UPDATE_ARM_TO_ENC_MSG 0x000A -#define AUDREC_CMD_PCM_BUFFER_PTR_UPDATE_ARM_TO_ENC_MSG_LEN \ - sizeof(struct audrec_cmd_pcm_buffer_ptr_update_arm_to_enc_msg) - -struct audrec_cmd_pcm_buffer_ptr_update_arm_to_enc_msg { - unsigned short buffer_readcnt_msw; - unsigned short buffer_readcnt_lsw; - unsigned short number_of_buffers; - unsigned short buffer_address_length[]; -} __packed; - -/* - * Message to indicate flush acknowledgement - */ - -#define AUDREC_CMD_FLUSH_DONE_MSG 0x000B - -#define ADSP_MESSAGE_ID 0xFFFF - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegcmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegcmdi.h deleted file mode 100644 index 40e96d780169709eced9d0b9e7b91f21fd1ecd0b..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegcmdi.h +++ /dev/null @@ -1,377 +0,0 @@ -#ifndef QDSP5VIDJPEGCMDI_H -#define QDSP5VIDJPEGCMDI_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - - J P E G I N T E R N A L C O M M A N D S - -GENERAL DESCRIPTION - This file contains defintions of format blocks of commands - that are accepted by JPEG Task - -REFERENCES - None - -EXTERNALIZED FUNCTIONS - None - -Copyright (c) 1992-2009, The Linux Foundation. All rights reserved. - -This software is licensed under the terms of the GNU General Public -License version 2, as published by the Free Software Foundation, and -may be copied, distributed, and modified under those terms. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ -/*=========================================================================== - - EDIT HISTORY FOR FILE - -This section contains comments describing changes made to this file. -Notice that changes are listed in reverse chronological order. - - -$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5jpegcmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ -Revision History: -when who what, where, why --------- --- ---------------------------------------------------------- -06/09/08 sv initial version -===========================================================================*/ - -/* - * ARM to JPEG configuration commands are passed through the - * uPJpegCfgCmdQueue - */ - -/* - * Command to configure JPEG Encoder - */ - -#define JPEG_CMD_ENC_CFG 0x0000 -#define JPEG_CMD_ENC_CFG_LEN sizeof(jpeg_cmd_enc_cfg) - -#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_0 0x0000 -#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_90 0x0100 -#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_180 0x0200 -#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_270 0x0300 -#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_M 0x0003 -#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V2 0x0000 -#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V1 0x0001 -#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H1V2 0x0002 - -#define JPEG_CMD_IP_SIZE_CFG_LUMA_HEIGHT_M 0x0000FFFF -#define JPEG_CMD_IP_SIZE_CFG_LUMA_WIDTH_M 0xFFFF0000 -#define JPEG_CMD_ENC_UPSAMP_IP_SIZE_CFG_ENA 0x0001 -#define JPEG_CMD_ENC_UPSAMP_IP_SIZE_CFG_DIS 0x0000 - -#define JPEG_CMD_FRAG_SIZE_LUMA_HEIGHT_M 0xFFFF - -typedef struct { - unsigned int cmd_id; - unsigned int process_cfg; - unsigned int ip_size_cfg; - unsigned int op_size_cfg; - unsigned int frag_cfg; - unsigned int frag_cfg_part[16]; - - unsigned int part_num; - - unsigned int op_buf_0_cfg_part1; - unsigned int op_buf_0_cfg_part2; - unsigned int op_buf_1_cfg_part1; - unsigned int op_buf_1_cfg_part2; - - unsigned int luma_qunt_table[32]; - unsigned int chroma_qunt_table[32]; - - unsigned int upsamp_ip_size_cfg; - unsigned int upsamp_ip_frame_off; - unsigned int upsamp_pp_filter_coeff[64]; -} __attribute__((packed)) jpeg_cmd_enc_cfg; - -/* - * Command to configure JPEG Decoder - */ - -#define JPEG_CMD_DEC_CFG 0x0001 -#define JPEG_CMD_DEC_CFG_LEN sizeof(jpeg_cmd_dec_cfg) - -#define JPEG_CMD_DEC_OP_DATA_FORMAT_M 0x0001 -#define JPEG_CMD_DEC_OP_DATA_FORMAT_H2V2 0x0000 -#define JPEG_CMD_DEC_OP_DATA_FORMAT_H2V1 0x0001 - -#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_8 0x000000 -#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_4 0x010000 -#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_2 0x020000 -#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_1 0x030000 - -#define JPEG_CMD_DEC_IP_STREAM_BUF_CFG_PART3_NOT_FINAL 0x0000 -#define JPEG_CMD_DEC_IP_STREAM_BUF_CFG_PART3_FINAL 0x0001 - - -typedef struct { - unsigned int cmd_id; - unsigned int img_dimension_cfg; - unsigned int op_data_format; - unsigned int restart_interval; - unsigned int ip_buf_partition_num; - unsigned int ip_stream_buf_cfg_part1; - unsigned int ip_stream_buf_cfg_part2; - unsigned int ip_stream_buf_cfg_part3; - unsigned int op_stream_buf_0_cfg_part1; - unsigned int op_stream_buf_0_cfg_part2; - unsigned int op_stream_buf_0_cfg_part3; - unsigned int op_stream_buf_1_cfg_part1; - unsigned int op_stream_buf_1_cfg_part2; - unsigned int op_stream_buf_1_cfg_part3; - unsigned int luma_qunt_table_0_3; - unsigned int luma_qunt_table_4_7; - unsigned int luma_qunt_table_8_11; - unsigned int luma_qunt_table_12_15; - unsigned int luma_qunt_table_16_19; - unsigned int luma_qunt_table_20_23; - unsigned int luma_qunt_table_24_27; - unsigned int luma_qunt_table_28_31; - unsigned int luma_qunt_table_32_35; - unsigned int luma_qunt_table_36_39; - unsigned int luma_qunt_table_40_43; - unsigned int luma_qunt_table_44_47; - unsigned int luma_qunt_table_48_51; - unsigned int luma_qunt_table_52_55; - unsigned int luma_qunt_table_56_59; - unsigned int luma_qunt_table_60_63; - unsigned int chroma_qunt_table_0_3; - unsigned int chroma_qunt_table_4_7; - unsigned int chroma_qunt_table_8_11; - unsigned int chroma_qunt_table_12_15; - unsigned int chroma_qunt_table_16_19; - unsigned int chroma_qunt_table_20_23; - unsigned int chroma_qunt_table_24_27; - unsigned int chroma_qunt_table_28_31; - unsigned int chroma_qunt_table_32_35; - unsigned int chroma_qunt_table_36_39; - unsigned int chroma_qunt_table_40_43; - unsigned int chroma_qunt_table_44_47; - unsigned int chroma_qunt_table_48_51; - unsigned int chroma_qunt_table_52_55; - unsigned int chroma_qunt_table_56_59; - unsigned int chroma_qunt_table_60_63; - unsigned int luma_dc_hm_code_cnt_table_0_3; - unsigned int luma_dc_hm_code_cnt_table_4_7; - unsigned int luma_dc_hm_code_cnt_table_8_11; - unsigned int luma_dc_hm_code_cnt_table_12_15; - unsigned int luma_dc_hm_code_val_table_0_3; - unsigned int luma_dc_hm_code_val_table_4_7; - unsigned int luma_dc_hm_code_val_table_8_11; - unsigned int chroma_dc_hm_code_cnt_table_0_3; - unsigned int chroma_dc_hm_code_cnt_table_4_7; - unsigned int chroma_dc_hm_code_cnt_table_8_11; - unsigned int chroma_dc_hm_code_cnt_table_12_15; - unsigned int chroma_dc_hm_code_val_table_0_3; - unsigned int chroma_dc_hm_code_val_table_4_7; - unsigned int chroma_dc_hm_code_val_table_8_11; - unsigned int luma_ac_hm_code_cnt_table_0_3; - unsigned int luma_ac_hm_code_cnt_table_4_7; - unsigned int luma_ac_hm_code_cnt_table_8_11; - unsigned int luma_ac_hm_code_cnt_table_12_15; - unsigned int luma_ac_hm_code_val_table_0_3; - unsigned int luma_ac_hm_code_val_table_4_7; - unsigned int luma_ac_hm_code_val_table_8_11; - unsigned int luma_ac_hm_code_val_table_12_15; - unsigned int luma_ac_hm_code_val_table_16_19; - unsigned int luma_ac_hm_code_val_table_20_23; - unsigned int luma_ac_hm_code_val_table_24_27; - unsigned int luma_ac_hm_code_val_table_28_31; - unsigned int luma_ac_hm_code_val_table_32_35; - unsigned int luma_ac_hm_code_val_table_36_39; - unsigned int luma_ac_hm_code_val_table_40_43; - unsigned int luma_ac_hm_code_val_table_44_47; - unsigned int luma_ac_hm_code_val_table_48_51; - unsigned int luma_ac_hm_code_val_table_52_55; - unsigned int luma_ac_hm_code_val_table_56_59; - unsigned int luma_ac_hm_code_val_table_60_63; - unsigned int luma_ac_hm_code_val_table_64_67; - unsigned int luma_ac_hm_code_val_table_68_71; - unsigned int luma_ac_hm_code_val_table_72_75; - unsigned int luma_ac_hm_code_val_table_76_79; - unsigned int luma_ac_hm_code_val_table_80_83; - unsigned int luma_ac_hm_code_val_table_84_87; - unsigned int luma_ac_hm_code_val_table_88_91; - unsigned int luma_ac_hm_code_val_table_92_95; - unsigned int luma_ac_hm_code_val_table_96_99; - unsigned int luma_ac_hm_code_val_table_100_103; - unsigned int luma_ac_hm_code_val_table_104_107; - unsigned int luma_ac_hm_code_val_table_108_111; - unsigned int luma_ac_hm_code_val_table_112_115; - unsigned int luma_ac_hm_code_val_table_116_119; - unsigned int luma_ac_hm_code_val_table_120_123; - unsigned int luma_ac_hm_code_val_table_124_127; - unsigned int luma_ac_hm_code_val_table_128_131; - unsigned int luma_ac_hm_code_val_table_132_135; - unsigned int luma_ac_hm_code_val_table_136_139; - unsigned int luma_ac_hm_code_val_table_140_143; - unsigned int luma_ac_hm_code_val_table_144_147; - unsigned int luma_ac_hm_code_val_table_148_151; - unsigned int luma_ac_hm_code_val_table_152_155; - unsigned int luma_ac_hm_code_val_table_156_159; - unsigned int luma_ac_hm_code_val_table_160_161; - unsigned int chroma_ac_hm_code_cnt_table_0_3; - unsigned int chroma_ac_hm_code_cnt_table_4_7; - unsigned int chroma_ac_hm_code_cnt_table_8_11; - unsigned int chroma_ac_hm_code_cnt_table_12_15; - unsigned int chroma_ac_hm_code_val_table_0_3; - unsigned int chroma_ac_hm_code_val_table_4_7; - unsigned int chroma_ac_hm_code_val_table_8_11; - unsigned int chroma_ac_hm_code_val_table_12_15; - unsigned int chroma_ac_hm_code_val_table_16_19; - unsigned int chroma_ac_hm_code_val_table_20_23; - unsigned int chroma_ac_hm_code_val_table_24_27; - unsigned int chroma_ac_hm_code_val_table_28_31; - unsigned int chroma_ac_hm_code_val_table_32_35; - unsigned int chroma_ac_hm_code_val_table_36_39; - unsigned int chroma_ac_hm_code_val_table_40_43; - unsigned int chroma_ac_hm_code_val_table_44_47; - unsigned int chroma_ac_hm_code_val_table_48_51; - unsigned int chroma_ac_hm_code_val_table_52_55; - unsigned int chroma_ac_hm_code_val_table_56_59; - unsigned int chroma_ac_hm_code_val_table_60_63; - unsigned int chroma_ac_hm_code_val_table_64_67; - unsigned int chroma_ac_hm_code_val_table_68_71; - unsigned int chroma_ac_hm_code_val_table_72_75; - unsigned int chroma_ac_hm_code_val_table_76_79; - unsigned int chroma_ac_hm_code_val_table_80_83; - unsigned int chroma_ac_hm_code_val_table_84_87; - unsigned int chroma_ac_hm_code_val_table_88_91; - unsigned int chroma_ac_hm_code_val_table_92_95; - unsigned int chroma_ac_hm_code_val_table_96_99; - unsigned int chroma_ac_hm_code_val_table_100_103; - unsigned int chroma_ac_hm_code_val_table_104_107; - unsigned int chroma_ac_hm_code_val_table_108_111; - unsigned int chroma_ac_hm_code_val_table_112_115; - unsigned int chroma_ac_hm_code_val_table_116_119; - unsigned int chroma_ac_hm_code_val_table_120_123; - unsigned int chroma_ac_hm_code_val_table_124_127; - unsigned int chroma_ac_hm_code_val_table_128_131; - unsigned int chroma_ac_hm_code_val_table_132_135; - unsigned int chroma_ac_hm_code_val_table_136_139; - unsigned int chroma_ac_hm_code_val_table_140_143; - unsigned int chroma_ac_hm_code_val_table_144_147; - unsigned int chroma_ac_hm_code_val_table_148_151; - unsigned int chroma_ac_hm_code_val_table_152_155; - unsigned int chroma_ac_hm_code_val_table_156_159; - unsigned int chroma_ac_hm_code_val_table_160_161; -} __attribute__((packed)) jpeg_cmd_dec_cfg; - - -/* - * ARM to JPEG configuration commands are passed through the - * uPJpegActionCmdQueue - */ - -/* - * Command to start the encode process - */ - -#define JPEG_CMD_ENC_ENCODE 0x0001 -#define JPEG_CMD_ENC_ENCODE_LEN sizeof(jpeg_cmd_enc_encode) - - -typedef struct { - unsigned short cmd_id; -} __attribute__((packed)) jpeg_cmd_enc_encode; - - -/* - * Command to transition from current state of encoder to IDLE state - */ - -#define JPEG_CMD_ENC_IDLE 0x0006 -#define JPEG_CMD_ENC_IDLE_LEN sizeof(jpeg_cmd_enc_idle) - - -typedef struct { - unsigned short cmd_id; -} __attribute__((packed)) jpeg_cmd_enc_idle; - - -/* - * Command to inform the encoder that another buffer is ready - */ - -#define JPEG_CMD_ENC_OP_CONSUMED 0x0002 -#define JPEG_CMD_ENC_OP_CONSUMED_LEN sizeof(jpeg_cmd_enc_op_consumed) - - -typedef struct { - unsigned int cmd_id; - unsigned int op_buf_addr; - unsigned int op_buf_size; -} __attribute__((packed)) jpeg_cmd_enc_op_consumed; - - -/* - * Command to start the decoding process - */ - -#define JPEG_CMD_DEC_DECODE 0x0003 -#define JPEG_CMD_DEC_DECODE_LEN sizeof(jpeg_cmd_dec_decode) - - -typedef struct { - unsigned short cmd_id; -} __attribute__((packed)) jpeg_cmd_dec_decode; - - -/* - * Command to transition from the current state of decoder to IDLE - */ - -#define JPEG_CMD_DEC_IDLE 0x0007 -#define JPEG_CMD_DEC_IDLE_LEN sizeof(jpeg_cmd_dec_idle) - - -typedef struct { - unsigned short cmd_id; -} __attribute__((packed)) jpeg_cmd_dec_idle; - - -/* - * Command to inform that an op buffer is ready for use - */ - -#define JPEG_CMD_DEC_OP_CONSUMED 0x0004 -#define JPEG_CMD_DEC_OP_CONSUMED_LEN sizeof(jpeg_cmd_dec_op_consumed) - - -typedef struct { - unsigned int cmd_id; - unsigned int luma_op_buf_addr; - unsigned int luma_op_buf_size; - unsigned int chroma_op_buf_addr; -} __attribute__((packed)) jpeg_cmd_dec_op_consumed; - - -/* - * Command to pass a new ip buffer to the jpeg decoder - */ - -#define JPEG_CMD_DEC_IP 0x0005 -#define JPEG_CMD_DEC_IP_LEN sizeof(jpeg_cmd_dec_ip_len) - -#define JPEG_CMD_EOI_INDICATOR_NOT_END 0x0000 -#define JPEG_CMD_EOI_INDICATOR_END 0x0001 - -typedef struct { - unsigned int cmd_id; - unsigned int ip_buf_addr; - unsigned int ip_buf_size; - unsigned int eoi_indicator; -} __attribute__((packed)) jpeg_cmd_dec_ip; - - - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegmsg.h deleted file mode 100644 index 9b5ce77e5b2440a0aed071d2047dab1ff8d9b952..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegmsg.h +++ /dev/null @@ -1,177 +0,0 @@ -#ifndef QDSP5VIDJPEGMSGI_H -#define QDSP5VIDJPEGMSGI_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - - J P E G I N T E R N A L M E S S A G E S - -GENERAL DESCRIPTION - This file contains defintions of format blocks of messages - that are sent by JPEG Task - -REFERENCES - None - -EXTERNALIZED FUNCTIONS - None - -Copyright (c) 1992-2009, The Linux Foundation. All rights reserved. - -This software is licensed under the terms of the GNU General Public -License version 2, as published by the Free Software Foundation, and -may be copied, distributed, and modified under those terms. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ -/*=========================================================================== - - EDIT HISTORY FOR FILE - -This section contains comments describing changes made to this file. -Notice that changes are listed in reverse chronological order. - -$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5jpegmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ -Revision History: - -when who what, where, why --------- --- ---------------------------------------------------------- -05/10/08 sv initial version -===========================================================================*/ - -/* - * Messages from JPEG task to ARM through jpeguPMsgQueue - */ - -/* - * Message is ACK for CMD_JPEGE_ENCODE cmd - */ - -#define JPEG_MSG_ENC_ENCODE_ACK 0x0000 -#define JPEG_MSG_ENC_ENCODE_ACK_LEN \ - sizeof(jpeg_msg_enc_encode_ack) - -typedef struct { -} __attribute__((packed)) jpeg_msg_enc_encode_ack; - - -/* - * Message informs the up when op buffer is ready for consumption and - * when encoding is complete or errors - */ - -#define JPEG_MSG_ENC_OP_PRODUCED 0x0001 -#define JPEG_MSG_ENC_OP_PRODUCED_LEN \ - sizeof(jpeg_msg_enc_op_produced) - -#define JPEG_MSGOP_OP_BUF_STATUS_ENC_DONE_PROGRESS 0x0000 -#define JPEG_MSGOP_OP_BUF_STATUS_ENC_DONE_COMPLETE 0x0001 -#define JPEG_MSGOP_OP_BUF_STATUS_ENC_ERR 0x10000 - -typedef struct { - unsigned int op_buf_addr; - unsigned int op_buf_size; - unsigned int op_buf_status; -} __attribute__((packed)) jpeg_msg_enc_op_produced; - - -/* - * Message to ack CMD_JPEGE_IDLE - */ - -#define JPEG_MSG_ENC_IDLE_ACK 0x0002 -#define JPEG_MSG_ENC_IDLE_ACK_LEN sizeof(jpeg_msg_enc_idle_ack) - - -typedef struct { -} __attribute__ ((packed)) jpeg_msg_enc_idle_ack; - - -/* - * Message to indicate the illegal command - */ - -#define JPEG_MSG_ENC_ILLEGAL_COMMAND 0x0003 -#define JPEG_MSG_ENC_ILLEGAL_COMMAND_LEN \ - sizeof(jpeg_msg_enc_illegal_command) - -typedef struct { - unsigned int status; -} __attribute__((packed)) jpeg_msg_enc_illegal_command; - - -/* - * Message to ACK CMD_JPEGD_DECODE - */ - -#define JPEG_MSG_DEC_DECODE_ACK 0x0004 -#define JPEG_MSG_DEC_DECODE_ACK_LEN \ - sizeof(jpeg_msg_dec_decode_ack) - - -typedef struct { -} __attribute__((packed)) jpeg_msg_dec_decode_ack; - - -/* - * Message to inform up that an op buffer is ready for consumption and when - * decoding is complete or an error occurs - */ - -#define JPEG_MSG_DEC_OP_PRODUCED 0x0005 -#define JPEG_MSG_DEC_OP_PRODUCED_LEN \ - sizeof(jpeg_msg_dec_op_produced) - -#define JPEG_MSG_DEC_OP_BUF_STATUS_PROGRESS 0x0000 -#define JPEG_MSG_DEC_OP_BUF_STATUS_DONE 0x0001 - -typedef struct { - unsigned int luma_op_buf_addr; - unsigned int chroma_op_buf_addr; - unsigned int num_mcus; - unsigned int op_buf_status; -} __attribute__((packed)) jpeg_msg_dec_op_produced; - -/* - * Message to ack CMD_JPEGD_IDLE cmd - */ - -#define JPEG_MSG_DEC_IDLE_ACK 0x0006 -#define JPEG_MSG_DEC_IDLE_ACK_LEN sizeof(jpeg_msg_dec_idle_ack) - - -typedef struct { -} __attribute__((packed)) jpeg_msg_dec_idle_ack; - - -/* - * Message to indicate illegal cmd was received - */ - -#define JPEG_MSG_DEC_ILLEGAL_COMMAND 0x0007 -#define JPEG_MSG_DEC_ILLEGAL_COMMAND_LEN \ - sizeof(jpeg_msg_dec_illegal_command) - - -typedef struct { - unsigned int status; -} __attribute__((packed)) jpeg_msg_dec_illegal_command; - -/* - * Message to request up for the next segment of ip bit stream - */ - -#define JPEG_MSG_DEC_IP_REQUEST 0x0008 -#define JPEG_MSG_DEC_IP_REQUEST_LEN \ - sizeof(jpeg_msg_dec_ip_request) - - -typedef struct { -} __attribute__((packed)) jpeg_msg_dec_ip_request; - - - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmcmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmcmdi.h deleted file mode 100644 index 3d4fe5618d628251d5af393a51a6edd7118f7c95..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmcmdi.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef QDSP5LPMCMDI_H -#define QDSP5LPMCMDI_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - - L P M I N T E R N A L C O M M A N D S - -GENERAL DESCRIPTION - This file contains defintions of format blocks of commands - that are accepted by LPM Task - -REFERENCES - None - -EXTERNALIZED FUNCTIONS - None - -Copyright (c) 1992-2009, The Linux Foundation. All rights reserved. - -This software is licensed under the terms of the GNU General Public -License version 2, as published by the Free Software Foundation, and -may be copied, distributed, and modified under those terms. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ -/*=========================================================================== - - EDIT HISTORY FOR FILE - -This section contains comments describing changes made to this file. -Notice that changes are listed in reverse chronological order. - - -$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5lpmcmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ -Revision History: - -when who what, where, why --------- --- ---------------------------------------------------------- -06/12/08 sv initial version -===========================================================================*/ - - -/* - * Command to start LPM processing based on the config params - */ - -#define LPM_CMD_START 0x0000 -#define LPM_CMD_START_LEN sizeof(lpm_cmd_start) - -#define LPM_CMD_SPATIAL_FILTER_PART_OPMODE_0 0x00000000 -#define LPM_CMD_SPATIAL_FILTER_PART_OPMODE_1 0x00010000 -typedef struct { - unsigned int cmd_id; - unsigned int ip_data_cfg_part1; - unsigned int ip_data_cfg_part2; - unsigned int ip_data_cfg_part3; - unsigned int ip_data_cfg_part4; - unsigned int op_data_cfg_part1; - unsigned int op_data_cfg_part2; - unsigned int op_data_cfg_part3; - unsigned int spatial_filter_part[32]; -} __attribute__((packed)) lpm_cmd_start; - - - -/* - * Command to stop LPM processing - */ - -#define LPM_CMD_IDLE 0x0001 -#define LPM_CMD_IDLE_LEN sizeof(lpm_cmd_idle) - -typedef struct { - unsigned int cmd_id; -} __attribute__((packed)) lpm_cmd_idle; - - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmmsg.h deleted file mode 100644 index 81f766d38fa0448250e30fd463507ec11f4b59c2..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmmsg.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef QDSP5LPMMSGI_H -#define QDSP5LPMMSGI_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - - L P M I N T E R N A L M E S S A G E S - -GENERAL DESCRIPTION - This file contains defintions of format blocks of commands - that are accepted by LPM Task - -REFERENCES - None - -EXTERNALIZED FUNCTIONS - None - -Copyright (c) 1992-2009, The Linux Foundation. All rights reserved. - -This software is licensed under the terms of the GNU General Public -License version 2, as published by the Free Software Foundation, and -may be copied, distributed, and modified under those terms. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ -/*=========================================================================== - - EDIT HISTORY FOR FILE - -This section contains comments describing changes made to this file. -Notice that changes are listed in reverse chronological order. - -$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5lpmmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ -Revision History: - -when who what, where, why --------- --- ---------------------------------------------------------- -06/12/08 sv initial version -===========================================================================*/ - -/* - * Message to acknowledge CMD_LPM_IDLE command - */ - -#define LPM_MSG_IDLE_ACK 0x0000 -#define LPM_MSG_IDLE_ACK_LEN sizeof(lpm_msg_idle_ack) - -typedef struct { -} __attribute__((packed)) lpm_msg_idle_ack; - - -/* - * Message to acknowledge CMD_LPM_START command - */ - - -#define LPM_MSG_START_ACK 0x0001 -#define LPM_MSG_START_ACK_LEN sizeof(lpm_msg_start_ack) - - -typedef struct { -} __attribute__((packed)) lpm_msg_start_ack; - - -/* - * Message to notify the ARM that LPM processing is complete - */ - -#define LPM_MSG_DONE 0x0002 -#define LPM_MSG_DONE_LEN sizeof(lpm_msg_done) - -typedef struct { -} __attribute__((packed)) lpm_msg_done; - - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtcmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtcmdi.h deleted file mode 100644 index 9b9521fa17b89f16e355b71aeb9ac7eedd22f2ee..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtcmdi.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2010, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef QDSP5RMTCMDI_H -#define QDSP5RMTCMDI_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - - R M T A S K I N T E R N A L C O M M A N D S - -GENERAL DESCRIPTION - This file contains defintions of format blocks of commands - that are accepted by RM Task - -REFERENCES - None - -EXTERNALIZED FUNCTIONS - None - -*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ - -/* - * ARM to RMTASK Commands - * - * ARM uses one command queue to communicate with AUDPPTASK - * 1) apuRmtQueue: Used to send commands to RMTASK from APPS processor - * Location : MEMA - * Buffer Size : 3 words - */ - -#define RM_CMD_AUD_CODEC_CFG 0x0 - -#define RM_AUD_CLIENT_ID 0x0 -#define RMT_ENABLE 0x1 -#define RMT_DISABLE 0x0 - -struct aud_codec_config_cmd { - unsigned short cmd_id; - unsigned char task_id; - unsigned char client_id; - unsigned short enable; - unsigned short dec_type; -} __attribute__((packed)); - -#endif /* QDSP5RMTCMDI_H */ diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtmsg.h deleted file mode 100644 index 4e7ed33e1f9c69e660eb3e4d593664f272864003..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtmsg.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2010, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef QDSP5RMTMSG_H -#define QDSP5RMTMSG_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - - R M T A S K M S G - -GENERAL DESCRIPTION - Messages sent by RMTASK to APPS PROCESSOR - -REFERENCES - None - -EXTERNALIZED FUNCTIONS - None -*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ - -/* - * RMTASK uses RmtApuRlist to send messages to the APPS PROCESSOR - * Location : MEMA - * Buffer Size : 3 - */ - -#define RMT_CODEC_CONFIG_ACK 0x1 - -struct aud_codec_config_ack { - unsigned char task_id; - unsigned char client_id; - unsigned char reason; - unsigned char enable; - unsigned short dec_type; -} __attribute__((packed)); - -#define RMT_DSP_OUT_OF_MIPS 0x2 - -struct rmt_dsp_out_of_mips { - unsigned short dec_info; - unsigned short rvd_0; - unsigned short rvd_1; -} __attribute__((packed)); - -#endif /* QDSP5RMTMSG_H */ - diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdeccmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdeccmdi.h deleted file mode 100644 index 89af4aae143a7b9e3bbdef14466bd49796e64bd1..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdeccmdi.h +++ /dev/null @@ -1,189 +0,0 @@ -#ifndef QDSP5VIDDECCMDI_H -#define QDSP5VIDDECCMDI_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - - V I D E O D E C O D E R I N T E R N A L C O M M A N D S - -GENERAL DESCRIPTION - This file contains defintions of format blocks of commands - that are accepted by VIDDEC Task - -REFERENCES - None - -EXTERNALIZED FUNCTIONS - None - -Copyright (c) 1992-2009, The Linux Foundation. All rights reserved. - -This software is licensed under the terms of the GNU General Public -License version 2, as published by the Free Software Foundation, and -may be copied, distributed, and modified under those terms. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ -/*=========================================================================== - - EDIT HISTORY FOR FILE - -This section contains comments describing changes made to this file. -Notice that changes are listed in reverse chronological order. - -$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vdeccmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ -Revision History: - -when who what, where, why --------- --- ---------------------------------------------------------- -05/10/08 ac initial version -===========================================================================*/ - - -/* - * Command to inform VIDDEC that new subframe packet is ready - */ - -#define VIDDEC_CMD_SUBFRAME_PKT 0x0000 -#define VIDDEC_CMD_SUBFRAME_PKT_LEN \ - sizeof(viddec_cmd_subframe_pkt) - -#define VIDDEC_CMD_SF_INFO_1_DM_DMA_STATS_EXCHANGE_FLAG_DM 0x0000 -#define VIDDEC_CMD_SF_INFO_1_DM_DMA_STATS_EXCHANGE_FLAG_DMA 0x0001 - -#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_CONTI 0x0000 -#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_FIRST 0x0001 -#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_LAST 0x0002 -#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_FIRST_AND_LAST 0x0003 - -#define VIDDEC_CMD_CODEC_SELECTION_WORD_MPEG_4 0x0000 -#define VIDDEC_CMD_CODEC_SELECTION_WORD_H_263_P0 0x0001 -#define VIDDEC_CMD_CODEC_SELECTION_WORD_H_264 0x0002 -#define VIDDEC_CMD_CODEC_SELECTION_WORD_H_263_p3 0x0003 -#define VIDDEC_CMD_CODEC_SELECTION_WORD_RV9 0x0004 -#define VIDDEC_CMD_CODEC_SELECTION_WORD_WMV9 0x0005 -#define VIDDEC_CMD_CODEC_SELECTION_WORD_SMCDB 0x0006 -#define VIDDEC_CMD_CODEC_SELECTION_WORD_QFRE 0x0007 -#define VIDDEC_CMD_CODEC_SELECTION_WORD_VLD 0x0008 - -typedef struct { - unsigned short cmd_id; - unsigned short packet_seq_number; - unsigned short codec_instance_id; - unsigned short subframe_packet_size_high; - unsigned short subframe_packet_size_low; - unsigned short subframe_packet_high; - unsigned short subframe_packet_low; - unsigned short subframe_packet_partition; - unsigned short statistics_packet_size_high; - unsigned short statistics_packet_size_low; - unsigned short statistics_packet_high; - unsigned short statistics_packet_low; - unsigned short statistics_partition; - unsigned short subframe_info_1; - unsigned short subframe_info_0; - unsigned short codec_selection_word; - unsigned short num_mbs; -} __attribute__((packed)) viddec_cmd_subframe_pkt; - - -/* - * Command to inform VIDDEC task that post processing is required for the frame - */ - -#define VIDDEC_CMD_PP_ENABLE 0x0001 -#define VIDDEC_CMD_PP_ENABLE_LEN \ - sizeof(viddec_cmd_pp_enable) - -#define VIDDEC_CMD_PP_INFO_0_DM_DMA_LS_EXCHANGE_FLAG_DM 0x0000 -#define VIDDEC_CMD_PP_INFO_0_DM_DMA_LS_EXCHANGE_FLAG_DMA 0x0001 - -typedef struct { - unsigned short cmd_id; - unsigned short packet_seq_num; - unsigned short codec_instance_id; - unsigned short postproc_info_0; - unsigned short codec_selection_word; - unsigned short pp_output_addr_high; - unsigned short pp_output_addr_low; - unsigned short postproc_info_1; - unsigned short load_sharing_packet_size_high; - unsigned short load_sharing_packet_size_low; - unsigned short load_sharing_packet_high; - unsigned short load_sharing_packet_low; - unsigned short load_sharing_partition; - unsigned short pp_param_0; - unsigned short pp_param_1; - unsigned short pp_param_2; - unsigned short pp_param_3; -} __attribute__((packed)) viddec_cmd_pp_enable; - - -/* - * FRAME Header Packet : It is at the start of new frame - */ - -#define VIDDEC_CMD_FRAME_HEADER_PACKET 0x0002 - -#define VIDDEC_CMD_FRAME_INFO_0_ERROR_SKIP 0x0000 -#define VIDDEC_CMD_FRAME_INFO_0_ERROR_BLACK 0x0800 - -/* - * SLICE HEADER PACKET - * I-Slice and P-Slice - */ - -#define VIDDEC_CMD_SLICE_HEADER_PKT_ISLICE 0x0003 -#define VIDDEC_CMD_SLICE_HEADER_PKT_ISLICE_LEN \ - sizeof(viddec_cmd_slice_header_pkt_islice) - -#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_PSLICE 0x0000 -#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_BSLICE 0x0100 -#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_ISLICE 0x0200 -#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_SPSLICE 0x0300 -#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_SISLICE 0x0400 -#define VIDDEC_CMD_ISLICE_INFO_1_NOPADDING 0x0000 -#define VIDDEC_CMD_ISLICE_INFO_1_PADDING 0x0800 - -#define VIDDEC_CMD_ISLICE_EOP_MARKER 0x7FFF - -typedef struct { - unsigned short cmd_id; - unsigned short packet_id; - unsigned short slice_info_0; - unsigned short slice_info_1; - unsigned short slice_info_2; - unsigned short num_bytes_in_rbsp_high; - unsigned short num_bytes_in_rbsp_low; - unsigned short num_bytes_in_rbsp_consumed; - unsigned short end_of_packet_marker; -} __attribute__((packed)) viddec_cmd_slice_header_pkt_islice; - - -#define VIDDEC_CMD_SLICE_HEADER_PKT_PSLICE 0x0003 -#define VIDDEC_CMD_SLICE_HEADER_PKT_PSLICE_LEN \ - sizeof(viddec_cmd_slice_header_pkt_pslice) - - -typedef struct { - unsigned short cmd_id; - unsigned short packet_id; - unsigned short slice_info_0; - unsigned short slice_info_1; - unsigned short slice_info_2; - unsigned short slice_info_3; - unsigned short refidx_l0_map_tab_info_0; - unsigned short refidx_l0_map_tab_info_1; - unsigned short refidx_l0_map_tab_info_2; - unsigned short refidx_l0_map_tab_info_3; - unsigned short num_bytes_in_rbsp_high; - unsigned short num_bytes_in_rbsp_low; - unsigned short num_bytes_in_rbsp_consumed; - unsigned short end_of_packet_marker; -} __attribute__((packed)) viddec_cmd_slice_header_pkt_pslice; - - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdecmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdecmsg.h deleted file mode 100644 index ccd129d19a444a1060fd6d138464d4c4e0417dd5..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdecmsg.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef QDSP5VIDDECMSGI_H -#define QDSP5VIDDECMSGI_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - - V I D E O D E C O D E R I N T E R N A L M E S S A G E S - -GENERAL DESCRIPTION - This file contains defintions of format blocks of messages - that are sent by VIDDEC Task - -REFERENCES - None - -EXTERNALIZED FUNCTIONS - None - -Copyright (c) 1992-2009, The Linux Foundation. All rights reserved. - -This software is licensed under the terms of the GNU General Public -License version 2, as published by the Free Software Foundation, and -may be copied, distributed, and modified under those terms. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ -/*=========================================================================== - - EDIT HISTORY FOR FILE - -This section contains comments describing changes made to this file. -Notice that changes are listed in reverse chronological order. - -$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vdecmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ -Revision History: - -when who what, where, why --------- --- ---------------------------------------------------------- -05/10/08 ac initial version -===========================================================================*/ - -/* - * Message to inform ARM which VDEC_SUBFRAME_PKT_CMD processed by VIDDEC TASK - */ - -#define VIDDEC_MSG_SUBF_DONE 0x0000 -#define VIDDEC_MSG_SUBF_DONE_LEN \ - sizeof(viddec_msg_subf_done) - -typedef struct { - unsigned short packet_seq_number; - unsigned short codec_instance_id; -} __attribute__((packed)) viddec_msg_subf_done; - - -/* - * Message to inform ARM one frame has been decoded - */ - -#define VIDDEC_MSG_FRAME_DONE 0x0001 -#define VIDDEC_MSG_FRAME_DONE_LEN \ - sizeof(viddec_msg_frame_done) - -typedef struct { - unsigned short packet_seq_number; - unsigned short codec_instance_id; -} __attribute__((packed)) viddec_msg_frame_done; - - -/* - * Message to inform ARM that post processing frame has been decoded - */ - -#define VIDDEC_MSG_PP_ENABLE_CMD_DONE 0x0002 -#define VIDDEC_MSG_PP_ENABLE_CMD_DONE_LEN \ - sizeof(viddec_msg_pp_enable_cmd_done) - -typedef struct { - unsigned short packet_seq_number; - unsigned short codec_instance_id; -} __attribute__((packed)) viddec_msg_pp_enable_cmd_done; - - -/* - * Message to inform ARM that one post processing frame has been decoded - */ - - -#define VIDDEC_MSG_PP_FRAME_DONE 0x0003 -#define VIDDEC_MSG_PP_FRAME_DONE_LEN \ - sizeof(viddec_msg_pp_frame_done) - -#define VIDDEC_MSG_DISP_WORTHY_DISP 0x0000 -#define VIDDEC_MSG_DISP_WORTHY_DISP_NONE 0xFFFF - - -typedef struct { - unsigned short packet_seq_number; - unsigned short codec_instance_id; - unsigned short display_worthy; -} __attribute__((packed)) viddec_msg_pp_frame_done; - - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5venccmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5venccmdi.h deleted file mode 100644 index 34e00a61a349cfdc68ef5b983e8fb1abca344493..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5venccmdi.h +++ /dev/null @@ -1,231 +0,0 @@ -#ifndef QDSP5VIDENCCMDI_H -#define QDSP5VIDENCCMDI_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - - V I D E O E N C O D E R I N T E R N A L C O M M A N D S - -GENERAL DESCRIPTION - This file contains defintions of format blocks of commands - that are accepted by VIDENC Task - -REFERENCES - None - -EXTERNALIZED FUNCTIONS - None - -Copyright (c) 2008-2009, The Linux Foundation. All rights reserved. -*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ -/*=========================================================================== - - EDIT HISTORY FOR FILE - -This section contains comments describing changes made to this file. -Notice that changes are listed in reverse chronological order. - -Revision History: - -when who what, where, why --------- --- ---------------------------------------------------------- -09/25/08 umeshp initial version -===========================================================================*/ - - #define VIDENC_CMD_CFG 0x0000 - #define VIDENC_CMD_ACTIVE 0x0001 - #define VIDENC_CMD_IDLE 0x0002 - #define VIDENC_CMD_FRAME_START 0x0003 - #define VIDENC_CMD_STATUS_QUERY 0x0004 - #define VIDENC_CMD_RC_CFG 0x0005 - #define VIDENC_CMD_INTRA_REFRESH 0x0006 - #define VIDENC_CMD_CODEC_CONFIG 0x0007 - #define VIDENC_CMD_VIDEO_CONFIG 0x0008 - #define VIDENC_CMD_PARAMETER_UPDATE 0x0009 - #define VIDENC_CMD_VENC_CLOCK 0x000A - #define VIDENC_CMD_DIS_CFG 0x000B - #define VIDENC_CMD_DIS 0x000C - #define VIDENC_CMD_DIGITAL_ZOOM 0x000D - - - - -/* - * Command to pass the frame message information to VIDENC - */ - - -#define VIDENC_CMD_FRAME_START_LEN \ - sizeof(videnc_cmd_frame_start) - -typedef struct { - unsigned short cmd_id; - unsigned short frame_info; - unsigned short frame_rho_budget_word_high; - unsigned short frame_rho_budget_word_low; - unsigned short input_luma_addr_high; - unsigned short input_luma_addr_low; - unsigned short input_chroma_addr_high; - unsigned short input_chroma_addr_low; - unsigned short ref_vop_buf_ptr_high; - unsigned short ref_vop_buf_ptr_low; - unsigned short enc_pkt_buf_ptr_high; - unsigned short enc_pkt_buf_ptr_low; - unsigned short enc_pkt_buf_size_high; - unsigned short enc_pkt_buf_size_low; - unsigned short unfilt_recon_vop_buf_ptr_high; - unsigned short unfilt_recon_vop_buf_ptr_low; - unsigned short filt_recon_vop_buf_ptr_high; - unsigned short filt_recon_vop_buf_ptr_low; -} __attribute__((packed)) videnc_cmd_frame_start; - -/* - * Command to pass the frame-level digital stabilization parameters to VIDENC - */ - - -#define VIDENC_CMD_DIS_LEN \ - sizeof(videnc_cmd_dis) - -typedef struct { - unsigned short cmd_id; - unsigned short vfe_out_prev_luma_addr_high; - unsigned short vfe_out_prev_luma_addr_low; - unsigned short stabilization_info; -} __attribute__((packed)) videnc_cmd_dis; - -/* - * Command to pass the codec related parameters to VIDENC - */ - - -#define VIDENC_CMD_CFG_LEN \ - sizeof(videnc_cmd_cfg) - -typedef struct { - unsigned short cmd_id; - unsigned short cfg_info_0; - unsigned short cfg_info_1; - unsigned short four_mv_threshold; - unsigned short ise_fse_mv_cost_fac; - unsigned short venc_frame_dim; - unsigned short venc_DM_partition; -} __attribute__((packed)) videnc_cmd_cfg; - -/* - * Command to start the video encoding - */ - - -#define VIDENC_CMD_ACTIVE_LEN \ - sizeof(videnc_cmd_active) - -typedef struct { - unsigned short cmd_id; -} __attribute__((packed)) videnc_cmd_active; - -/* - * Command to stop the video encoding - */ - - -#define VIDENC_CMD_IDLE_LEN \ - sizeof(videnc_cmd_idle) - -typedef struct { - unsigned short cmd_id; -} __attribute__((packed)) videnc_cmd_idle; - -/* - * Command to query staus of VIDENC - */ - - -#define VIDENC_CMD_STATUS_QUERY_LEN \ - sizeof(videnc_cmd_status_query) - -typedef struct { - unsigned short cmd_id; -} __attribute__((packed)) videnc_cmd_status_query; - -/* - * Command to set rate control for a frame - */ - - -#define VIDENC_CMD_RC_CFG_LEN \ - sizeof(videnc_cmd_rc_cfg) - -typedef struct { - unsigned short cmd_id; - unsigned short max_frame_qp_delta; - unsigned short max_min_frame_qp; -} __attribute__((packed)) videnc_cmd_rc_cfg; - -/* - * Command to set intra-refreshing - */ - - -#define VIDENC_CMD_INTRA_REFRESH_LEN \ - sizeof(videnc_cmd_intra_refresh) - -typedef struct { - unsigned short cmd_id; - unsigned short num_mb_refresh; - unsigned short mb_index[15]; -} __attribute__((packed)) videnc_cmd_intra_refresh; - -/* - * Command to pass digital zoom information to the VIDENC - */ -#define VIDENC_CMD_DIGITAL_ZOOM_LEN \ - sizeof(videnc_cmd_digital_zoom) - -typedef struct { - unsigned short cmd_id; - unsigned short digital_zoom_en; - unsigned short luma_frame_shift_X; - unsigned short luma_frame_shift_Y; - unsigned short up_ip_luma_rows; - unsigned short up_ip_luma_cols; - unsigned short up_ip_chroma_rows; - unsigned short up_ip_chroma_cols; - unsigned short luma_ph_incr_V_low; - unsigned short luma_ph_incr_V_high; - unsigned short luma_ph_incr_H_low; - unsigned short luma_ph_incr_H_high; - unsigned short chroma_ph_incr_V_low; - unsigned short chroma_ph_incr_V_high; - unsigned short chroma_ph_incr_H_low; - unsigned short chroma_ph_incr_H_high; -} __attribute__((packed)) videnc_cmd_digital_zoom; - -/* - * Command to configure digital stabilization parameters - */ - -#define VIDENC_CMD_DIS_CFG_LEN \ - sizeof(videnc_cmd_dis_cfg) - -typedef struct { - unsigned short cmd_id; - unsigned short image_stab_subf_start_row_col; - unsigned short image_stab_subf_dim; - unsigned short image_stab_info_0; -} __attribute__((packed)) videnc_cmd_dis_cfg; - - -/* - * Command to set VIDENC_CMD_VENC_CLOCK - */ - - -#define VIDENC_CMD_VENC_CLOCK_LEN \ - sizeof(struct videnc_cmd_venc_clock) - -struct videnc_cmd_venc_clock { - unsigned short cmd_id; - unsigned short payload; -} __attribute__((packed)) ; - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfecmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfecmdi.h deleted file mode 100644 index 18ea21cc59a01a73e592b31c3b98863dff4d1607..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfecmdi.h +++ /dev/null @@ -1,910 +0,0 @@ -#ifndef QDSP5VFECMDI_H -#define QDSP5VFECMDI_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - - V F E I N T E R N A L C O M M A N D S - -GENERAL DESCRIPTION - This file contains defintions of format blocks of commands - that are accepted by VFE Task - -REFERENCES - None - -EXTERNALIZED FUNCTIONS - None - -Copyright (c) 1992-2009, The Linux Foundation. All rights reserved. - -This software is licensed under the terms of the GNU General Public -License version 2, as published by the Free Software Foundation, and -may be copied, distributed, and modified under those terms. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ -/*=========================================================================== - - EDIT HISTORY FOR FILE - -This section contains comments describing changes made to this file. -Notice that changes are listed in reverse chronological order. - -$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vfecmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ -Revision History: - -when who what, where, why --------- --- ---------------------------------------------------------- -06/12/08 sv initial version -===========================================================================*/ - -/****************************************************************************** - * Commands through vfeCommandScaleQueue - *****************************************************************************/ - -/* - * Command to program scaler for op1 . max op of scaler is VGA - */ - - -#define VFE_CMD_SCALE_OP1_CFG 0x0000 -#define VFE_CMD_SCALE_OP1_CFG_LEN \ - sizeof(vfe_cmd_scale_op1_cfg) - -#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_Y_STANDARD 0x0000 -#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_Y_CASCADED 0x0001 -#define VFE_CMD_SCALE_OP1_SEL_H_Y_SCALER_DIS 0x0000 -#define VFE_CMD_SCALE_OP1_SEL_H_Y_SCALER_ENA 0x0002 -#define VFE_CMD_SCALE_OP1_SEL_H_PP_Y_SCALER_DIS 0x0000 -#define VFE_CMD_SCALE_OP1_SEL_H_PP_Y_SCALER_ENA 0x0004 -#define VFE_CMD_SCALE_OP1_SEL_V_Y_SCALER_DIS 0x0000 -#define VFE_CMD_SCALE_OP1_SEL_V_Y_SCALER_ENA 0x0008 -#define VFE_CMD_SCALE_OP1_SEL_V_PP_Y_SCALER_DIS 0x0000 -#define VFE_CMD_SCALE_OP1_SEL_V_PP_Y_SCALER_ENA 0x0010 -#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_CBCR_STANDARD 0x0000 -#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_CBCR_CASCADED 0x0020 -#define VFE_CMD_SCALE_OP1_SEL_H_CBCR_SCALER_DIS 0x0000 -#define VFE_CMD_SCALE_OP1_SEL_H_CBCR_SCALER_ENA 0x0040 -#define VFE_CMD_SCALE_OP1_SEL_V_CBCR_SCALER_DIS 0x0000 -#define VFE_CMD_SCALE_OP1_SEL_V_CBCR_SCALER_ENA 0x0080 - -#define VFE_CMD_OP1_PP_Y_SCALER_CFG_PART1_DONT_LOAD_COEFFS 0x80000000 -#define VFE_CMD_OP1_PP_Y_SCALER_CFG_PART1_LOAD_COEFFS 0x80000000 - -typedef struct { - unsigned int cmd_id; - unsigned int scale_op1_sel; - unsigned int y_scaler_cfg_part1; - unsigned int y_scaler_cfg_part2; - unsigned int cbcr_scaler_cfg_part1; - unsigned int cbcr_scaler_cfg_part2; - unsigned int cbcr_scaler_cfg_part3; - unsigned int pp_y_scaler_cfg_part1; - unsigned int pp_y_scaler_cfg_part2; - unsigned int y_scaler_v_coeff_bank_part1[16]; - unsigned int y_scaler_v_coeff_bank_part2[16]; - unsigned int y_scaler_h_coeff_bank_part1[16]; - unsigned int y_scaler_h_coeff_bank_part2[16]; -} __attribute__((packed)) vfe_cmd_scale_op1_cfg; - - -/* - * Command to program scaler for op2 - */ - -#define VFE_CMD_SCALE_OP2_CFG 0x0001 -#define VFE_CMD_SCALE_OP2_CFG_LEN \ - sizeof(vfe_cmd_scale_op2_cfg) - -#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_Y_STANDARD 0x0000 -#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_Y_CASCADED 0x0001 -#define VFE_CMD_SCALE_OP2_SEL_H_Y_SCALER_DIS 0x0000 -#define VFE_CMD_SCALE_OP2_SEL_H_Y_SCALER_ENA 0x0002 -#define VFE_CMD_SCALE_OP2_SEL_H_PP_Y_SCALER_DIS 0x0000 -#define VFE_CMD_SCALE_OP2_SEL_H_PP_Y_SCALER_ENA 0x0004 -#define VFE_CMD_SCALE_OP2_SEL_V_Y_SCALER_DIS 0x0000 -#define VFE_CMD_SCALE_OP2_SEL_V_Y_SCALER_ENA 0x0008 -#define VFE_CMD_SCALE_OP2_SEL_V_PP_Y_SCALER_DIS 0x0000 -#define VFE_CMD_SCALE_OP2_SEL_V_PP_Y_SCALER_ENA 0x0010 -#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_CBCR_STANDARD 0x0000 -#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_CBCR_CASCADED 0x0020 -#define VFE_CMD_SCALE_OP2_SEL_H_CBCR_SCALER_DIS 0x0000 -#define VFE_CMD_SCALE_OP2_SEL_H_CBCR_SCALER_ENA 0x0040 -#define VFE_CMD_SCALE_OP2_SEL_V_CBCR_SCALER_DIS 0x0000 -#define VFE_CMD_SCALE_OP2_SEL_V_CBCR_SCALER_ENA 0x0080 - -#define VFE_CMD_OP2_PP_Y_SCALER_CFG_PART1_DONT_LOAD_COEFFS 0x80000000 -#define VFE_CMD_OP2_PP_Y_SCALER_CFG_PART1_LOAD_COEFFS 0x80000000 - -typedef struct { - unsigned int cmd_id; - unsigned int scale_op2_sel; - unsigned int y_scaler_cfg_part1; - unsigned int y_scaler_cfg_part2; - unsigned int cbcr_scaler_cfg_part1; - unsigned int cbcr_scaler_cfg_part2; - unsigned int cbcr_scaler_cfg_part3; - unsigned int pp_y_scaler_cfg_part1; - unsigned int pp_y_scaler_cfg_part2; - unsigned int y_scaler_v_coeff_bank_part1[16]; - unsigned int y_scaler_v_coeff_bank_part2[16]; - unsigned int y_scaler_h_coeff_bank_part1[16]; - unsigned int y_scaler_h_coeff_bank_part2[16]; -} __attribute__((packed)) vfe_cmd_scale_op2_cfg; - - -/****************************************************************************** - * Commands through vfeCommandTableQueue - *****************************************************************************/ - -/* - * Command to program the AXI ip paths - */ - -#define VFE_CMD_AXI_IP_CFG 0x0000 -#define VFE_CMD_AXI_IP_CFG_LEN sizeof(vfe_cmd_axi_ip_cfg) - -#define VFE_CMD_IP_SEL_IP_FORMAT_8 0x0000 -#define VFE_CMD_IP_SEL_IP_FORMAT_10 0x0001 -#define VFE_CMD_IP_SEL_IP_FORMAT_12 0x0002 - -typedef struct { - unsigned int cmd_id; - unsigned int ip_sel; - unsigned int ip_cfg_part1; - unsigned int ip_cfg_part2; - unsigned int ip_unpack_cfg_part[6]; - unsigned int ip_buf_addr[8]; -} __attribute__ ((packed)) vfe_cmd_axi_ip_cfg; - - -/* - * Command to program axi op paths - */ - -#define VFE_CMD_AXI_OP_CFG 0x0001 -#define VFE_CMD_AXI_OP_CFG_LEN sizeof(vfe_cmd_axi_op_cfg) - -#define VFE_CMD_OP_SEL_OP1 0x0000 -#define VFE_CMD_OP_SEL_OP2 0x0001 -#define VFE_CMD_OP_SEL_OP1_OP2 0x0002 -#define VFE_CMD_OP_SEL_CTOA 0x0003 -#define VFE_CMD_OP_SEL_CTOA_OP1 0x0004 -#define VFE_CMD_OP_SEL_CTOA_OP2 0x0005 -#define VFE_CMD_OP_SEL_OP_FORMAT_8 0x0000 -#define VFE_CMD_OP_SEL_OP_FORMAT_10 0x0008 -#define VFE_CMD_OP_SEL_OP_FORMAT_12 0x0010 - - -typedef struct { - unsigned int cmd_id; - unsigned int op_sel; - unsigned int op1_y_cfg_part1; - unsigned int op1_y_cfg_part2; - unsigned int op1_cbcr_cfg_part1; - unsigned int op1_cbcr_cfg_part2; - unsigned int op2_y_cfg_part1; - unsigned int op2_y_cfg_part2; - unsigned int op2_cbcr_cfg_part1; - unsigned int op2_cbcr_cfg_part2; - unsigned int op1_buf1_addr[16]; - unsigned int op2_buf1_addr[16]; -} __attribute__((packed)) vfe_cmd_axi_op_cfg; - - - - -/* - * Command to program the roll off correction module - */ - -#define VFE_CMD_ROLLOFF_CFG 0x0002 -#define VFE_CMD_ROLLOFF_CFG_LEN \ - sizeof(vfe_cmd_rolloff_cfg) - - -typedef struct { - unsigned int cmd_id; - unsigned int correction_opt_center_pos; - unsigned int radius_square_entry[32]; - unsigned int red_table_entry[32]; - unsigned int green_table_entry[32]; - unsigned int blue_table_entry[32]; -} __attribute__((packed)) vfe_cmd_rolloff_cfg; - -/* - * Command to program RGB gamma table - */ - -#define VFE_CMD_RGB_GAMMA_CFG 0x0003 -#define VFE_CMD_RGB_GAMMA_CFG_LEN \ - sizeof(vfe_cmd_rgb_gamma_cfg) - -#define VFE_CMD_RGB_GAMMA_SEL_LINEAR 0x0000 -#define VFE_CMD_RGB_GAMMA_SEL_PW_LINEAR 0x0001 -typedef struct { - unsigned int cmd_id; - unsigned int rgb_gamma_sel; - unsigned int rgb_gamma_entry[256]; -} __attribute__((packed)) vfe_cmd_rgb_gamma_cfg; - - -/* - * Command to program luma gamma table for the noise reduction path - */ - -#define VFE_CMD_Y_GAMMA_CFG 0x0004 -#define VFE_CMD_Y_GAMMA_CFG_LEN \ - sizeof(vfe_cmd_y_gamma_cfg) - -#define VFE_CMD_Y_GAMMA_SEL_LINEAR 0x0000 -#define VFE_CMD_Y_GAMMA_SEL_PW_LINEAR 0x0001 - -typedef struct { - unsigned int cmd_id; - unsigned int y_gamma_sel; - unsigned int y_gamma_entry[256]; -} __attribute__((packed)) vfe_cmd_y_gamma_cfg; - - - -/****************************************************************************** - * Commands through vfeCommandQueue - *****************************************************************************/ - -/* - * Command to reset the VFE to a known good state.All previously programmed - * Params will be lost - */ - - -#define VFE_CMD_RESET 0x0000 -#define VFE_CMD_RESET_LEN sizeof(vfe_cmd_reset) - - -typedef struct { - unsigned short cmd_id; -} __attribute__((packed)) vfe_cmd_reset; - - -/* - * Command to start VFE processing based on the config params - */ - - -#define VFE_CMD_START 0x0001 -#define VFE_CMD_START_LEN sizeof(vfe_cmd_start) - -#define VFE_CMD_STARTUP_PARAMS_SRC_CAMIF 0x0000 -#define VFE_CMD_STARTUP_PARAMS_SRC_AXI 0x0001 -#define VFE_CMD_STARTUP_PARAMS_MODE_CONTINUOUS 0x0000 -#define VFE_CMD_STARTUP_PARAMS_MODE_SNAPSHOT 0x0002 - -#define VFE_CMD_IMAGE_PL_BLACK_LVL_CORR_DIS 0x0000 -#define VFE_CMD_IMAGE_PL_BLACK_LVL_CORR_ENA 0x0001 -#define VFE_CMD_IMAGE_PL_ROLLOFF_CORR_DIS 0x0000 -#define VFE_CMD_IMAGE_PL_ROLLOFF_CORR_ENA 0x0002 -#define VFE_CMD_IMAGE_PL_WHITE_BAL_DIS 0x0000 -#define VFE_CMD_IMAGE_PL_WHITE_BAL_ENA 0x0004 -#define VFE_CMD_IMAGE_PL_RGB_GAMMA_DIS 0x0000 -#define VFE_CMD_IMAGE_PL_RGB_GAMMA_ENA 0x0008 -#define VFE_CMD_IMAGE_PL_LUMA_NOISE_RED_PATH_DIS 0x0000 -#define VFE_CMD_IMAGE_PL_LUMA_NOISE_RED_PATH_ENA 0x0010 -#define VFE_CMD_IMAGE_PL_ADP_FILTER_DIS 0x0000 -#define VFE_CMD_IMAGE_PL_ADP_FILTER_ENA 0x0020 -#define VFE_CMD_IMAGE_PL_CHROMA_SAMP_DIS 0x0000 -#define VFE_CMD_IMAGE_PL_CHROMA_SAMP_ENA 0x0040 - - -typedef struct { - unsigned int cmd_id; - unsigned int startup_params; - unsigned int image_pipeline; - unsigned int frame_dimension; -} __attribute__((packed)) vfe_cmd_start; - - -/* - * Command to halt all processing - */ - -#define VFE_CMD_STOP 0x0002 -#define VFE_CMD_STOP_LEN sizeof(vfe_cmd_stop) - -typedef struct { - unsigned short cmd_id; -} __attribute__((packed)) vfe_cmd_stop; - - -/* - * Command to commit the params that have been programmed to take - * effect on the next frame - */ - -#define VFE_CMD_UPDATE 0x0003 -#define VFE_CMD_UPDATE_LEN sizeof(vfe_cmd_update) - - -typedef struct { - unsigned short cmd_id; -} __attribute__((packed)) vfe_cmd_update; - - -/* - * Command to program CAMIF module - */ - -#define VFE_CMD_CAMIF_CFG 0x0004 -#define VFE_CMD_CAMIF_CFG_LEN sizeof(vfe_cmd_camif_cfg) - -#define VFE_CMD_CFG_VSYNC_SYNC_EDGE_HIGH 0x0000 -#define VFE_CMD_CFG_VSYNC_SYNC_EDGE_LOW 0x0002 -#define VFE_CMD_CFG_HSYNC_SYNC_EDGE_HIGH 0x0000 -#define VFE_CMD_CFG_HSYNC_SYNC_EDGE_LOW 0x0004 -#define VFE_CMD_CFG_SYNC_MODE_APS 0x0000 -#define VFE_CMD_CFG_SYNC_MODE_EFS 0X0008 -#define VFE_CMD_CFG_SYNC_MODE_ELS 0x0010 -#define VFE_CMD_CFG_SYNC_MODE_RVD 0x0018 -#define VFE_CMD_CFG_VFE_SUBSAMP_EN_DIS 0x0000 -#define VFE_CMD_CFG_VFE_SUBSAMP_EN_ENA 0x0020 -#define VFE_CMD_CFG_BUS_SUBSAMP_EN_DIS 0x0000 -#define VFE_CMD_CFG_BUS_SUBSAMP_EN_ENA 0x0080 -#define VFE_CMD_CFG_IRQ_SUBSAMP_EN_DIS 0x0000 -#define VFE_CMD_CFG_IRQ_SUBSAMP_EN_ENA 0x0800 - -#define VFE_CMD_SUBSAMP2_CFG_PIXEL_SKIP_16 0x0000 -#define VFE_CMD_SUBSAMP2_CFG_PIXEL_SKIP_12 0x0010 - -#define VFE_CMD_EPOCH_IRQ_1_DIS 0x0000 -#define VFE_CMD_EPOCH_IRQ_1_ENA 0x4000 -#define VFE_CMD_EPOCH_IRQ_2_DIS 0x0000 -#define VFE_CMD_EPOCH_IRQ_2_ENA 0x8000 - -typedef struct { - unsigned int cmd_id; - unsigned int cfg; - unsigned int efs_cfg; - unsigned int frame_cfg; - unsigned int window_width_cfg; - unsigned int window_height_cfg; - unsigned int subsamp1_cfg; - unsigned int subsamp2_cfg; - unsigned int epoch_irq; -} __attribute__((packed)) vfe_cmd_camif_cfg; - - - -/* - * Command to program the black level module - */ - -#define VFE_CMD_BLACK_LVL_CFG 0x0005 -#define VFE_CMD_BLACK_LVL_CFG_LEN sizeof(vfe_cmd_black_lvl_cfg) - -#define VFE_CMD_BL_SEL_MANUAL 0x0000 -#define VFE_CMD_BL_SEL_AUTO 0x0001 - -typedef struct { - unsigned int cmd_id; - unsigned int black_lvl_sel; - unsigned int cfg_part[3]; -} __attribute__((packed)) vfe_cmd_black_lvl_cfg; - - -/* - * Command to program the active region by cropping the region of interest - */ - -#define VFE_CMD_ACTIVE_REGION_CFG 0x0006 -#define VFE_CMD_ACTIVE_REGION_CFG_LEN \ - sizeof(vfe_cmd_active_region_cfg) - - -typedef struct { - unsigned int cmd_id; - unsigned int cfg_part1; - unsigned int cfg_part2; -} __attribute__((packed)) vfe_cmd_active_region_cfg; - - - -/* - * Command to program the defective pixel correction(DPC) , - * adaptive bayer filter (ABF) and demosaic modules - */ - -#define VFE_CMD_DEMOSAIC_CFG 0x0007 -#define VFE_CMD_DEMOSAIC_CFG_LEN sizeof(vfe_cmd_demosaic_cfg) - -#define VFE_CMD_DEMOSAIC_PART1_ABF_EN_DIS 0x0000 -#define VFE_CMD_DEMOSAIC_PART1_ABF_EN_ENA 0x0001 -#define VFE_CMD_DEMOSAIC_PART1_DPC_EN_DIS 0x0000 -#define VFE_CMD_DEMOSAIC_PART1_DPC_EN_ENA 0x0002 -#define VFE_CMD_DEMOSAIC_PART1_FORCE_ABF_OFF 0x0000 -#define VFE_CMD_DEMOSAIC_PART1_FORCE_ABF_ON 0x0004 -#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1 0x00000000 -#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_2 0x10000000 -#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_4 0x20000000 -#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_8 0x30000000 -#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_2 0x50000000 -#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_4 0x60000000 -#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_8 0x70000000 - -typedef struct { - unsigned int cmd_id; - unsigned int demosaic_part1; - unsigned int demosaic_part2; - unsigned int demosaic_part3; - unsigned int demosaic_part4; - unsigned int demosaic_part5; -} __attribute__((packed)) vfe_cmd_demosaic_cfg; - - -/* - * Command to program the ip format - */ - -#define VFE_CMD_IP_FORMAT_CFG 0x0008 -#define VFE_CMD_IP_FORMAT_CFG_LEN \ - sizeof(vfe_cmd_ip_format_cfg) - -#define VFE_CMD_IP_FORMAT_SEL_RGRG 0x0000 -#define VFE_CMD_IP_FORMAT_SEL_GRGR 0x0001 -#define VFE_CMD_IP_FORMAT_SEL_BGBG 0x0002 -#define VFE_CMD_IP_FORMAT_SEL_GBGB 0x0003 -#define VFE_CMD_IP_FORMAT_SEL_YCBYCR 0x0004 -#define VFE_CMD_IP_FORMAT_SEL_YCRYCB 0x0005 -#define VFE_CMD_IP_FORMAT_SEL_CBYCRY 0x0006 -#define VFE_CMD_IP_FORMAT_SEL_CRYCBY 0x0007 -#define VFE_CMD_IP_FORMAT_SEL_NO_CHROMA 0x0000 -#define VFE_CMD_IP_FORMAT_SEL_CHROMA 0x0008 - - -typedef struct { - unsigned int cmd_id; - unsigned int ip_format_sel; - unsigned int balance_gains_part1; - unsigned int balance_gains_part2; -} __attribute__((packed)) vfe_cmd_ip_format_cfg; - - - -/* - * Command to program max and min allowed op values - */ - -#define VFE_CMD_OP_CLAMP_CFG 0x0009 -#define VFE_CMD_OP_CLAMP_CFG_LEN \ - sizeof(vfe_cmd_op_clamp_cfg) - -typedef struct { - unsigned int cmd_id; - unsigned int op_clamp_max; - unsigned int op_clamp_min; -} __attribute__((packed)) vfe_cmd_op_clamp_cfg; - - -/* - * Command to program chroma sub sample module - */ - -#define VFE_CMD_CHROMA_SUBSAMPLE_CFG 0x000A -#define VFE_CMD_CHROMA_SUBSAMPLE_CFG_LEN \ - sizeof(vfe_cmd_chroma_subsample_cfg) - -#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_INTERESTIAL_SAMPS 0x0000 -#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_COSITED_SAMPS 0x0001 -#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_INTERESTIAL_SAMPS 0x0000 -#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_COSITED_SAMPS 0x0002 -#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_SUBSAMP_DIS 0x0000 -#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_SUBSAMP_ENA 0x0004 -#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_SUBSAMP_DIS 0x0000 -#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_SUBSAMP_ENA 0x0008 - -typedef struct { - unsigned int cmd_id; - unsigned int chroma_subsamp_sel; -} __attribute__((packed)) vfe_cmd_chroma_subsample_cfg; - - -/* - * Command to program the white balance module - */ - -#define VFE_CMD_WHITE_BALANCE_CFG 0x000B -#define VFE_CMD_WHITE_BALANCE_CFG_LEN \ - sizeof(vfe_cmd_white_balance_cfg) - -typedef struct { - unsigned int cmd_id; - unsigned int white_balance_gains; -} __attribute__((packed)) vfe_cmd_white_balance_cfg; - - -/* - * Command to program the color processing module - */ - -#define VFE_CMD_COLOR_PROCESS_CFG 0x000C -#define VFE_CMD_COLOR_PROCESS_CFG_LEN \ - sizeof(vfe_cmd_color_process_cfg) - -#define VFE_CMD_COLOR_CORRE_PART7_Q7_FACTORS 0x0000 -#define VFE_CMD_COLOR_CORRE_PART7_Q8_FACTORS 0x0001 -#define VFE_CMD_COLOR_CORRE_PART7_Q9_FACTORS 0x0002 -#define VFE_CMD_COLOR_CORRE_PART7_Q10_FACTORS 0x0003 - -typedef struct { - unsigned int cmd_id; - unsigned int color_correction_part1; - unsigned int color_correction_part2; - unsigned int color_correction_part3; - unsigned int color_correction_part4; - unsigned int color_correction_part5; - unsigned int color_correction_part6; - unsigned int color_correction_part7; - unsigned int chroma_enhance_part1; - unsigned int chroma_enhance_part2; - unsigned int chroma_enhance_part3; - unsigned int chroma_enhance_part4; - unsigned int chroma_enhance_part5; - unsigned int luma_calc_part1; - unsigned int luma_calc_part2; -} __attribute__((packed)) vfe_cmd_color_process_cfg; - - -/* - * Command to program adaptive filter module - */ - -#define VFE_CMD_ADP_FILTER_CFG 0x000D -#define VFE_CMD_ADP_FILTER_CFG_LEN \ - sizeof(vfe_cmd_adp_filter_cfg) - -#define VFE_CMD_ASF_CFG_PART_SMOOTH_FILTER_DIS 0x0000 -#define VFE_CMD_ASF_CFG_PART_SMOOTH_FILTER_ENA 0x0001 -#define VFE_CMD_ASF_CFG_PART_NO_SHARP_MODE 0x0000 -#define VFE_CMD_ASF_CFG_PART_SINGLE_FILTER 0x0002 -#define VFE_CMD_ASF_CFG_PART_DUAL_FILTER 0x0004 -#define VFE_CMD_ASF_CFG_PART_SHARP_MODE 0x0007 - -typedef struct { - unsigned int cmd_id; - unsigned int asf_cfg_part[7]; -} __attribute__((packed)) vfe_cmd_adp_filter_cfg; - - -/* - * Command to program for frame skip pattern for op1 and op2 - */ - -#define VFE_CMD_FRAME_SKIP_CFG 0x000E -#define VFE_CMD_FRAME_SKIP_CFG_LEN \ - sizeof(vfe_cmd_frame_skip_cfg) - -typedef struct { - unsigned int cmd_id; - unsigned int frame_skip_pattern_op1; - unsigned int frame_skip_pattern_op2; -} __attribute__((packed)) vfe_cmd_frame_skip_cfg; - - -/* - * Command to program field-of-view crop for digital zoom - */ - -#define VFE_CMD_FOV_CROP 0x000F -#define VFE_CMD_FOV_CROP_LEN sizeof(vfe_cmd_fov_crop) - -typedef struct { - unsigned int cmd_id; - unsigned int fov_crop_part1; - unsigned int fov_crop_part2; -} __attribute__((packed)) vfe_cmd_fov_crop; - - - -/* - * Command to program auto focus(AF) statistics module - */ - -#define VFE_CMD_STATS_AUTOFOCUS_CFG 0x0010 -#define VFE_CMD_STATS_AUTOFOCUS_CFG_LEN \ - sizeof(vfe_cmd_stats_autofocus_cfg) - -#define VFE_CMD_AF_STATS_SEL_STATS_DIS 0x0000 -#define VFE_CMD_AF_STATS_SEL_STATS_ENA 0x0001 -#define VFE_CMD_AF_STATS_SEL_PRI_FIXED 0x0000 -#define VFE_CMD_AF_STATS_SEL_PRI_VAR 0x0002 -#define VFE_CMD_AF_STATS_CFG_PART_METRIC_SUM 0x00000000 -#define VFE_CMD_AF_STATS_CFG_PART_METRIC_MAX 0x00200000 - -typedef struct { - unsigned int cmd_id; - unsigned int af_stats_sel; - unsigned int af_stats_cfg_part[8]; - unsigned int af_stats_op_buf_hdr; - unsigned int af_stats_op_buf[3]; -} __attribute__((packed)) vfe_cmd_stats_autofocus_cfg; - - -/* - * Command to program White balance(wb) and exposure (exp) - * statistics module - */ - -#define VFE_CMD_STATS_WB_EXP_CFG 0x0011 -#define VFE_CMD_STATS_WB_EXP_CFG_LEN \ - sizeof(vfe_cmd_stats_wb_exp_cfg) - -#define VFE_CMD_WB_EXP_STATS_SEL_STATS_DIS 0x0000 -#define VFE_CMD_WB_EXP_STATS_SEL_STATS_ENA 0x0001 -#define VFE_CMD_WB_EXP_STATS_SEL_PRI_FIXED 0x0000 -#define VFE_CMD_WB_EXP_STATS_SEL_PRI_VAR 0x0002 - -#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_REG_8_8 0x0000 -#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_REG_16_16 0x0001 -#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_SREG_8_8 0x0000 -#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_SREG_4_4 0x0002 - -typedef struct { - unsigned int cmd_id; - unsigned int wb_exp_stats_sel; - unsigned int wb_exp_stats_cfg_part1; - unsigned int wb_exp_stats_cfg_part2; - unsigned int wb_exp_stats_cfg_part3; - unsigned int wb_exp_stats_cfg_part4; - unsigned int wb_exp_stats_op_buf_hdr; - unsigned int wb_exp_stats_op_buf[3]; -} __attribute__((packed)) vfe_cmd_stats_wb_exp_cfg; - - -/* - * Command to program histogram(hg) stats module - */ - -#define VFE_CMD_STATS_HG_CFG 0x0012 -#define VFE_CMD_STATS_HG_CFG_LEN \ - sizeof(vfe_cmd_stats_hg_cfg) - -#define VFE_CMD_HG_STATS_SEL_PRI_FIXED 0x0000 -#define VFE_CMD_HG_STATS_SEL_PRI_VAR 0x0002 - -typedef struct { - unsigned int cmd_id; - unsigned int hg_stats_sel; - unsigned int hg_stats_cfg_part1; - unsigned int hg_stats_cfg_part2; - unsigned int hg_stats_op_buf_hdr; - unsigned int hg_stats_op_buf; -} __attribute__((packed)) vfe_cmd_stats_hg_cfg; - - -/* - * Command to acknowledge last MSG_VFE_OP1 message - */ - -#define VFE_CMD_OP1_ACK 0x0013 -#define VFE_CMD_OP1_ACK_LEN sizeof(vfe_cmd_op1_ack) - -typedef struct { - unsigned int cmd_id; - unsigned int op1_buf_y_addr; - unsigned int op1_buf_cbcr_addr; -} __attribute__((packed)) vfe_cmd_op1_ack; - - - -/* - * Command to acknowledge last MSG_VFE_OP2 message - */ - -#define VFE_CMD_OP2_ACK 0x0014 -#define VFE_CMD_OP2_ACK_LEN sizeof(vfe_cmd_op2_ack) - -typedef struct { - unsigned int cmd_id; - unsigned int op2_buf_y_addr; - unsigned int op2_buf_cbcr_addr; -} __attribute__((packed)) vfe_cmd_op2_ack; - - - -/* - * Command to acknowledge MSG_VFE_STATS_AUTOFOCUS msg - */ - -#define VFE_CMD_STATS_AF_ACK 0x0015 -#define VFE_CMD_STATS_AF_ACK_LEN sizeof(vfe_cmd_stats_af_ack) - - -typedef struct { - unsigned int cmd_id; - unsigned int af_stats_op_buf; -} __attribute__((packed)) vfe_cmd_stats_af_ack; - - -/* - * Command to acknowledge MSG_VFE_STATS_WB_EXP msg - */ - -#define VFE_CMD_STATS_WB_EXP_ACK 0x0016 -#define VFE_CMD_STATS_WB_EXP_ACK_LEN sizeof(vfe_cmd_stats_wb_exp_ack) - -typedef struct { - unsigned int cmd_id; - unsigned int wb_exp_stats_op_buf; -} __attribute__((packed)) vfe_cmd_stats_wb_exp_ack; - - -/* - * Command to acknowledge MSG_VFE_EPOCH1 message - */ - -#define VFE_CMD_EPOCH1_ACK 0x0017 -#define VFE_CMD_EPOCH1_ACK_LEN sizeof(vfe_cmd_epoch1_ack) - -typedef struct { - unsigned short cmd_id; -} __attribute__((packed)) vfe_cmd_epoch1_ack; - - -/* - * Command to acknowledge MSG_VFE_EPOCH2 message - */ - -#define VFE_CMD_EPOCH2_ACK 0x0018 -#define VFE_CMD_EPOCH2_ACK_LEN sizeof(vfe_cmd_epoch2_ack) - -typedef struct { - unsigned short cmd_id; -} __attribute__((packed)) vfe_cmd_epoch2_ack; - - - -/* - * Command to configure, enable or disable synchronous timer1 - */ - -#define VFE_CMD_SYNC_TIMER1_CFG 0x0019 -#define VFE_CMD_SYNC_TIMER1_CFG_LEN \ - sizeof(vfe_cmd_sync_timer1_cfg) - -#define VFE_CMD_SYNC_T1_CFG_PART1_TIMER_DIS 0x0000 -#define VFE_CMD_SYNC_T1_CFG_PART1_TIMER_ENA 0x0001 -#define VFE_CMD_SYNC_T1_CFG_PART1_POL_HIGH 0x0000 -#define VFE_CMD_SYNC_T1_CFG_PART1_POL_LOW 0x0002 - -typedef struct { - unsigned int cmd_id; - unsigned int sync_t1_cfg_part1; - unsigned int sync_t1_h_sync_countdown; - unsigned int sync_t1_pclk_countdown; - unsigned int sync_t1_duration; -} __attribute__((packed)) vfe_cmd_sync_timer1_cfg; - - -/* - * Command to configure, enable or disable synchronous timer1 - */ - -#define VFE_CMD_SYNC_TIMER2_CFG 0x001A -#define VFE_CMD_SYNC_TIMER2_CFG_LEN \ - sizeof(vfe_cmd_sync_timer2_cfg) - -#define VFE_CMD_SYNC_T2_CFG_PART1_TIMER_DIS 0x0000 -#define VFE_CMD_SYNC_T2_CFG_PART1_TIMER_ENA 0x0001 -#define VFE_CMD_SYNC_T2_CFG_PART1_POL_HIGH 0x0000 -#define VFE_CMD_SYNC_T2_CFG_PART1_POL_LOW 0x0002 - -typedef struct { - unsigned int cmd_id; - unsigned int sync_t2_cfg_part1; - unsigned int sync_t2_h_sync_countdown; - unsigned int sync_t2_pclk_countdown; - unsigned int sync_t2_duration; -} __attribute__((packed)) vfe_cmd_sync_timer2_cfg; - - -/* - * Command to configure and start asynchronous timer1 - */ - -#define VFE_CMD_ASYNC_TIMER1_START 0x001B -#define VFE_CMD_ASYNC_TIMER1_START_LEN \ - sizeof(vfe_cmd_async_timer1_start) - -#define VFE_CMD_ASYNC_T1_POLARITY_A_HIGH 0x0000 -#define VFE_CMD_ASYNC_T1_POLARITY_A_LOW 0x0001 -#define VFE_CMD_ASYNC_T1_POLARITY_B_HIGH 0x0000 -#define VFE_CMD_ASYNC_T1_POLARITY_B_LOW 0x0002 - -typedef struct { - unsigned int cmd_id; - unsigned int async_t1a_cfg; - unsigned int async_t1b_cfg; - unsigned int async_t1_polarity; -} __attribute__((packed)) vfe_cmd_async_timer1_start; - - -/* - * Command to configure and start asynchronous timer2 - */ - -#define VFE_CMD_ASYNC_TIMER2_START 0x001C -#define VFE_CMD_ASYNC_TIMER2_START_LEN \ - sizeof(vfe_cmd_async_timer2_start) - -#define VFE_CMD_ASYNC_T2_POLARITY_A_HIGH 0x0000 -#define VFE_CMD_ASYNC_T2_POLARITY_A_LOW 0x0001 -#define VFE_CMD_ASYNC_T2_POLARITY_B_HIGH 0x0000 -#define VFE_CMD_ASYNC_T2_POLARITY_B_LOW 0x0002 - -typedef struct { - unsigned int cmd_id; - unsigned int async_t2a_cfg; - unsigned int async_t2b_cfg; - unsigned int async_t2_polarity; -} __attribute__((packed)) vfe_cmd_async_timer2_start; - - -/* - * Command to program partial configurations of auto focus(af) - */ - -#define VFE_CMD_STATS_AF_UPDATE 0x001D -#define VFE_CMD_STATS_AF_UPDATE_LEN \ - sizeof(vfe_cmd_stats_af_update) - -#define VFE_CMD_AF_UPDATE_PART1_WINDOW_ONE 0x00000000 -#define VFE_CMD_AF_UPDATE_PART1_WINDOW_MULTI 0x80000000 - -typedef struct { - unsigned int cmd_id; - unsigned int af_update_part1; - unsigned int af_update_part2; -} __attribute__((packed)) vfe_cmd_stats_af_update; - - -/* - * Command to program partial cfg of wb and exp - */ - -#define VFE_CMD_STATS_WB_EXP_UPDATE 0x001E -#define VFE_CMD_STATS_WB_EXP_UPDATE_LEN \ - sizeof(vfe_cmd_stats_wb_exp_update) - -#define VFE_CMD_WB_EXP_UPDATE_PART1_REGIONS_8_8 0x0000 -#define VFE_CMD_WB_EXP_UPDATE_PART1_REGIONS_16_16 0x0001 -#define VFE_CMD_WB_EXP_UPDATE_PART1_SREGIONS_8_8 0x0000 -#define VFE_CMD_WB_EXP_UPDATE_PART1_SREGIONS_4_4 0x0002 - -typedef struct { - unsigned int cmd_id; - unsigned int wb_exp_update_part1; - unsigned int wb_exp_update_part2; - unsigned int wb_exp_update_part3; - unsigned int wb_exp_update_part4; -} __attribute__((packed)) vfe_cmd_stats_wb_exp_update; - - - -/* - * Command to re program the CAMIF FRAME CONFIG settings - */ - -#define VFE_CMD_UPDATE_CAMIF_FRAME_CFG 0x001F -#define VFE_CMD_UPDATE_CAMIF_FRAME_CFG_LEN \ - sizeof(vfe_cmd_update_camif_frame_cfg) - -typedef struct { - unsigned int cmd_id; - unsigned int camif_frame_cfg; -} __attribute__((packed)) vfe_cmd_update_camif_frame_cfg; - - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfemsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfemsg.h deleted file mode 100644 index 7d7f73169306d0602afe2ba096486d91274b8340..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfemsg.h +++ /dev/null @@ -1,290 +0,0 @@ -#ifndef QDSP5VFEMSGI_H -#define QDSP5VFEMSGI_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - - V F E I N T E R N A L M E S S A G E S - -GENERAL DESCRIPTION - This file contains defintions of format blocks of commands - that are sent by VFE Task - -REFERENCES - None - -EXTERNALIZED FUNCTIONS - None - -Copyright (c) 1992-2009, The Linux Foundation. All rights reserved. - -This software is licensed under the terms of the GNU General Public -License version 2, as published by the Free Software Foundation, and -may be copied, distributed, and modified under those terms. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ -/*=========================================================================== - - EDIT HISTORY FOR FILE - -This section contains comments describing changes made to this file. -Notice that changes are listed in reverse chronological order. - -$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vfemsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $ -Revision History: - -when who what, where, why --------- --- ---------------------------------------------------------- -06/12/08 sv initial version -===========================================================================*/ - - -/* - * Message to acknowledge CMD_VFE_REST command - */ - -#define VFE_MSG_RESET_ACK 0x0000 -#define VFE_MSG_RESET_ACK_LEN sizeof(vfe_msg_reset_ack) - -typedef struct { -} __attribute__((packed)) vfe_msg_reset_ack; - - -/* - * Message to acknowledge CMD_VFE_START command - */ - -#define VFE_MSG_START_ACK 0x0001 -#define VFE_MSG_START_ACK_LEN sizeof(vfe_msg_start_ack) - -typedef struct { -} __attribute__((packed)) vfe_msg_start_ack; - -/* - * Message to acknowledge CMD_VFE_STOP command - */ - -#define VFE_MSG_STOP_ACK 0x0002 -#define VFE_MSG_STOP_ACK_LEN sizeof(vfe_msg_stop_ack) - -typedef struct { -} __attribute__((packed)) vfe_msg_stop_ack; - - -/* - * Message to acknowledge CMD_VFE_UPDATE command - */ - -#define VFE_MSG_UPDATE_ACK 0x0003 -#define VFE_MSG_UPDATE_ACK_LEN sizeof(vfe_msg_update_ack) - -typedef struct { -} __attribute__((packed)) vfe_msg_update_ack; - - -/* - * Message to notify the ARM that snapshot processing is complete - * and that the VFE is now STATE_VFE_IDLE - */ - -#define VFE_MSG_SNAPSHOT_DONE 0x0004 -#define VFE_MSG_SNAPSHOT_DONE_LEN \ - sizeof(vfe_msg_snapshot_done) - -typedef struct { -} __attribute__((packed)) vfe_msg_snapshot_done; - - - -/* - * Message to notify ARM that illegal cmd was received and - * system is in the IDLE state - */ - -#define VFE_MSG_ILLEGAL_CMD 0x0005 -#define VFE_MSG_ILLEGAL_CMD_LEN \ - sizeof(vfe_msg_illegal_cmd) - -typedef struct { - unsigned int status; -} __attribute__((packed)) vfe_msg_illegal_cmd; - - -/* - * Message to notify ARM that op1 buf is full and ready - */ - -#define VFE_MSG_OP1 0x0006 -#define VFE_MSG_OP1_LEN sizeof(vfe_msg_op1) - -typedef struct { - unsigned int op1_buf_y_addr; - unsigned int op1_buf_cbcr_addr; - unsigned int black_level_even_col; - unsigned int black_level_odd_col; - unsigned int defect_pixels_detected; - unsigned int asf_max_edge; -} __attribute__((packed)) vfe_msg_op1; - - -/* - * Message to notify ARM that op2 buf is full and ready - */ - -#define VFE_MSG_OP2 0x0007 -#define VFE_MSG_OP2_LEN sizeof(vfe_msg_op2) - -typedef struct { - unsigned int op2_buf_y_addr; - unsigned int op2_buf_cbcr_addr; - unsigned int black_level_even_col; - unsigned int black_level_odd_col; - unsigned int defect_pixels_detected; - unsigned int asf_max_edge; -} __attribute__((packed)) vfe_msg_op2; - - -/* - * Message to notify ARM that autofocus(af) stats are ready - */ - -#define VFE_MSG_STATS_AF 0x0008 -#define VFE_MSG_STATS_AF_LEN sizeof(vfe_msg_stats_af) - -typedef struct { - unsigned int af_stats_op_buffer; -} __attribute__((packed)) vfe_msg_stats_af; - - -/* - * Message to notify ARM that white balance(wb) and exposure (exp) - * stats are ready - */ - -#define VFE_MSG_STATS_WB_EXP 0x0009 -#define VFE_MSG_STATS_WB_EXP_LEN \ - sizeof(vfe_msg_stats_wb_exp) - -typedef struct { - unsigned int wb_exp_stats_op_buf; -} __attribute__((packed)) vfe_msg_stats_wb_exp; - - -/* - * Message to notify the ARM that histogram(hg) stats are ready - */ - -#define VFE_MSG_STATS_HG 0x000A -#define VFE_MSG_STATS_HG_LEN sizeof(vfe_msg_stats_hg) - -typedef struct { - unsigned int hg_stats_op_buf; -} __attribute__((packed)) vfe_msg_stats_hg; - - -/* - * Message to notify the ARM that epoch1 event occurred in the CAMIF - */ - -#define VFE_MSG_EPOCH1 0x000B -#define VFE_MSG_EPOCH1_LEN sizeof(vfe_msg_epoch1) - -typedef struct { -} __attribute__((packed)) vfe_msg_epoch1; - - -/* - * Message to notify the ARM that epoch2 event occurred in the CAMIF - */ - -#define VFE_MSG_EPOCH2 0x000C -#define VFE_MSG_EPOCH2_LEN sizeof(vfe_msg_epoch2) - -typedef struct { -} __attribute__((packed)) vfe_msg_epoch2; - - -/* - * Message to notify the ARM that sync timer1 op is completed - */ - -#define VFE_MSG_SYNC_T1_DONE 0x000D -#define VFE_MSG_SYNC_T1_DONE_LEN sizeof(vfe_msg_sync_t1_done) - -typedef struct { -} __attribute__((packed)) vfe_msg_sync_t1_done; - - -/* - * Message to notify the ARM that sync timer2 op is completed - */ - -#define VFE_MSG_SYNC_T2_DONE 0x000E -#define VFE_MSG_SYNC_T2_DONE_LEN sizeof(vfe_msg_sync_t2_done) - -typedef struct { -} __attribute__((packed)) vfe_msg_sync_t2_done; - - -/* - * Message to notify the ARM that async t1 operation completed - */ - -#define VFE_MSG_ASYNC_T1_DONE 0x000F -#define VFE_MSG_ASYNC_T1_DONE_LEN sizeof(vfe_msg_async_t1_done) - -typedef struct { -} __attribute__((packed)) vfe_msg_async_t1_done; - - - -/* - * Message to notify the ARM that async t2 operation completed - */ - -#define VFE_MSG_ASYNC_T2_DONE 0x0010 -#define VFE_MSG_ASYNC_T2_DONE_LEN sizeof(vfe_msg_async_t2_done) - -typedef struct { -} __attribute__((packed)) vfe_msg_async_t2_done; - - - -/* - * Message to notify the ARM that an error has occurred - */ - -#define VFE_MSG_ERROR 0x0011 -#define VFE_MSG_ERROR_LEN sizeof(vfe_msg_error) - -#define VFE_MSG_ERR_COND_NO_CAMIF_ERR 0x0000 -#define VFE_MSG_ERR_COND_CAMIF_ERR 0x0001 -#define VFE_MSG_ERR_COND_OP1_Y_NO_BUS_OF 0x0000 -#define VFE_MSG_ERR_COND_OP1_Y_BUS_OF 0x0002 -#define VFE_MSG_ERR_COND_OP1_CBCR_NO_BUS_OF 0x0000 -#define VFE_MSG_ERR_COND_OP1_CBCR_BUS_OF 0x0004 -#define VFE_MSG_ERR_COND_OP2_Y_NO_BUS_OF 0x0000 -#define VFE_MSG_ERR_COND_OP2_Y_BUS_OF 0x0008 -#define VFE_MSG_ERR_COND_OP2_CBCR_NO_BUS_OF 0x0000 -#define VFE_MSG_ERR_COND_OP2_CBCR_BUS_OF 0x0010 -#define VFE_MSG_ERR_COND_AF_NO_BUS_OF 0x0000 -#define VFE_MSG_ERR_COND_AF_BUS_OF 0x0020 -#define VFE_MSG_ERR_COND_WB_EXP_NO_BUS_OF 0x0000 -#define VFE_MSG_ERR_COND_WB_EXP_BUS_OF 0x0040 -#define VFE_MSG_ERR_COND_NO_AXI_ERR 0x0000 -#define VFE_MSG_ERR_COND_AXI_ERR 0x0080 - -#define VFE_MSG_CAMIF_STS_IDLE 0x0000 -#define VFE_MSG_CAMIF_STS_CAPTURE_DATA 0x0001 - -typedef struct { - unsigned int err_cond; - unsigned int camif_sts; -} __attribute__((packed)) vfe_msg_error; - - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5/snd_adie.h b/arch/arm/mach-msm/include/mach/qdsp5/snd_adie.h deleted file mode 100644 index 2bad3b00842a43428d740d56495dff94157c5d4d..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5/snd_adie.h +++ /dev/null @@ -1,86 +0,0 @@ -/* Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __SND_ADIE_SVC_H_ -#define __SND_ADIE_SVC_H_ - -#define ADIE_SVC_PROG 0x30000002 -#define ADIE_SVC_VERS 0x00020003 - -#define ADIE_SVC_CLIENT_STATUS_FUNC_PTR_TYPE_PROC 0xFFFFFF01 -#define SND_ADIE_SVC_CLIENT_REGISTER_PROC 34 -#define SND_ADIE_SVC_CONFIG_ADIE_BLOCK_PROC 35 -#define SND_ADIE_SVC_CLIENT_DEREGISTER_PROC 36 - -#define ADIE_SVC_MAX_CLIENTS 5 - -enum adie_svc_client_operation{ - ADIE_SVC_REGISTER_CLIENT, - ADIE_SVC_DEREGISTER_CLIENT, - ADIE_SVC_CONFIG_ADIE_BLOCK, -}; - -enum adie_svc_status_type{ - ADIE_SVC_STATUS_SUCCESS, - ADIE_SVC_STATUS_FAILURE, - ADIE_SVC_STATUS_INUSE -}; - -enum adie_block_enum_type{ - MIC_BIAS, - HSSD, - HPH_PA -}; - -enum adie_config_enum_type{ - DISABLE, - ENABLE -}; - -struct adie_svc_client{ - int client_id; - int cb_id; - enum adie_svc_status_type status; - bool adie_svc_cb_done; - struct mutex lock; - wait_queue_head_t wq; - struct msm_rpc_client *rpc_client; -}; - -struct adie_svc_client_register_cb_cb_args { - int cb_id; - uint32_t size; - int client_id; - enum adie_block_enum_type adie_block; - enum adie_svc_status_type status; - enum adie_svc_client_operation client_operation; -}; - -struct adie_svc_client_register_cb_args { - int cb_id; -}; - -struct adie_svc_client_deregister_cb_args { - int client_id; -}; - -struct adie_svc_config_adie_block_cb_args { - int client_id; - enum adie_block_enum_type adie_block; - enum adie_config_enum_type config; -}; - -int adie_svc_get(void); -int adie_svc_put(int id); -int adie_svc_config_adie_block(int id, - enum adie_block_enum_type adie_block_type, bool enable); -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/acdb_commands.h b/arch/arm/mach-msm/include/mach/qdsp5v2/acdb_commands.h deleted file mode 100644 index 93863078a6aae125ff0f05d7f0388c1f87e6650a..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/acdb_commands.h +++ /dev/null @@ -1,303 +0,0 @@ -/* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef _MACH_QDSP5_V2_ACDB_COMMANDS_H -#define _MACH_QDSP5_V2_ACDB_COMMANDS_H - -#define ACDB_VOICE_NETWORK_ID_DEFAULT 0x00010037 -#define ACDB_INITIALISING 0 -#define ACDB_READY 1 - - -/* 4KB */ -#define ACDB_PAGE_SIZE 0x1000 - -#define ACDB_CDMA_NB 0x0108b153 -#define ACDB_CDMA_WB 0x0108b154 -#define ACDB_GSM_NB 0x0108b155 -#define ACDB_GSM_WB 0x0108b156 -#define ACDB_WCDMA_NB 0x0108b157 -#define ACDB_WCDMA_WB 0x0108b158 - - -/* ACDB commands */ - - -/* struct acdb_cmd_install_device */ -#define ACDB_INSTALL_DEVICE 0x0108d245 - -/* struct acdb_cmd_install_device */ -#define ACDB_UNINSTALL_DEVICE 0x0108d246 - -/* struct acdb_cmd_device */ -#define ACDB_GET_DEVICE 0x0108bb92 - -/* struct acdb_cmd_device */ -#define ACDB_SET_DEVICE 0x0108bb93 - -/* struct acdb_cmd_get_device_table */ -#define ACDB_GET_DEVICE_TABLE 0x0108bb97 - -/* struct acdb_cmd_get_device_capabilities */ -#define ACDB_GET_DEVICE_CAPABILITIES 0x0108f5ca - -/* struct acdb_cmd_get_device_info */ -#define ACDB_GET_DEVICE_INFO 0x0108f5cb - -/*command to intitialize ACDB based on codec type*/ -#define ACDB_CMD_INITIALIZE_FOR_ADIE 0x00011283 - - -/* ACDB Error codes */ - -#define ACDB_RES_SUCCESS 0 -#define ACDB_RES_FAILURE -1 -#define ACDB_RES_BADPARM -2 -#define ACDB_RES_BADSTATE -3 - -#define TGTVERS_MSM7x30_BRING_UP 0x00010064 - - - -/* Algorithm Aspect IDs */ - -#define IID_ENABLE_FLAG 0x0108b6b9 - - -#define IID_ENABLE_FLAG_SIZE 1 -#define IID_ECHO_CANCELLER_VERSION_SIZE 2 -#define IID_ECHO_CANCELLER_MODE_SIZE 2 -#define IID_ECHO_CANCELLER_NOISE_SUPPRESSOR_ENABLE_SIZE 1 -#define IID_ECHO_CANCELLER_PARAMETERS_SIZE 32 -#define IID_ECHO_CANCELLER_NEXTGEN_NB_PARAMETERS_SIZE (38 * 2) -#define IID_ECHO_CANCELLER_NEXTGEN_WB_PARAMETERS_SIZE (38 * 2) -#define IID_FLUENCE_PARAMETERS_SIZE 486 -#define IID_AFE_VOLUME_CONTROL_SIZE 6 -#define IID_GAIN_SIZE 2 -#define IID_VOICE_FIR_FILTER_SIZE 14 -#define IID_VOICE_IIR_FILTER_SIZE 114 -#define IID_RX_DBM_OFFSET_SIZE 2 -#define IID_AGC_SIZE 36 -#define IID_AVC_SIZE 80 - -#define IID_AUDIO_IIR_COEFF_SIZE 100 -#define IID_MBADRC_PARAMETERS_SIZE 8 -#define IID_MBADRC_EXT_BUFF_SIZE 392 -#define IID_MBADRC_BAND_CONFIG_SIZE 100 -#define IID_QAFX_PARAMETERS_SIZE 2 -#define IID_QCONCERT_PARAMETERS_SIZE 2 -#define IID_AUDIO_AGC_PARAMETERS_SIZE 42 -#define IID_NS_PARAMETERS_SIZE 14 - -#define IID_ECHO_CANCELLER_VERSION 0x00010042 -#define IID_ECHO_CANCELLER_MODE 0x00010043 -#define IID_ECHO_CANCELLER_NOISE_SUPPRESSOR_ENABLE 0x00010044 -#define IID_ECHO_CANCELLER_PARAMETERS 0x00010045 -#define IID_ECHO_CANCELLER_NEXTGEN_NB_PARAMETERS 0x00010046 -#define IID_ECHO_CANCELLER_NEXTGEN_WB_PARAMETERS 0x00010047 -#define IID_FLUENCE_PARAMETERS 0x00010048 -#define IID_AFE_VOLUME_CONTROL 0x00010049 -#define IID_GAIN 0x0001004A -#define IID_VOICE_FIR_FILTER 0x0001004B -#define IID_VOICE_IIR_FILTER 0x0001004C -#define IID_AGC 0x0001004E -#define IID_AVC 0x0001004F -#define ABID_SIDETONE_GAIN 0x00010050 -#define ABID_TX_VOICE_GAIN 0x00010051 -#define ABID_TX_DTMF_GAIN 0x00010052 -#define ABID_CODEC_TX_GAIN 0x00010053 -#define ABID_HSSD 0x00010054 -#define ABID_TX_AGC 0x00010055 -#define ABID_TX_VOICE_FIR 0x00010056 -#define ABID_TX_VOICE_IIR 0x00010057 -#define ABID_ECHO_CANCELLER 0x00010058 -#define ABID_ECHO_CANCELLER_NB_LVHF 0x00010059 -#define ABID_ECHO_CANCELLER_WB_LVHF 0x0001005A -#define ABID_FLUENCE 0x0001005B -#define ABID_CODEC_RX_GAIN 0x0001005C -#define ABID_RX_DBM_OFFSET 0x0001005D -#define ABID_RX_AGC 0x0001005E -#define ABID_AVC 0x0001005F -#define ABID_RX_VOICE_FIR 0x00010060 -#define ABID_RX_VOICE_IIR 0x00010061 -#define ABID_AFE_VOL_CTRL 0x00010067 - - -/* AUDIO IDs */ -#define ABID_AUDIO_AGC_TX 0x00010068 -#define ABID_AUDIO_NS_TX 0x00010069 -#define ABID_VOICE_NS 0x0001006A -#define ABID_AUDIO_IIR_TX 0x0001006B -#define ABID_AUDIO_IIR_RX 0x0001006C -#define ABID_AUDIO_MBADRC_RX 0x0001006E -#define ABID_AUDIO_QAFX_RX 0x0001006F -#define ABID_AUDIO_QCONCERT_RX 0x00010070 -#define ABID_AUDIO_STF_RX 0x00010071 -#define ABID_AUDIO_CALIBRATION_GAIN_RX 0x00011162 -#define ABID_AUDIO_CALIBRATION_GAIN_TX 0x00011149 -#define ABID_AUDIO_PBE_RX 0x00011197 -#define ABID_AUDIO_RMC_TX 0x00011226 -#define ABID_AUDIO_FLUENCE_TX 0x00011244 - - -#define IID_AUDIO_AGC_PARAMETERS 0x0001007E -#define IID_NS_PARAMETERS 0x00010072 -#define IID_AUDIO_IIR_COEFF 0x00010073 -#define IID_MBADRC_EXT_BUFF 0x00010075 -#define IID_MBADRC_BAND_CONFIG 0x00010076 -#define IID_MBADRC_PARAMETERS 0x00010077 -#define IID_QAFX_PARAMETERS 0x00010079 -#define IID_QCONCERT_PARAMETERS 0x0001007A -#define IID_STF_COEFF 0x0001007B -#define IID_AUDIO_CALIBRATION_GAIN_RX 0x00011163 -#define IID_AUDIO_CALIBRATION_GAIN_TX 0x00011171 -#define IID_PBE_CONFIG_PARAMETERS 0x00011198 -#define IID_AUDIO_PBE_RX_ENABLE_FLAG 0x00011199 -#define IID_AUDIO_RMC_PARAM 0x00011227 -#define IID_AUDIO_FLUENCE_TX 0x00011245 - - -#define TOPID_RX_TOPOLOGY_1 0x00010062 -#define TOPID_TX_TOPOLOGY_1 0x00010063 -#define AFERID_INT_SINK 0x00010065 -#define AFERID_INT_SOURCE 0x00010066 -#define AFERID_NO_SINK 0x00000000 -#define AFERID_NULL_SINK 0x0108ea92 - - -struct acdb_cmd_install_device { - u32 command_id; - u32 device_id; - u32 topology_id; - u32 afe_routing_id; - u32 cad_routing_id; /* see "Sample Rate Bit Mask" below */ - u32 sample_rate_mask; - - /* represents device direction: Tx, Rx (aux pga - loopback) */ - u8 device_type; - u8 channel_config; /* Mono or Stereo */ - u32 adie_codec_path_id; -}; - - -struct acdb_cmd_get_device_capabilities { - u32 command_id; - u32 total_bytes; /* Length in bytes allocated for buffer */ - u32 *phys_buf; /* Physical Address of data */ -}; - - -struct acdb_cmd_get_device_info { - u32 command_id; - u32 device_id; - u32 total_bytes; /* Length in bytes allocated for buffer */ - u32 *phys_buf; /* Physical Address of data */ -}; - -struct acdb_cmd_device { - u32 command_id; - u32 device_id; - u32 network_id; - u32 sample_rate_id; /* Actual sample rate value */ - u32 interface_id; /* See interface id's above */ - u32 algorithm_block_id; /* See enumerations above */ - u32 total_bytes; /* Length in bytes used by buffer */ - u32 *phys_buf; /* Physical Address of data */ -}; - -struct acdb_cmd_get_device_table { - u32 command_id; - u32 device_id; - u32 network_id; - u32 sample_rate_id; /* Actual sample rate value */ - u32 total_bytes; /* Length in bytes used by buffer */ - u32 *phys_buf; /* Physical Address of data */ -}; - -struct acdb_result { - /* This field is populated in response to the */ - /* ACDB_GET_DEVICE_CAPABILITIES command and indicates the total */ - /* devices whose capabilities are copied to the physical memory. */ - u32 total_devices; - u32 *buf; /* Physical Address of data */ - u32 used_bytes; /* The size in bytes of the data */ - u32 result; /* See ACDB Error codes above */ -}; - -struct acdb_device_capability { - u32 device_id; - u32 sample_rate_mask; /* See "Sample Rate Bit Mask" below */ -}; - -struct acdb_dev_info { - u32 cad_routing_id; - u32 sample_rate_mask; /* See "Sample Rate Bit Mask" below */ - u32 adsp_device_id; /* QDSP6 device ID */ - u32 device_type; /* Tx, Rx (aux pga - loopback) */ - u32 channel_config; /* Mono or Stereo */ - s32 min_volume; /* Min volume (mB) */ - s32 max_volume; /* Max volume (mB) */ -}; - -/*structure is used to intialize ACDB software on modem -based on adie type detected*/ -struct acdb_cmd_init_adie { - u32 command_id; - u32 adie_type; -}; - -#define ACDB_CURRENT_ADIE_MODE_UNKNOWN 0 -#define ACDB_CURRENT_ADIE_MODE_TIMPANI 1 -#define ACDB_CURRENT_ADIE_MODE_MARIMBA 2 - -/* Sample Rate Bit Mask */ - -/* AUX PGA devices will have a sample rate mask of 0xFFFFFFFF */ -/* 8kHz 0x00000001 */ -/* 11.025kHz 0x00000002 */ -/* 12kHz 0x00000004 */ -/* 16kHz 0x00000008 */ -/* 22.5kHz 0x00000010 */ -/* 24kHz 0x00000020 */ -/* 32kHz 0x00000040 */ -/* 44.1kHz 0x00000080 */ -/* 48kHz 0x00000100 */ - - -/* Device type enumeration */ -enum { - RX_DEVICE = 1, - TX_DEVICE, - AUXPGA_DEVICE, - DEVICE_TYPE_MAX -}; - -#ifdef CONFIG_DEBUG_FS -/*These are ABID used for RTC*/ -#define ABID_AUDIO_RTC_MBADRC_RX 0x0001118A -#define ABID_AUDIO_RTC_VOLUME_PAN_RX 0x0001118C -#define ABID_AUDIO_RTC_SPA 0x0001118E -#define ABID_AUDIO_RTC_EQUALIZER_PARAMETERS 0x0001119F - -/*These are IID used for RTC*/ -#define IID_AUDIO_RTC_MBADRC_PARAMETERS 0x0001118B -#define IID_AUDIO_RTC_VOLUME_PAN_PARAMETERS 0x0001118D -#define IID_AUDIO_RTC_SPA_PARAMETERS 0x0001118F -#define IID_AUDIO_RTC_EQUALIZER_PARAMETERS 0x0001119E -#define IID_AUDIO_RTC_AGC_PARAMETERS 0x000111A7 -#define IID_AUDIO_RTC_TX_IIR_COEFF 0x000111A8 - -#endif - - -#endif - diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/adie_marimba.h b/arch/arm/mach-msm/include/mach/qdsp5v2/adie_marimba.h deleted file mode 100644 index 1851322881eba0f177ad0eb2741c4943fe1919d3..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/adie_marimba.h +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright (c) 2009-2010, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef __MACH_QDSP5_V2_ADIE_MARIMBA_H -#define __MACH_QDSP5_V2_ADIE_MARIMBA_H - -#include - -/* Value Represents a entry */ -#define ADIE_CODEC_ACTION_ENTRY 0x1 -/* Value representing a delay wait */ -#define ADIE_CODEC_ACTION_DELAY_WAIT 0x2 -/* Value representing a stage reached */ -#define ADIE_CODEC_ACTION_STAGE_REACHED 0x3 - -/* This value is the state after the client sets the path */ -#define ADIE_CODEC_PATH_OFF 0x0050 - -/* State to which client asks the drv to proceed to where it can - * set up the clocks and 0-fill PCM buffers - */ -#define ADIE_CODEC_DIGITAL_READY 0x0100 - -/* State to which client asks the drv to proceed to where it can - * start sending data after internal steady state delay - */ -#define ADIE_CODEC_DIGITAL_ANALOG_READY 0x1000 - - -/* Client Asks adie to switch off the Analog portion of the - * the internal codec. After the use of this path - */ -#define ADIE_CODEC_ANALOG_OFF 0x0750 - - -/* Client Asks adie to switch off the digital portion of the - * the internal codec. After switching off the analog portion. - * - * 0-fill PCM may or maynot be sent at this point - * - */ -#define ADIE_CODEC_DIGITAL_OFF 0x0600 - -/* State to which client asks the drv to write the default values - * to the registers */ -#define ADIE_CODEC_FLASH_IMAGE 0x0001 - -/* Path type */ -#define ADIE_CODEC_RX 0 -#define ADIE_CODEC_TX 1 -#define ADIE_CODEC_LB 3 -#define ADIE_CODEC_MAX 4 - -#define ADIE_CODEC_PACK_ENTRY(reg, mask, val) ((val)|(mask << 8)|(reg << 16)) - -#define ADIE_CODEC_UNPACK_ENTRY(packed, reg, mask, val) \ - do { \ - ((reg) = ((packed >> 16) & (0xff))); \ - ((mask) = ((packed >> 8) & (0xff))); \ - ((val) = ((packed) & (0xff))); \ - } while (0); - -struct adie_codec_action_unit { - u32 type; - u32 action; -}; - -struct adie_codec_hwsetting_entry{ - struct adie_codec_action_unit *actions; - u32 action_sz; - u32 freq_plan; - u32 osr; - /* u32 VolMask; - * u32 SidetoneMask; - */ -}; - -struct adie_codec_dev_profile { - u32 path_type; /* RX or TX */ - u32 setting_sz; - struct adie_codec_hwsetting_entry *settings; -}; - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/afe.h b/arch/arm/mach-msm/include/mach/qdsp5v2/afe.h deleted file mode 100644 index e4e29335f3da71e2abffdad9c1e6939d9fa58365..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/afe.h +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef _MACH_QDSP5_V2_AFE_H -#define _MACH_QDSP5_V2_AFE_H - -#include -#include - -#define AFE_HW_PATH_CODEC_RX 1 -#define AFE_HW_PATH_CODEC_TX 2 -#define AFE_HW_PATH_AUXPCM_RX 3 -#define AFE_HW_PATH_AUXPCM_TX 4 -#define AFE_HW_PATH_MI2S_RX 5 -#define AFE_HW_PATH_MI2S_TX 6 - -#define AFE_VOLUME_UNITY 0x4000 /* Based on Q14 */ - -struct msm_afe_config { - u16 sample_rate; - u16 channel_mode; - u16 volume; - /* To be expaned for AUX CODEC */ -}; - -int afe_enable(u8 path_id, struct msm_afe_config *config); - -int afe_disable(u8 path_id); - -int afe_config_aux_codec(int pcm_ctl_value, int aux_codec_intf_value, - int data_format_pad); -int afe_config_fm_codec(int fm_enable, uint16_t source); - -int afe_config_fm_volume(uint16_t volume); -int afe_config_fm_calibration_gain(uint16_t device_id, - uint16_t calibration_gain); -void afe_loopback(int enable); -void afe_ext_loopback(int enable, int rx_copp_id, int tx_copp_id); - -void afe_device_volume_ctrl(u16 device_id, u16 device_volume); - -int afe_config_rmc_block(struct acdb_rmc_block *acdb_rmc); -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdb_def.h b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdb_def.h deleted file mode 100644 index 0a0c3082125fd69062e2283cb41336a3d413fa39..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdb_def.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2010 - 2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef _MACH_QDSP5_V2_AUDIO_ACDB_DEF_H -#define _MACH_QDSP5_V2_AUDIO_ACDB_DEF_H - -/* Define ACDB device ID */ -#define ACDB_ID_HANDSET_SPKR 1 -#define ACDB_ID_HANDSET_MIC 2 -#define ACDB_ID_HEADSET_MIC 3 -#define ACDB_ID_HEADSET_SPKR_MONO 4 -#define ACDB_ID_HEADSET_SPKR_STEREO 5 -#define ACDB_ID_SPKR_PHONE_MIC 6 -#define ACDB_ID_SPKR_PHONE_MONO 7 -#define ACDB_ID_SPKR_PHONE_STEREO 8 -#define ACDB_ID_BT_SCO_MIC 9 -#define ACDB_ID_BT_SCO_SPKR 0x0A -#define ACDB_ID_BT_A2DP_SPKR 0x0B -#define ACDB_ID_BT_A2DP_TX 0x10 -#define ACDB_ID_TTY_HEADSET_MIC 0x0C -#define ACDB_ID_TTY_HEADSET_SPKR 0x0D -#define ACDB_ID_HEADSET_MONO_PLUS_SPKR_MONO_RX 0x11 -#define ACDB_ID_HEADSET_STEREO_PLUS_SPKR_STEREO_RX 0x14 -#define ACDB_ID_FM_TX_LOOPBACK 0x17 -#define ACDB_ID_FM_TX 0x18 -#define ACDB_ID_LP_FM_SPKR_PHONE_STEREO_RX 0x19 -#define ACDB_ID_LP_FM_HEADSET_SPKR_STEREO_RX 0x1A -#define ACDB_ID_I2S_RX 0x20 -#define ACDB_ID_SPKR_PHONE_MIC_BROADSIDE 0x2B -#define ACDB_ID_HANDSET_MIC_BROADSIDE 0x2C -#define ACDB_ID_SPKR_PHONE_MIC_ENDFIRE 0x2D -#define ACDB_ID_HANDSET_MIC_ENDFIRE 0x2E -#define ACDB_ID_I2S_TX 0x30 -#define ACDB_ID_HDMI 0x40 -#define ACDB_ID_FM_RX 0x4F -/*Replace the max device ID,if any new device is added Specific to RTC only*/ -#define ACDB_ID_MAX ACDB_ID_FM_RX - -/* ID used for virtual devices */ -#define PSEUDO_ACDB_ID 0xFFFF - -#endif /* _MACH_QDSP5_V2_AUDIO_ACDB_DEF_H */ diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdbi.h b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdbi.h deleted file mode 100644 index f05ebaa112921e7acca8246010ac14796c49ac8e..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdbi.h +++ /dev/null @@ -1,303 +0,0 @@ -/* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef _MACH_QDSP5_V2_AUDIO_ACDBI_H -#define _MACH_QDSP5_V2_AUDIO_ACDBI_H - -#define DBOR_SIGNATURE 0x524F4244 - -#ifdef CONFIG_DEBUG_FS -void acdb_rtc_set_err(u32 ErrCode); -#endif - - -struct header { - u32 dbor_signature; - u32 abid; - u32 iid; - u32 data_len; -}; - -enum { - ACDB_AGC_BLOCK = 197, - ACDB_IIR_BLOCK = 245, - ACDB_MBADRC_BLOCK = 343 -}; - -/* Structure to query for acdb parameter */ -struct acdb_get_block { - u32 acdb_id; - u32 sample_rate_id; /* Actual sample rate value */ - u32 interface_id; /* Interface id's */ - u32 algorithm_block_id; /* Algorithm block id */ - u32 total_bytes; /* Length in bytes used by buffer for - configuration */ - u32 *buf_ptr; /* Address for storing configuration - data */ -}; - -struct acdb_agc_block { - u16 enable_status; - u16 comp_rlink_static_gain; - u16 comp_rlink_aig_flag; - u16 exp_rlink_threshold; - u16 exp_rlink_slope; - u16 comp_rlink_threshold; - u16 comp_rlink_slope; - u16 comp_rlink_aig_attack_k; - u16 comp_rlink_aig_leak_down; - u16 comp_rlink_aig_leak_up; - u16 comp_rlink_aig_max; - u16 comp_rlink_aig_min; - u16 comp_rlink_aig_release_k; - u16 comp_rlink_aig_sm_leak_rate_fast; - u16 comp_rlink_aig_sm_leak_rate_slow; - u16 comp_rlink_attack_k_msw; - u16 comp_rlink_attack_k_lsw; - u16 comp_rlink_delay; - u16 comp_rlink_release_k_msw; - u16 comp_rlink_release_k_lsw; - u16 comp_rlink_rms_trav; -}; - - -struct iir_coeff_type { - u16 b0_lo; - u16 b0_hi; - u16 b1_lo; - u16 b1_hi; - u16 b2_lo; - u16 b2_hi; -}; - -struct iir_coeff_stage_a { - u16 a1_lo; - u16 a1_hi; - u16 a2_lo; - u16 a2_hi; -}; - -struct acdb_iir_block { - u16 enable_flag; - u16 stage_count; - struct iir_coeff_type stages[4]; - struct iir_coeff_stage_a stages_a[4]; - u16 shift_factor[4]; - u16 pan[4]; -}; - - - -struct mbadrc_band_config_type { - u16 mbadrc_sub_band_enable; - u16 mbadrc_sub_mute; - u16 mbadrc_comp_rms_tav; - u16 mbadrc_comp_threshold; - u16 mbadrc_comp_slop; - u16 mbadrc_comp_attack_msw; - u16 mbadrc_comp_attack_lsw; - u16 mbadrc_comp_release_msw; - u16 mbadrc_comp_release_lsw; - u16 mbadrc_make_up_gain; -}; - -struct mbadrc_parameter { - u16 mbadrc_enable; - u16 mbadrc_num_bands; - u16 mbadrc_down_sample_level; - u16 mbadrc_delay; -}; - -struct acdb_mbadrc_block { - u16 ext_buf[196]; - struct mbadrc_band_config_type band_config[5]; - struct mbadrc_parameter parameters; -}; - -struct acdb_calib_gain_rx { - u16 audppcalgain; - u16 reserved; -}; - -struct acdb_calib_gain_tx { - u16 audprecalgain; - u16 reserved; -}; - -struct acdb_pbe_block { - s16 realbassmix; - s16 basscolorcontrol; - u16 mainchaindelay; - u16 xoverfltorder; - u16 bandpassfltorder; - s16 adrcdelay; - u16 downsamplelevel; - u16 comprmstav; - s16 expthreshold; - u16 expslope; - u16 compthreshold; - u16 compslope; - u16 cpmpattack_lsw; - u16 compattack_msw; - u16 comprelease_lsw; - u16 comprelease_msw; - u16 compmakeupgain; - s16 baselimthreshold; - s16 highlimthreshold; - s16 basslimmakeupgain; - s16 highlimmakeupgain; - s16 limbassgrc; - s16 limhighgrc; - s16 limdelay; - u16 filter_coeffs[90]; -}; - -struct acdb_rmc_block { - s16 rmc_enable; - u16 rmc_ipw_length_ms; - u16 rmc_detect_start_threshdb; - u16 rmc_peak_length_ms; - s16 rmc_init_pulse_threshdb; - u16 rmc_init_pulse_length_ms; - u16 rmc_total_int_length_ms; - u16 rmc_rampupdn_length_ms; - u16 rmc_delay_length_ms; - u16 reserved00; - u16 reserved01; - s16 reserved02; - s16 reserved03; - s16 reserved04; -}; - -struct acdb_fluence_block { - u16 csmode; - u16 cs_tuningMode; - u16 cs_echo_path_delay_by_80; - u16 cs_echo_path_delay; - u16 af1_twoalpha; - u16 af1_erl; - u16 af1_taps; - u16 af1_preset_coefs; - u16 af1_offset; - u16 af2_twoalpha; - u16 af2_erl; - u16 af2_taps; - u16 af2_preset_coefs; - u16 af2_offset; - u16 pcd_twoalpha; - u16 pcd_offset; - u16 cspcd_threshold; - u16 wgthreshold; - u16 mpthreshold; - u16 sf_init_table_0[8]; - u16 sf_init_table_1[8]; - u16 sf_taps; - u16 sf_twoalpha; - u16 dnns_echoalpharev; - u16 dnns_echoycomp; - u16 dnns_wbthreshold; - u16 dnns_echogammahi; - u16 dnns_echogammalo; - u16 dnns_noisegammas; - u16 dnns_noisegamman; - u16 dnns_noisegainmins; - u16 dnns_noisegainminn; - u16 dnns_noisebiascomp; - u16 dnns_acthreshold; - u16 wb_echo_ratio_2mic; - u16 wb_gamma_e; - u16 wb_gamma_nn; - u16 wb_gamma_sn; - u16 vcodec_delay0; - u16 vcodec_delay1; - u16 vcodec_len0; - u16 vcodec_len1; - u16 vcodec_thr0; - u16 vcodec_thr1; - u16 fixcalfactorleft; - u16 fixcalfactorright; - u16 csoutputgain; - u16 enh_meu_1; - u16 enh_meu_2; - u16 fixed_over_est; - u16 rx_nlpp_limit; - u16 rx_nlpp_gain; - u16 wnd_threshold; - u16 wnd_ns_hover; - u16 wnd_pwr_smalpha; - u16 wnd_det_esmalpha; - u16 wnd_ns_egoffset; - u16 wnd_sm_ratio; - u16 wnd_det_coefs[5]; - u16 wnd_th1; - u16 wnd_th2; - u16 wnd_fq; - u16 wnd_dfc; - u16 wnd_sm_alphainc; - u16 wnd_sm_alphsdec; - u16 lvnv_spdet_far; - u16 lvnv_spdet_mic; - u16 lvnv_spdet_xclip; - u16 dnns_nl_atten; - u16 dnns_cni_level; - u16 dnns_echogammaalpha; - u16 dnns_echogammarescue; - u16 dnns_echogammadt; - u16 mf_noisegammafac; - u16 e_noisegammafac; - u16 dnns_noisegammainit; - u16 sm_noisegammas; - u16 wnd_noisegamman; - u16 af_taps_bg_spkr; - u16 af_erl_bg_spkr; - u16 minimum_erl_bg; - u16 erl_step_bg; - u16 upprisecalpha; - u16 upprisecthresh; - u16 uppriwindbias; - u16 e_pcd_threshold; - u16 nv_maxvadcount; - u16 crystalspeechreserved[38]; - u16 cs_speaker[7]; - u16 ns_fac; - u16 ns_blocksize; - u16 is_bias; - u16 is_bias_inp; - u16 sc_initb; - u16 ac_resetb; - u16 sc_avar; - u16 is_hover[5]; - u16 is_cf_level; - u16 is_cf_ina; - u16 is_cf_inb; - u16 is_cf_a; - u16 is_cf_b; - u16 sc_th; - u16 sc_pscale; - u16 sc_nc; - u16 sc_hover; - u16 sc_alphas; - u16 sc_cfac; - u16 sc_sdmax; - u16 sc_sdmin; - u16 sc_initl; - u16 sc_maxval; - u16 sc_spmin; - u16 is_ec_th; - u16 is_fx_dl; - u16 coeffs_iva_filt_0[32]; - u16 coeffs_iva_filt_1[32]; -}; - -s32 acdb_get_calibration_data(struct acdb_get_block *get_block); -void fluence_feature_update(int enable, int stream_id); -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_dev_ctl.h b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_dev_ctl.h deleted file mode 100644 index 976d9ae2bc205d3ab5204221257dddda0e372e46..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_dev_ctl.h +++ /dev/null @@ -1,206 +0,0 @@ -/* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef __MACH_QDSP5_V2_SNDDEV_H -#define __MACH_QDSP5_V2_SNDDEV_H -#include - -#define AUDIO_DEV_CTL_MAX_DEV 64 -#define DIR_TX 2 -#define DIR_RX 1 - -#define DEVICE_IGNORE 0xff -#define SESSION_IGNORE 0x00000000 - -#define VOICE_STATE_INVALID 0x0 -#define VOICE_STATE_INCALL 0x1 -#define VOICE_STATE_OFFCALL 0x2 -#define MAX_COPP_NODE_SUPPORTED 6 -#define MAX_AUDREC_SESSIONS 3 - -#define REAL_STEREO_CHANNEL_MODE 9 - -struct msm_snddev_info { - const char *name; - u32 capability; - u32 copp_id; - u32 acdb_id; - u32 dev_volume; - struct msm_snddev_ops { - int (*open)(struct msm_snddev_info *); - int (*close)(struct msm_snddev_info *); - int (*set_freq)(struct msm_snddev_info *, u32); - int (*enable_sidetone)(struct msm_snddev_info *, u32); - int (*set_device_volume)(struct msm_snddev_info *, u32); - } dev_ops; - u8 opened; - void *private_data; - bool state; - u32 sample_rate; - u32 set_sample_rate; - u32 sessions; - int usage_count; - s32 max_voc_rx_vol[VOC_RX_VOL_ARRAY_NUM]; /* [0] is for NB,[1] for WB */ - s32 min_voc_rx_vol[VOC_RX_VOL_ARRAY_NUM]; -}; - -struct msm_volume { - int volume; /* Volume parameter, in % Scale */ - int pan; -}; - -extern struct msm_volume msm_vol_ctl; - -int msm_get_dual_mic_config(int enc_session_id); -int msm_set_dual_mic_config(int enc_session_id, int config); -int msm_reset_all_device(void); -void msm_snddev_register(struct msm_snddev_info *); -void msm_snddev_unregister(struct msm_snddev_info *); -int msm_snddev_devcount(void); -int msm_snddev_query(int dev_id); -unsigned short msm_snddev_route_dec(int popp_id); -unsigned short msm_snddev_route_enc(int enc_id); -int msm_snddev_set_dec(int popp_id, int copp_id, int set); -int msm_snddev_set_enc(int popp_id, int copp_id, int set); -int msm_snddev_is_set(int popp_id, int copp_id); -int msm_get_voc_route(u32 *rx_id, u32 *tx_id); -int msm_set_voc_route(struct msm_snddev_info *dev_info, int stream_type, - int dev_id); -int msm_snddev_enable_sidetone(u32 dev_id, u32 enable); - -struct msm_snddev_info *audio_dev_ctrl_find_dev(u32 dev_id); - -void msm_release_voc_thread(void); - -int snddev_voice_set_volume(int vol, int path); - -struct auddev_evt_voc_devinfo { - u32 dev_type; /* Rx or Tx */ - u32 acdb_dev_id; /* acdb id of device */ - u32 dev_sample; /* Sample rate of device */ - s32 max_rx_vol[VOC_RX_VOL_ARRAY_NUM]; /* unit is mb (milibel), - [0] is for NB, other for WB */ - s32 min_rx_vol[VOC_RX_VOL_ARRAY_NUM]; /* unit is mb */ - u32 dev_id; /* registered device id */ -}; - -struct auddev_evt_audcal_info { - u32 dev_id; - u32 acdb_id; - u32 sample_rate; - u32 dev_type; - u32 sessions; -}; - -struct auddev_evt_devinfo { - u32 dev_id; - u32 acdb_id; - u32 sample_rate; - u32 dev_type; - u32 sessions; -}; - -union msm_vol_mute { - int vol; - bool mute; -}; - -struct auddev_evt_voc_mute_info { - u32 dev_type; - u32 acdb_dev_id; - union msm_vol_mute dev_vm_val; -}; - -struct auddev_evt_freq_info { - u32 dev_type; - u32 acdb_dev_id; - u32 sample_rate; -}; - -union auddev_evt_data { - struct auddev_evt_voc_devinfo voc_devinfo; - struct auddev_evt_voc_mute_info voc_vm_info; - struct auddev_evt_freq_info freq_info; - u32 routing_id; - s32 session_vol; - s32 voice_state; - struct auddev_evt_audcal_info audcal_info; - struct auddev_evt_devinfo devinfo; -}; - -struct message_header { - uint32_t id; - uint32_t data_len; -}; - -#define AUDDEV_EVT_DEV_CHG_VOICE 0x01 /* device change event */ -#define AUDDEV_EVT_DEV_RDY 0x02 /* device ready event */ -#define AUDDEV_EVT_DEV_RLS 0x04 /* device released event */ -#define AUDDEV_EVT_REL_PENDING 0x08 /* device release pending */ -#define AUDDEV_EVT_DEVICE_VOL_MUTE_CHG 0x10 /* device volume changed */ -#define AUDDEV_EVT_START_VOICE 0x20 /* voice call start */ -#define AUDDEV_EVT_END_VOICE 0x40 /* voice call end */ -#define AUDDEV_EVT_STREAM_VOL_CHG 0x80 /* device volume changed */ -#define AUDDEV_EVT_FREQ_CHG 0x100 /* Change in freq */ -#define AUDDEV_EVT_VOICE_STATE_CHG 0x200 /* Change in voice state */ -#define AUDDEV_EVT_DEVICE_INFO 0x400 /* routed device information - event */ - -#define AUDDEV_CLNT_VOC 0x1 /* Vocoder clients */ -#define AUDDEV_CLNT_DEC 0x2 /* Decoder clients */ -#define AUDDEV_CLNT_ENC 0x3 /* Encoder clients */ -#define AUDDEV_CLNT_AUDIOCAL 0x4 /* AudioCalibration client */ - -#define AUDIO_DEV_CTL_MAX_LISTNER 20 /* Max Listeners Supported */ - -struct msm_snd_evt_listner { - uint32_t evt_id; - uint32_t clnt_type; - uint32_t clnt_id; - void *private_data; - void (*auddev_evt_listener)(u32 evt_id, - union auddev_evt_data *evt_payload, - void *private_data); - struct msm_snd_evt_listner *cb_next; - struct msm_snd_evt_listner *cb_prev; -}; - -struct event_listner { - struct msm_snd_evt_listner *cb; - u32 num_listner; - int state; /* Call state */ /* TODO remove this if not req*/ -}; - -extern struct event_listner event; -int auddev_register_evt_listner(u32 evt_id, u32 clnt_type, u32 clnt_id, - void (*listner)(u32 evt_id, - union auddev_evt_data *evt_payload, - void *private_data), - void *private_data); -int auddev_unregister_evt_listner(u32 clnt_type, u32 clnt_id); -void mixer_post_event(u32 evt_id, u32 dev_id); -void broadcast_event(u32 evt_id, u32 dev_id, u32 session_id); -int msm_snddev_request_freq(int *freq, u32 session_id, - u32 capability, u32 clnt_type); -int msm_snddev_withdraw_freq(u32 session_id, - u32 capability, u32 clnt_type); -int msm_device_is_voice(int dev_id); -int msm_get_voc_freq(int *tx_freq, int *rx_freq); -int msm_snddev_get_enc_freq(int session_id); -int msm_set_voice_vol(int dir, s32 volume); -int msm_set_voice_mute(int dir, int mute); -int msm_get_voice_state(void); -#ifdef CONFIG_DEBUG_FS -bool is_dev_opened(u32 acdb_id); -#endif - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_interct.h b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_interct.h deleted file mode 100644 index 2690bf5bd8a3c3300af5b132cff5211ac1c6661a..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_interct.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef __MACH_QDSP5_V2_AUDIO_INTERCT_H -#define __MACH_QDSP5_V2_AUDIO_INTERCT_H - -#define AUDIO_INTERCT_ADSP 0 -#define AUDIO_INTERCT_LPA 1 -#define AUDIO_ADSP_A 1 -#define AUDIO_ADSP_V 0 - -void audio_interct_lpa(u32 source); -void audio_interct_aux_regsel(u32 source); -void audio_interct_rpcm_source(u32 source); -void audio_interct_tpcm_source(u32 source); -void audio_interct_pcmmi2s(u32 source); -void audio_interct_codec(u32 source); -void audio_interct_multichannel(u32 source); - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/audpp.h b/arch/arm/mach-msm/include/mach/qdsp5v2/audpp.h deleted file mode 100644 index 763a6516d9f0a23dc98f93b7c1c91b0e1824cd5f..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/audpp.h +++ /dev/null @@ -1,129 +0,0 @@ -/*arch/arm/mach-msm/qdsp5iv2/audpp.h - * - * Copyright (C) 2008 Google, Inc. - * Copyright (c) 2008-2011, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * -*/ - -#ifndef _MACH_QDSP5_V2_AUDPP_H -#define _MACH_QDSP5_V2_AUDPP_H - -#include - -typedef void (*audpp_event_func)(void *private, unsigned id, uint16_t *msg); - -/* worst case delay of 1sec for response */ -#define MSM_AUD_DECODER_WAIT_MS 1000 -#define MSM_AUD_MODE_TUNNEL 0x00000100 -#define MSM_AUD_MODE_NONTUNNEL 0x00000200 -#define MSM_AUD_MODE_LP 0x00000400 -#define MSM_AUD_DECODER_MASK 0x0000FFFF -#define MSM_AUD_OP_MASK 0xFFFF0000 - -/* read call timeout for error cases */ -#define MSM_AUD_BUFFER_UPDATE_WAIT_MS 2000 - -/* stream info error message mask */ -#define AUDPLAY_STREAM_INFO_MSG_MASK 0xFFFF0000 -#define AUDPLAY_ERROR_THRESHOLD_ENABLE 0xFFFFFFFF - -#define NON_TUNNEL_MODE_PLAYBACK 1 -#define TUNNEL_MODE_PLAYBACK 0 - -#define AUDPP_MIXER_ICODEC AUDPP_CMD_CFG_DEV_MIXER_DEV_0 -#define AUDPP_MIXER_1 AUDPP_CMD_CFG_DEV_MIXER_DEV_1 -#define AUDPP_MIXER_2 AUDPP_CMD_CFG_DEV_MIXER_DEV_2 -#define AUDPP_MIXER_3 AUDPP_CMD_CFG_DEV_MIXER_DEV_3 -#define AUDPP_MIXER_HLB AUDPP_CMD_CFG_DEV_MIXER_DEV_4 -#define AUDPP_MIXER_NONHLB (AUDPP_CMD_CFG_DEV_MIXER_DEV_0 | \ - AUDPP_CMD_CFG_DEV_MIXER_DEV_1 | \ - AUDPP_CMD_CFG_DEV_MIXER_DEV_2 | \ - AUDPP_CMD_CFG_DEV_MIXER_DEV_3) -#define AUDPP_MIXER_UPLINK_RX AUDPP_CMD_CFG_DEV_MIXER_DEV_5 -#define AUDPP_MAX_COPP_DEVICES 6 - -enum obj_type { - COPP, - POPP -}; - -enum msm_aud_decoder_state { - MSM_AUD_DECODER_STATE_NONE = 0, - MSM_AUD_DECODER_STATE_FAILURE = 1, - MSM_AUD_DECODER_STATE_SUCCESS = 2, - MSM_AUD_DECODER_STATE_CLOSE = 3, -}; - -int audpp_adec_alloc(unsigned dec_attrb, const char **module_name, - unsigned *queueid); -void audpp_adec_free(int decid); - -struct audpp_event_callback { - audpp_event_func fn; - void *private; -}; - -int audpp_register_event_callback(struct audpp_event_callback *eh); -int audpp_unregister_event_callback(struct audpp_event_callback *eh); -int is_audpp_enable(void); - -int audpp_enable(int id, audpp_event_func func, void *private); -void audpp_disable(int id, void *private); - -int audpp_send_queue1(void *cmd, unsigned len); -int audpp_send_queue2(void *cmd, unsigned len); -int audpp_send_queue3(void *cmd, unsigned len); - -void audpp_route_stream(unsigned short dec_id, unsigned short mixer_mask); - -int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan, - enum obj_type objtype); -int audpp_pause(unsigned id, int pause); -int audpp_flush(unsigned id); -int audpp_query_avsync(int id); -int audpp_restore_avsync(int id, uint16_t *avsync); - -int audpp_dsp_set_eq(unsigned id, unsigned enable, - struct audpp_cmd_cfg_object_params_eqalizer *eq, - enum obj_type objtype); - -int audpp_dsp_set_spa(unsigned id, - struct audpp_cmd_cfg_object_params_spectram *spa, - enum obj_type objtype); - -int audpp_dsp_set_stf(unsigned id, unsigned enable, - struct audpp_cmd_cfg_object_params_sidechain *stf, - enum obj_type objtype); - -int audpp_dsp_set_vol_pan(unsigned id, - struct audpp_cmd_cfg_object_params_volume *vol_pan, - enum obj_type objtype); - -int audpp_dsp_set_mbadrc(unsigned id, unsigned enable, - struct audpp_cmd_cfg_object_params_mbadrc *mbadrc, - enum obj_type objtype); - -int audpp_dsp_set_qconcert_plus(unsigned id, unsigned enable, - struct audpp_cmd_cfg_object_params_qconcert *qconcert_plus, - enum obj_type objtype); - -int audpp_dsp_set_rx_iir(unsigned id, unsigned enable, - struct audpp_cmd_cfg_object_params_pcm *iir, - enum obj_type objtype); - -int audpp_dsp_set_gain_rx(unsigned id, - struct audpp_cmd_cfg_cal_gain *calib_gain_rx, - enum obj_type objtype); -int audpp_dsp_set_pbe(unsigned id, unsigned enable, - struct audpp_cmd_cfg_pbe *pbe_block, - enum obj_type objtype); -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/audpreproc.h b/arch/arm/mach-msm/include/mach/qdsp5v2/audpreproc.h deleted file mode 100644 index 16a0a8fb227df8501692bd156fe0fc7bcd519db4..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/audpreproc.h +++ /dev/null @@ -1,96 +0,0 @@ -/* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _MACH_QDSP5_V2_AUDPREPROC_H -#define _MACH_QDSP5_V2_AUDPREPROC_H - -#include -#include - -#define MAX_ENC_COUNT 3 - -#define MSM_ADSP_ENC_CODEC_WAV 0 -#define MSM_ADSP_ENC_CODEC_AAC 1 -#define MSM_ADSP_ENC_CODEC_SBC 2 -#define MSM_ADSP_ENC_CODEC_AMRNB 3 -#define MSM_ADSP_ENC_CODEC_EVRC 4 -#define MSM_ADSP_ENC_CODEC_QCELP 5 -#define MSM_ADSP_ENC_CODEC_EXT_WAV (15) - -#define MSM_ADSP_ENC_MODE_TUNNEL 24 -#define MSM_ADSP_ENC_MODE_NON_TUNNEL 25 - -#define AUDPREPROC_CODEC_MASK 0x00FF -#define AUDPREPROC_MODE_MASK 0xFF00 - -#define MSM_AUD_ENC_MODE_TUNNEL 0x00000100 -#define MSM_AUD_ENC_MODE_NONTUNNEL 0x00000200 - -#define SOURCE_PIPE_1 0x0001 -#define SOURCE_PIPE_0 0x0000 - -/* event callback routine prototype*/ -typedef void (*audpreproc_event_func)(void *private, unsigned id, void *msg); - -struct audpreproc_event_callback { - audpreproc_event_func fn; - void *private; -}; - -/*holds audrec information*/ -struct audrec_session_info { - int session_id; - int sampling_freq; -}; - -/* Exported common api's from audpreproc layer */ -int audpreproc_aenc_alloc(unsigned enc_type, const char **module_name, - unsigned *queue_id); -void audpreproc_aenc_free(int enc_id); - -int audpreproc_enable(int enc_id, audpreproc_event_func func, void *private); -void audpreproc_disable(int enc_id, void *private); - -int audpreproc_send_audreccmdqueue(void *cmd, unsigned len); - -int audpreproc_send_preproccmdqueue(void *cmd, unsigned len); - -int audpreproc_dsp_set_agc(struct audpreproc_cmd_cfg_agc_params *agc, - unsigned len); -int audpreproc_dsp_set_agc2(struct audpreproc_cmd_cfg_agc_params_2 *agc2, - unsigned len); -int audpreproc_dsp_set_ns(struct audpreproc_cmd_cfg_ns_params *ns, - unsigned len); -int audpreproc_dsp_set_iir( -struct audpreproc_cmd_cfg_iir_tuning_filter_params *iir, unsigned len); - -int audpreproc_dsp_set_agc(struct audpreproc_cmd_cfg_agc_params *agc, - unsigned int len); - -int audpreproc_dsp_set_iir( -struct audpreproc_cmd_cfg_iir_tuning_filter_params *iir, unsigned int len); - -int audpreproc_update_audrec_info(struct audrec_session_info - *audrec_session_info); -int audpreproc_unregister_event_callback(struct audpreproc_event_callback *ecb); - -int audpreproc_register_event_callback(struct audpreproc_event_callback *ecb); - -int audpreproc_dsp_set_gain_tx( - struct audpreproc_cmd_cfg_cal_gain *calib_gain_tx, unsigned len); - -void get_audrec_session_info(int id, struct audrec_session_info *info); - -int audpreproc_dsp_set_lvnv( - struct audpreproc_cmd_cfg_lvnv_param *preproc_lvnv, unsigned len); -#endif /* _MACH_QDSP5_V2_AUDPREPROC_H */ diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/aux_pcm.h b/arch/arm/mach-msm/include/mach/qdsp5v2/aux_pcm.h deleted file mode 100644 index d9b9427d11a8febc07c52323e9caa710a733860d..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/aux_pcm.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef __MACH_QDSP5_V2_AUX_PCM_H -#define __MACH_QDSP5_V2_AUX_PCM_H -#include - -/* define some values in AUX_CODEC_CTL register */ -#define AUX_CODEC_CTL__ADSP_CODEC_CTL_EN__MSM_V 0 /* default */ -#define AUX_CODEC_CTL__ADSP_CODEC_CTL_EN__ADSP_V 0x800 -#define AUX_CODEC_CTL__PCM_SYNC_LONG_OFFSET_V 0x400 -#define AUX_CODEC_CTL__PCM_SYNC_SHORT_OFFSET_V 0x200 -#define AUX_CODEC_CTL__I2S_SAMPLE_CLK_SRC__SDAC_V 0 -#define AUX_CODEC_CTL__I2S_SAMPLE_CLK_SRC__ICODEC_V 0x80 -#define AUX_CODEC_CTL__I2S_SAMPLE_CLK_MODE__MASTER_V 0 -#define AUX_CODEC_CTL__I2S_SAMPLE_CLK_MODE__SLAVE_V 0x40 -#define AUX_CODEC_CTL__I2S_RX_MODE__REV_V 0 -#define AUX_CODEC_CTL__I2S_RX_MODE__TRAN_V 0x20 -#define AUX_CODEC_CTL__I2S_CLK_MODE__MASTER_V 0 -#define AUX_CODEC_CTL__I2S_CLK_MODE__SLAVE_V 0x10 -#define AUX_CODEC_CTL__AUX_PCM_MODE__PRIM_MASTER_V 0 -#define AUX_CODEC_CTL__AUX_PCM_MODE__AUX_MASTER_V 0x4 -#define AUX_CODEC_CTL__AUX_PCM_MODE__PRIM_SLAVE_V 0x8 -#define AUX_CODEC_CTL__AUX_CODEC_MDOE__PCM_V 0 -#define AUX_CODEC_CTL__AUX_CODEC_MODE__I2S_V 0x2 - -/* define some values in PCM_PATH_CTL register */ -#define PCM_PATH_CTL__ADSP_CTL_EN__MSM_V 0 -#define PCM_PATH_CTL__ADSP_CTL_EN__ADSP_V 0x8 - -/* define some values for aux codec config of AFE*/ -/* PCM CTL */ -#define PCM_CTL__RPCM_WIDTH__LINEAR_V 0x1 -#define PCM_CTL__TPCM_WIDTH__LINEAR_V 0x2 -/* AUX_CODEC_INTF_CTL */ -#define AUX_CODEC_INTF_CTL__PCMINTF_DATA_EN_V 0x800 -/* DATA_FORMAT_PADDING_INFO */ -#define DATA_FORMAT_PADDING_INFO__RPCM_FORMAT_V 0x400 -#define DATA_FORMAT_PADDING_INFO__TPCM_FORMAT_V 0x2000 - -void aux_codec_adsp_codec_ctl_en(bool msm_adsp_en); -void aux_codec_pcm_path_ctl_en(bool msm_adsp_en); -int aux_pcm_gpios_request(void); -void aux_pcm_gpios_free(void); - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/codec_utils.h b/arch/arm/mach-msm/include/mach/qdsp5v2/codec_utils.h deleted file mode 100644 index f7804417a69daafe8ae3ff22d091da026055f38e..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/codec_utils.h +++ /dev/null @@ -1,139 +0,0 @@ -/* Copyright (c) 2010, 2012, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef CODEC_UTILS_H -#define CODEC_UTILS_H - -#include - -#define ADRV_STATUS_AIO_INTF 0x00000001 -#define ADRV_STATUS_OBUF_GIVEN 0x00000002 -#define ADRV_STATUS_IBUF_GIVEN 0x00000004 -#define ADRV_STATUS_FSYNC 0x00000008 - -#define PCM_BUFSZ_MIN 4800 /* Hold one stereo MP3 frame */ -#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most - but support 2 buffers currently */ -#define ROUTING_MODE_FTRT 1 -#define ROUTING_MODE_RT 2 -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 -#define AUDPP_DEC_STATUS_EOS 5 - -/* worst case delay of 3secs(3000ms) for AV Sync Query response */ -#define AVSYNC_EVENT_TIMEOUT 3000 - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; -}; -struct audio; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audio_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct codec_operations { - long (*ioctl)(struct file *, unsigned int, unsigned long); - void (*adec_params)(struct audio *); -}; - -struct audio { - spinlock_t dsp_lock; - - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - struct list_head out_queue; /* queue to retain output buffers */ - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - struct msm_adsp_module *audplay; - - /* configuration to use on next enable */ - uint32_t out_sample_rate; - uint32_t out_channel_mode; - uint32_t out_bits; /* bits per sample (used by PCM decoder) */ - - /* data allocated for various buffers */ - char *data; - int32_t phys; /* physical address of write buffer */ - - uint32_t drv_status; - int wflush; /* Write flush */ - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - int buf_refresh; - int teos; /* valid only if tunnel mode & no data left for decoder */ - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - int reserved; /* A byte is being reserved */ - char rsv_byte; /* Handle odd length user data */ - - const char *module_name; - unsigned queue_id; - uint16_t dec_id; - uint32_t read_ptr_offset; - int16_t source; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audio_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - /* AV sync Info */ - int avsync_flag; /* Flag to indicate feedback from DSP */ - wait_queue_head_t avsync_wait;/* Wait queue for AV Sync Message */ - /* flags, 48 bits sample/bytes counter per channel */ - uint16_t avsync[AUDPP_AVSYNC_CH_COUNT * AUDPP_AVSYNC_NUM_WORDS + 1]; - - uint32_t device_events; - uint32_t device_switch; /* Flag to indicate device switch */ - uint64_t bytecount_consumed; - uint64_t bytecount_head; - uint64_t bytecount_given; - uint64_t bytecount_query; - - struct list_head pmem_region_queue; /* protected by lock */ - - int eq_enable; - int eq_needs_commit; - struct audpp_cmd_cfg_object_params_eqalizer eq; - struct audpp_cmd_cfg_object_params_volume vol_pan; - - unsigned int minor_no; - struct codec_operations codec_ops; - uint32_t buffer_size; - uint32_t buffer_count; -}; - -#endif /* !CODEC_UTILS_H */ diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/lpa.h b/arch/arm/mach-msm/include/mach/qdsp5v2/lpa.h deleted file mode 100644 index d9d9ab1a548bb834ba5f5a1907a83009858fc8db..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/lpa.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef __MACH_QDSP5_V2_LPA_H__ -#define __MACH_QDSP5_V2_LPA_H__ - -#define LPA_OUTPUT_INTF_WB_CODEC 3 -#define LPA_OUTPUT_INTF_SDAC 1 -#define LPA_OUTPUT_INTF_MI2S 2 - -struct lpa_codec_config { - uint32_t sample_rate; - uint32_t sample_width; - uint32_t output_interface; - uint32_t num_channels; -}; - -struct lpa_drv; - -struct lpa_drv *lpa_get(void); -void lpa_put(struct lpa_drv *lpa); -int lpa_cmd_codec_config(struct lpa_drv *lpa, - struct lpa_codec_config *config_ptr); -int lpa_cmd_enable_codec(struct lpa_drv *lpa, bool enable); - -#endif - diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/lpa_hw.h b/arch/arm/mach-msm/include/mach/qdsp5v2/lpa_hw.h deleted file mode 100644 index beb4aeeab6a4f9da32ede2450e5a35bafd82a3d5..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/lpa_hw.h +++ /dev/null @@ -1,236 +0,0 @@ -/* Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef __MACH_QDSP5_V2_LPA_HW_H__ -#define __MACH_QDSP5_V2_LPA_HW_H__ - -#define LPA_MAX_BUF_SIZE 0x30000 - -/* LPA Output config registers */ -enum { - LPA_OBUF_CONTROL = 0x00000000, - LPA_OBUF_CODEC = 0x00000004, - LPA_OBUF_HLB_MIN_ADDR = 0x00000008, - LPA_OBUF_HLB_MAX_ADDR = 0x0000000C, - LPA_OBUF_HLB_WPTR = 0x00000010, - LPA_OBUF_HLB_VOLUME_CONTROL = 0x00000014, - LPA_OBUF_LLB_MIN_ADDR = 0x00000018, - LPA_OBUF_LLB_MAX_ADDR = 0x0000001C, - LPA_OBUF_SB_MIN_ADDR = 0x00000020, - LPA_OBUF_SB_MAX_ADDR = 0x00000024, - LPA_OBUF_INTR_ENABLE = 0x00000028, - LPA_OBUF_INTR_STATUS = 0x0000002C, - LPA_OBUF_WMARK_ASSIGN = 0x00000030, - LPA_OBUF_WMARK_0_LLB = 0x00000034, - LPA_OBUF_WMARK_1_LLB = 0x00000038, - LPA_OBUF_WMARK_2_LLB = 0x0000003C, - LPA_OBUF_WMARK_3_LLB = 0x00000040, - LPA_OBUF_WMARK_HLB = 0x00000044, - LPA_OBUF_WMARK_SB = 0x00000048, - LPA_OBUF_RDPTR_LLB = 0x0000004C, - LPA_OBUF_RDPTR_HLB = 0x00000050, - LPA_OBUF_WRPTR_SB = 0x00000054, - LPA_OBUF_UTC_CONFIG = 0x00000058, - LPA_OBUF_UTC_INTR_LOW = 0x0000005C, - LPA_OBUF_UTC_INTR_HIGH = 0x00000060, - LPA_OBUF_UTC_LOW = 0x00000064, - LPA_OBUF_UTC_HIGH = 0x00000068, - LPA_OBUF_MISR = 0x0000006C, - LPA_OBUF_STATUS = 0x00000070, - LPA_OBUF_ACK = 0x00000074, - LPA_OBUF_MEMORY_CONTROL = 0x00000078, - LPA_OBUF_MEMORY_STATUS = 0x0000007C, - LPA_OBUF_MEMORY_TIME_CONTROL = 0x00000080, - LPA_OBUF_ACC_LV = 0x00000084, - LPA_OBUF_ACC_HV = 0x0000008c, - LPA_OBUF_RESETS = 0x00000090, - LPA_OBUF_TESTBUS = 0x00000094, -}; - -/* OBUF_CODEC definition */ -#define LPA_OBUF_CODEC_RESERVED31_22_BMSK 0xffc00000 -#define LPA_OBUF_CODEC_RESERVED31_22_SHFT 0x16 -#define LPA_OBUF_CODEC_LOAD_BMSK 0x200000 -#define LPA_OBUF_CODEC_LOAD_SHFT 0x15 -#define LPA_OBUF_CODEC_CODEC_INTF_EN_BMSK 0x100000 -#define LPA_OBUF_CODEC_CODEC_INTF_EN_SHFT 0x14 -#define LPA_OBUF_CODEC_SAMP_BMSK 0xf0000 -#define LPA_OBUF_CODEC_SAMP_SHFT 0x10 -#define LPA_OBUF_CODEC_BITS_PER_CHAN_BMSK 0xc000 -#define LPA_OBUF_CODEC_BITS_PER_CHAN_SHFT 0xe -#define LPA_OBUF_CODEC_RESERVED_13_7_BMSK 0x3f80 -#define LPA_OBUF_CODEC_RESERVED_13_7_SHFT 0x7 -#define LPA_OBUF_CODEC_INTF_BMSK 0x70 -#define LPA_OBUF_CODEC_INTF_SHFT 0x4 -#define LPA_OBUF_CODEC_NUM_CHAN_BMSK 0xf -#define LPA_OBUF_CODEC_NUM_CHAN_SHFT 0 - -/* OBUF_CONTROL definition */ -#define LPA_OBUF_CONTROL_RESERVED31_9_BMSK 0xfffffe00 -#define LPA_OBUF_CONTROL_RESERVED31_9_SHFT 0x9 -#define LPA_OBUF_CONTROL_TEST_EN_BMSK 0x100 -#define LPA_OBUF_CONTROL_TEST_EN_SHFT 0x8 -#define LPA_OBUF_CONTROL_LLB_CLR_CMD_BMSK 0x80 -#define LPA_OBUF_CONTROL_LLB_CLR_CMD_SHFT 0x7 -#define LPA_OBUF_CONTROL_SB_SAT_EN_BMSK 0x40 -#define LPA_OBUF_CONTROL_SB_SAT_EN_SHFT 0x6 -#define LPA_OBUF_CONTROL_LLB_SAT_EN_BMSK 0x20 -#define LPA_OBUF_CONTROL_LLB_SAT_EN_SHFT 0x5 -#define LPA_OBUF_CONTROL_RESERVED4_BMSK 0x10 -#define LPA_OBUF_CONTROL_RESERVED4_SHFT 0x4 -#define LPA_OBUF_CONTROL_LLB_ACC_EN_BMSK 0x8 -#define LPA_OBUF_CONTROL_LLB_ACC_EN_SHFT 0x3 -#define LPA_OBUF_CONTROL_HLB_EN_BMSK 0x4 -#define LPA_OBUF_CONTROL_HLB_EN_SHFT 0x2 -#define LPA_OBUF_CONTROL_LLB_EN_BMSK 0x2 -#define LPA_OBUF_CONTROL_LLB_EN_SHFT 0x1 -#define LPA_OBUF_CONTROL_SB_EN_BMSK 0x1 -#define LPA_OBUF_CONTROL_SB_EN_SHFT 0 - -/* OBUF_RESET definition */ -#define LPA_OBUF_RESETS_MISR_RESET 0x1 -#define LPA_OBUF_RESETS_OVERALL_RESET 0x2 - -/* OBUF_STATUS definition */ -#define LPA_OBUF_STATUS_RESET_DONE 0x80000 -#define LPA_OBUF_STATUS_LLB_CLR_BMSK 0x40000 -#define LPA_OBUF_STATUS_LLB_CLR_SHFT 0x12 - -/* OBUF_HLB_MIN_ADDR definition */ -#define LPA_OBUF_HLB_MIN_ADDR_LOAD_BMSK 0x40000 -#define LPA_OBUF_HLB_MIN_ADDR_SEG_BMSK 0x3e000 - -/* OBUF_HLB_MAX_ADDR definition */ -#define LPA_OBUF_HLB_MAX_ADDR_SEG_BMSK 0x3fff8 - -/* OBUF_LLB_MIN_ADDR definition */ -#define LPA_OBUF_LLB_MIN_ADDR_LOAD_BMSK 0x40000 -#define LPA_OBUF_LLB_MIN_ADDR_SEG_BMSK 0x3e000 - -/* OBUF_LLB_MAX_ADDR definition */ -#define LPA_OBUF_LLB_MAX_ADDR_SEG_BMSK 0x3ff8 -#define LPA_OBUF_LLB_MAX_ADDR_SEG_SHFT 0x3 - -/* OBUF_SB_MIN_ADDR definition */ -#define LPA_OBUF_SB_MIN_ADDR_LOAD_BMSK 0x4000 -#define LPA_OBUF_SB_MIN_ADDR_SEG_BMSK 0x3e00 - -/* OBUF_SB_MAX_ADDR definition */ -#define LPA_OBUF_SB_MAX_ADDR_SEG_BMSK 0x3ff8 - -/* OBUF_MEMORY_CONTROL definition */ -#define LPA_OBUF_MEM_CTL_PWRUP_BMSK 0xfff -#define LPA_OBUF_MEM_CTL_PWRUP_SHFT 0x0 - -/* OBUF_INTR_ENABLE definition */ -#define LPA_OBUF_INTR_EN_BMSK 0x3 - -/* OBUF_WMARK_ASSIGN definition */ -#define LPA_OBUF_WMARK_ASSIGN_BMSK 0xF -#define LPA_OBUF_WMARK_ASSIGN_DONE 0xF - -/* OBUF_WMARK_n_LLB definition */ -#define LPA_OBUF_WMARK_n_LLB_ADDR(n) (0x00000034 + 0x4 * (n)) -#define LPA_OBUF_LLB_WMARK_CTRL_BMSK 0xc0000 -#define LPA_OBUF_LLB_WMARK_CTRL_SHFT 0x12 -#define LPA_OBUF_LLB_WMARK_MAP_BMSK 0xf00000 -#define LPA_OBUF_LLB_WMARK_MAP_SHFT 0x14 - -/* OBUF_WMARK_SB definition */ -#define LPA_OBUF_SB_WMARK_CTRL_BMSK 0xc0000 -#define LPA_OBUF_SB_WMARK_CTRL_SHFT 0x12 -#define LPA_OBUF_SB_WMARK_MAP_BMSK 0xf00000 -#define LPA_OBUF_SB_WMARK_MAP_SHFT 0x14 - -/* OBUF_WMARK_HLB definition */ -#define LPA_OBUF_HLB_WMARK_CTRL_BMSK 0xc0000 -#define LPA_OBUF_HLB_WMARK_CTRL_SHFT 0x12 -#define LPA_OBUF_HLB_WMARK_MAP_BMSK 0xf00000 -#define LPA_OBUF_HLB_WMARK_MAP_SHFT 0x14 - -/* OBUF_UTC_CONFIG definition */ -#define LPA_OBUF_UTC_CONFIG_MAP_BMSK 0xf0 -#define LPA_OBUF_UTC_CONFIG_MAP_SHFT 0x4 -#define LPA_OBUF_UTC_CONFIG_EN_BMSK 0x1 -#define LPA_OBUF_UTC_CONFIG_EN_SHFT 0 -#define LPA_OBUF_UTC_CONFIG_NO_INTR 0xF - -/* OBUF_ACK definition */ -#define LPA_OBUF_ACK_RESET_DONE_BMSK 0x80000 -#define LPA_OBUF_ACK_RESET_DONE_SHFT 0x13 -enum { - LPA_SAMPLE_RATE_8KHZ = 0x0000, - LPA_SAMPLE_RATE_11P025KHZ = 0x0001, - LPA_SAMPLE_RATE_16KHZ = 0x0002, - LPA_SAMPLE_RATE_22P05KHZ = 0x0003, - LPA_SAMPLE_RATE_32KHZ = 0x0004, - LPA_SAMPLE_RATE_44P1KHZ = 0x0005, - LPA_SAMPLE_RATE_48KHZ = 0x0006, - LPA_SAMPLE_RATE_64KHZ = 0x0007, - LPA_SAMPLE_RATE_96KHZ = 0x0008, -}; - -enum { - LPA_BITS_PER_CHAN_16BITS = 0x0000, - LPA_BITS_PER_CHAN_24BITS = 0x0001, - LPA_BITS_PER_CHAN_32BITS = 0x0002, - LPA_BITS_PER_CHAN_RESERVED = 0x0003, -}; - -enum { - LPA_INTF_WB_CODEC = 0x0000, - LPA_INTF_SDAC = 0x0001, - LPA_INTF_MI2S = 0x0002, - LPA_INTF_RESERVED = 0x0003, -}; - -enum { - LPA_BUF_ID_HLB, /* HLB buffer */ - LPA_BUF_ID_LLB, /* LLB buffer */ - LPA_BUF_ID_SB, /* SB buffer */ - LPA_BUF_ID_UTC, -}; - -/* WB_CODEC & SDAC can only support 16bit mono/stereo. - * MI2S can bit format and number of channel - */ -enum { - LPA_NUM_CHAN_MONO = 0x0000, - LPA_NUM_CHAN_STEREO = 0x0001, - LPA_NUM_CHAN_5P1 = 0x0002, - LPA_NUM_CHAN_7P1 = 0x0003, - LPA_NUM_CHAN_4_CHANNEL = 0x0004, -}; - -enum { - LPA_WMARK_CTL_DISABLED = 0x0, - LPA_WMARK_CTL_NON_BLOCK = 0x1, - LPA_WMARK_CTL_ZERO_INSERT = 0x2, - LPA_WMARK_CTL_RESERVED = 0x3 -}; - -struct lpa_mem_bank_select { - u32 b0:1; /*RAM bank 0 16KB=2Kx64(0) */ - u32 b1:1; /*RAM bank 1 16KB=2Kx64(0) */ - u32 b2:1; /*RAM bank 2 16KB=2Kx64(0) */ - u32 b3:1; /*RAM bank 3 16KB=2Kx64(0) */ - u32 b4:1; /*RAM bank 4 16KB=2Kx64(1) */ - u32 b5:1; /*RAM bank 5 16KB=2Kx64(1) */ - u32 b6:1; /*RAM bank 6 16KB=2Kx64(1) */ - u32 b7:1; /*RAM bank 7 16KB=2Kx64(1) */ - u32 b8:1; /*RAM bank 8 16KB=4Kx32(0) */ - u32 b9:1; /*RAM bank 9 16KB=4Kx32(1) */ - u32 b10:1; /*RAM bank 10 16KB=4Kx32(2) */ - u32 llb:1; /*RAM bank 11 16KB=4Kx32(3) */ -}; - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/marimba_profile.h b/arch/arm/mach-msm/include/mach/qdsp5v2/marimba_profile.h deleted file mode 100644 index 7e455a13ac716e0a2fee8e19df13bdf983aafd63..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/marimba_profile.h +++ /dev/null @@ -1,3201 +0,0 @@ -/* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef __MACH_QDSP5_V2_MARIMBA_PROFILE_H__ -#define __MACH_QDSP5_V2_MARIMBA_PROFILE_H__ - -/***************************************************************************\ - Handset -\***************************************************************************/ - - -#define HANDSET_RX_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x44)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xff, 0x8C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x4E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x36, 0xc0, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3d, 0xFF, 0xD5)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x21, 0x21)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x2710}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x40)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x05, 0x04)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x36, 0xc0, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HANDSET_RX_16000_OSR_256 HANDSET_RX_8000_OSR_256 - -#define HANDSET_RX_48000_OSR_64\ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x47)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xfF, 0x8C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x42)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x36, 0xc0, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3d, 0xFF, 0xD5)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x21, 0x21)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x2710}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x40)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x05, 0x04)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x36, 0xc0, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HANDSET_RX_48000_OSR_256\ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x44)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xfF, 0x8C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x4e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x36, 0xc0, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3d, 0xFF, 0x55)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x21, 0x21)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x2710}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x40)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x05, 0x04)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x36, 0xc0, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HANDSET_TX_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x13, 0xfc, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xff, 0x65)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x15, 0xff, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xff, 0x5E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x10, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xF0, 0xd0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x14)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8b, 0xff, 0xE6)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8c, 0x03, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x50, 0x40)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x10, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HANDSET_TX_16000_OSR_256 HANDSET_TX_8000_OSR_256 - -#define HANDSET_TX_48000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x13, 0xfc, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xff, 0x65)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x15, 0xff, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xff, 0x5A)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x10, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xF0, 0xd0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x14)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8b, 0xff, 0xE6)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8c, 0x03, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x50, 0x40)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x10, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -/***************************************************************************\ - Headset -\***************************************************************************/ - - - -#define HEADSET_STEREO_TX_8000_OSR_256\ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x13, 0xfc, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xfd, 0x65)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x15, 0xff, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xFF, 0x5E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x10, 0xFF, 0x64)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0E, 0xE8, 0xE8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xF0, 0xD0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x1c, 0x1c)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8b, 0xff, 0xE7)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8c, 0x03, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x87, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xF0)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0e, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0d, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x1c, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_STEREO_TX_16000_OSR_256 HEADSET_STEREO_TX_8000_OSR_256 - -#define HEADSET_STEREO_TX_48000_OSR_64\ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x13, 0xfc, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xfd, 0x65)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x15, 0xfc, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xFF, 0x46)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x10, 0xFF, 0x64)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0E, 0xE8, 0xE8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xF0, 0xD0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x1c, 0x1c)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8b, 0xff, 0xE7)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8c, 0x03, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x87, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xF0)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0e, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0d, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x1c, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_STEREO_TX_48000_OSR_256\ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FALSH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x13, 0xfc, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xfd, 0x65)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x15, 0xfc, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xff, 0x5A)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x10, 0xFF, 0x64)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0E, 0xE8, 0xE8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xF0, 0xD0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x1c, 0x1c)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8b, 0xff, 0xE7)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8c, 0x03, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x87, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xF0)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0e, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0d, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x1c, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_MONO_TX_16000_OSR_256\ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x13, 0xfc, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xff, 0x65)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x15, 0xfc, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xFF, 0x5E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x10, 0xFF, 0x64)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xFf, 0xc8)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x14)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8b, 0xff, 0xE7)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8c, 0x03, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x50, 0x40)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x10, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_MONO_TX_8000_OSR_256 HEADSET_MONO_TX_16000_OSR_256 - -#define HEADSET_MONO_TX_48000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x13, 0xfc, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xff, 0x65)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x15, 0xff, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xff, 0x5A)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x10, 0xFF, 0x64)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xFF, 0xC8)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x14)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8b, 0xff, 0xE7)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8c, 0x03, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x50, 0x40)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x10, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_RX_CAPLESS_8000_OSR_256\ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x4E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xff, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xff, 0xa2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0xeb)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xf0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_RX_CAPLESS_48000_OSR_64 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x42)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xff, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x67)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xff, 0xa2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0xab)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xf0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_RX_CAPLESS_48000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x4e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xff, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xff, 0xa2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0xab)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xf0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - - -#define HEADSET_RX_LEGACY_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x4E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xff, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xff, 0xa0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xa0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xf0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_RX_LEGACY_16000_OSR_256 HEADSET_RX_LEGACY_8000_OSR_256 - -#define HEADSET_RX_LEGACY_48000_OSR_64 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x42)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xff, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x67)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xff, 0xa0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xa0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xf0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - - -#define HEADSET_RX_LEGACY_48000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x4e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xff, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xff, 0xa0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xa0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xf0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_RX_CLASS_D_LEGACY_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xf8, 0xA8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x28, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x29, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x50, 0x50)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x40, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x41, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x42, 0xFF, 0xFF)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x43, 0xFF, 0xc4)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x44, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0xDD)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3F, 0xFF, 0x0f)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x45, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x46, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x47, 0xFF, 0xc4)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x48, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x49, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4a, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0a, 0x0a)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0f, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - - -#define HEADSET_RX_CLASS_D_LEGACY_11025_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xf8, 0xA8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x28, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x29, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x50, 0x50)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x40, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x41, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x42, 0xFF, 0xbb)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x43, 0xFF, 0xc2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x44, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0xDD)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3F, 0xFF, 0x0f)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x45, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x46, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x47, 0xFF, 0xc2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x48, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x49, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4a, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0a, 0x0a)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0f, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - - -#define HEADSET_RX_CLASS_D_LEGACY_16000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xf8, 0xA8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x28, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x29, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x50, 0x50)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x40, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x41, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x42, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x43, 0xFF, 0xd4)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x44, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0xDD)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3F, 0xFF, 0x0f)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x45, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x46, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x47, 0xFF, 0xd4)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x48, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x49, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4a, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0a, 0x0a)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0f, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - - -#define HEADSET_RX_CLASS_D_LEGACY_22050_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xf8, 0xA8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x28, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x29, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x50, 0x50)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x40, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x41, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x42, 0xFF, 0xbb)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x43, 0xFF, 0xd2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x44, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0xDD)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3F, 0xFF, 0x0f)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x45, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x46, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x47, 0xFF, 0xd2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x48, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x49, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4a, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0a, 0x0a)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0f, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - - -#define HEADSET_CLASS_D_LEGACY_32000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xf8, 0xA8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x28, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x29, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x50, 0x50)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x40, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x41, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x42, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x43, 0xFF, 0xf4)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x44, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0xDD)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3F, 0xFF, 0x0f)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x45, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x46, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x47, 0xFF, 0xf4)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x48, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x49, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4a, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0a, 0x0a)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0f, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_RX_CLASS_D_LEGACY_48000_OSR_64 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xf8, 0xA8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x28, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x29, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x50, 0x50)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x40, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x41, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x42, 0xFF, 0x55)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x43, 0xFF, 0xc5)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x44, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0xDD)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3F, 0xFF, 0x0f)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x45, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x46, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x47, 0xFF, 0xc2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x48, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x49, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4a, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0a, 0x0a)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0f, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_RX_CLASS_D_LEGACY_48000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xf8, 0xA8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x28, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x29, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x50, 0x50)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x40, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x41, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x42, 0xFF, 0xBB)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x43, 0xFF, 0xF2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x44, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0xDD)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3F, 0xFF, 0x0f)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x45, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x46, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x47, 0xFF, 0xF2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x48, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x49, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4a, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0a, 0x0a)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0f, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_STEREO_RX_CAPLESS_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x4E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xff, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xff, 0x82)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0xeb)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xf0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_STEREO_RX_CAPLESS_48000_OSR_64 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x42)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xff, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x67)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xff, 0x82)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0xab)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xf0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - - - -#define HEADSET_STEREO_RX_CAPLESS_48000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x4e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xff, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xff, 0x82)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0xab)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x82)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xf0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_STEREO_RX_LEGACY_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x4E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xff, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xff, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xa0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xf0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFF, 0xaC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xaC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_STEREO_RX_LEGACY_48000_OSR_64 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x42)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xff, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x67)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xff, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xa0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xf0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_STEREO_RX_LEGACY_48000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x4e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xff, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xff, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xa0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xf0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_STEREO_RX_CLASS_D_LEGACY_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xf8, 0xA8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x28, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x29, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x40, 0x40)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x40, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x41, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x42, 0xFF, 0xFF)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x43, 0xFF, 0xc4)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x44, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0xDD)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3F, 0xFF, 0x0f)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x45, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x46, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x47, 0xFF, 0xc4)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x48, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x49, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4a, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0a, 0x0a)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0f, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - - -#define HEADSET_STEREO_RX_CLASS_D_LEGACY_11025_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xf8, 0xA8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x28, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x29, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x40, 0x40)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x40, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x41, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x42, 0xFF, 0xbb)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x43, 0xFF, 0xc2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x44, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0xDD)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3F, 0xFF, 0x0f)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x45, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x46, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x47, 0xFF, 0xc2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x48, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x49, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4a, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0a, 0x0a)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0f, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_STEREO_RX_CLASS_D_LEGACY_16000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xf8, 0xA8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x28, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x29, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x40, 0x40)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x40, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x41, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x42, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x43, 0xFF, 0xd4)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x44, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0xDD)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3F, 0xFF, 0x0f)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x45, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x46, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x47, 0xFF, 0xd4)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x48, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x49, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4a, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0a, 0x0a)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0f, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - - -#define HEADSET_STEREO_RX_CLASS_D_LEGACY_22050_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xf8, 0xA8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x28, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x29, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x40, 0x40)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x40, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x41, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x42, 0xFF, 0xbb)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x43, 0xFF, 0xd2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x44, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0xDD)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3F, 0xFF, 0x0f)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x45, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x46, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x47, 0xFF, 0xd2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x48, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x49, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4a, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0a, 0x0a)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0f, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - - -#define HEADSET_STEREO_RX_CLASS_D_LEGACY_32000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xf8, 0xA8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x28, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x29, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x40, 0x40)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x40, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x41, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x42, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x43, 0xFF, 0xf4)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x44, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0xDD)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3F, 0xFF, 0x0f)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x45, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x46, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x47, 0xFF, 0xf4)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x48, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x49, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4a, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0a, 0x0a)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0f, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_STEREO_RX_CLASS_D_LEGACY_48000_OSR_64 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xf8, 0xA8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x28, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x29, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x40, 0x40)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x40, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x41, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x42, 0xFF, 0x55)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x43, 0xFF, 0xc5)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x44, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0xDD)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3F, 0xFF, 0x0f)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x45, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x46, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x47, 0xFF, 0xc2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x48, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x49, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4a, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0a, 0x0a)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0f, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_STEREO_RX_CLASS_D_LEGACY_48000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xf8, 0xA8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x28, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x29, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x40, 0x40)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x40, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x41, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x42, 0xFF, 0xBB)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x43, 0xFF, 0xF2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x44, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0xDD)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3F, 0xFF, 0x0f)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x45, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x46, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x47, 0xFF, 0xF2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x48, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x49, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4a, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0a, 0x0a)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0f, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define SPEAKER_RX_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x4E)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x37, 0xe2, 0xa2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3d, 0xFF, 0x55)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x8a, 0x8a)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x7530}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x05, 0x04)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x7530}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - - -#define SPEAKER_RX_48000_OSR_64 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x42)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x67)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x37, 0xe2, 0xa2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3d, 0xFF, 0x55)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x8a, 0x8a)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x7530}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x05, 0x04)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x7530}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define SPEAKER_RX_48000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x37, 0xe2, 0xa2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3d, 0xFF, 0x55)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x8a, 0x8a)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x7530}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x05, 0x04)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x7530}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define SPEAKER_STEREO_RX_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x4E)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x37, 0xe6, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3d, 0xFF, 0x55)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x8a, 0x8a)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x7530}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x0f, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x7530}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - - -#define SPEAKER_STEREO_RX_48000_OSR_64 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x42)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x67)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x37, 0xe6, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3d, 0xFF, 0x55)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x8a, 0x8a)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x7530}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x0f, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x7530}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define SPEAKER_STEREO_RX_48000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x37, 0xe6, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3d, 0xFF, 0x55)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x8a, 0x8a)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x7530}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x0f, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x7530}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - - -#define SPEAKER_TX_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x13, 0xfc, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xff, 0x65)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x15, 0xff, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xff, 0x5E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x10, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xF0, 0xD0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x14)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8c, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x50, 0x40)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x10, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define SPEAKER_TX_48000_OSR_64 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x13, 0xfc, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xff, 0x65)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x15, 0xff, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xff, 0x46)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x10, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xF0, 0xD0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x14)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8c, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x50, 0x40)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x10, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - - -#define SPEAKER_TX_48000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x13, 0xfc, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xff, 0x65)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x15, 0xff, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xff, 0x5A)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x10, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xF0, 0xD0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x14)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8c, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x50, 0x40)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x10, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define FM_HANDSET_OSR_64 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x47)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xff, 0x8C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x92)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x36, 0xc0, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3d, 0xFF, 0xD5)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x2710}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x40)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x05, 0x04)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x36, 0xc0, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define FM_HEADSET_STEREO_CLASS_D_LEGACY_OSR_64 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x92)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xf8, 0xA8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x28, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x29, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x40, 0x40)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x40, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x41, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x42, 0xFF, 0x55)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x43, 0xFF, 0xD5)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x44, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0xDD)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3F, 0xFF, 0x0f)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x45, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x46, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x47, 0xFF, 0xD5)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x48, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x49, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4a, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0a, 0x0a)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0f, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define FM_HEADSET_CLASS_AB_STEREO_LEGACY_OSR_64 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x92)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xff, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x67)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xff, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xa0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xf0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define FM_HEADSET_CLASS_AB_STEREO_CAPLESS_OSR_64 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x92)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xff, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x67)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xff, 0x82)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0xeb)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xf0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define FM_SPEAKER_OSR_64 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x92)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x67)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x37, 0xe2, 0xa2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3d, 0xFF, 0x55)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x8a, 0x8a)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x2710}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x05, 0x04)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - - -#define AUXPGA_HEADSET_STEREO_RX_LEGACY \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2B, 0xff, 0x09)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2C, 0xff, 0x09)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2B, 0xff, 0x89)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2C, 0xff, 0x89)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xff, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xa0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xf0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0x10)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0x18, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x40, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define AUXPGA_HEADSET_MONO_RX_LEGACY \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2B, 0xff, 0x09)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2C, 0xff, 0x09)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2B, 0xff, 0x89)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2C, 0xff, 0x89)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xff, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xa0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xf0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0x10)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0x18, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x40, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define AUXPGA_HEADSET_STEREO_RX_CAPLESS \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0xeb)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2B, 0xff, 0x89)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2C, 0xff, 0x89)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xff, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xa0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xf0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0x18, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x40, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define AUXPGA_HEADSET_MONO_RX_CAPLESS \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2B, 0xff, 0x09)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2C, 0xff, 0x09)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0xeb)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2B, 0xff, 0x89)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2C, 0xff, 0x89)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xff, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xa0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xf0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0x18, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x40, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define AUXPGA_HEADSET_STEREO_RX_CLASS_D \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2B, 0xff, 0x09)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2C, 0xff, 0x09)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2B, 0xff, 0x89)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2C, 0xff, 0x89)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x20, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x40, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x41, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x42, 0xFF, 0x55)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x43, 0xFF, 0xD5)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x44, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0xDD)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3F, 0xFF, 0x0f)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x45, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x46, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x47, 0xFF, 0xD5)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x48, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x49, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4a, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0a, 0x0a)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFC, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0x04)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x20, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - - -#define AUXPGA_HEADSET_MONO_RX_CLASS_D \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2B, 0xff, 0x09)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2C, 0xff, 0x09)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2B, 0xff, 0x89)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2C, 0xff, 0x89)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x40, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x41, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x42, 0xFF, 0x55)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x43, 0xFF, 0xD5)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x44, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0xDD)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3F, 0xFF, 0x0f)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x45, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x46, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x47, 0xFF, 0xD5)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x48, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x49, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4a, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0a, 0x0a)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFC, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0x04)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x20, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define AUXPGA_EAR \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2B, 0xff, 0x09)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2C, 0xff, 0x09)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2B, 0xff, 0x89)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2C, 0xff, 0x89)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x36, 0x20, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x2710}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x40)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x36, 0x20, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - - -/***************************************************************************\ - DigitalMicprofile -\***************************************************************************/ -#define DIGITAL_MIC \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xfd, 0x65)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x1A, 0xff, 0xc0)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xFF, 0x66)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x1c, 0x1c)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x87, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xF0)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x1c, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -/***************************************************************************\ - DualMicprofile -\***************************************************************************/ -#define SPEAKER_MIC1_LEFT_LINE_IN_RIGHT_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x13, 0xfc, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xfd, 0x65)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x15, 0xff, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xFF, 0x5E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x10, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0E, 0xE2, 0xE2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xF0, 0xD0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x1c, 0x1c)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8c, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x87, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xc0)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0e, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0d, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x1c, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define SPEAKER_MIC1_LEFT_AUX_IN_RIGHT_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x13, 0xfc, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xfd, 0x65)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x15, 0xff, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xFF, 0x5E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x10, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0E, 0xE2, 0xE1)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xF0, 0xD0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x1c, 0x1c)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8c, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x87, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xc0)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0e, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0d, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x1c, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define MIC1_LEFT_LINE_IN_RIGHT_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x13, 0xfc, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xfd, 0x65)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x15, 0xff, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xFF, 0x5E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x10, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0E, 0xE2, 0xE2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xF0, 0xD0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x1c, 0x1c)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8b, 0xff, 0xCE)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8c, 0x03, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x87, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xc0)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0e, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0d, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x1c, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define MIC1_LEFT_AUX_IN_RIGHT_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x13, 0xfc, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xfd, 0x65)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x15, 0xff, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xFF, 0x5E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x10, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0E, 0xE1, 0xE1)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xF0, 0xD0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x1c, 0x1c)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8b, 0xff, 0xCE)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8c, 0x03, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x87, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xc0)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0e, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0d, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x1c, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - - -/***************************************************************************\ - AnalogDualMicProfile -\***************************************************************************/ -#define ANALOG_DUAL_MIC \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x13, 0xfc, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xfd, 0x65)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x15, 0xff, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xFF, 0x5E)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0E, 0xE2, 0xE2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xF0, 0xD0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x1c, 0x1c)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x87, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xF0)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0e, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0d, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x1c, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } -/***************************************************************************\ - TTY -\***************************************************************************/ -#define TTY_HEADSET_MONO_TX_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x13, 0xfc, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xff, 0x65)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x15, 0xfc, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xFF, 0x5E)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xFf, 0xA8)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x14)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8c, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xff, 0x0A)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x50, 0x40)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x10, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define TTY_HEADSET_MONO_TX_16000_OSR_256 TTY_HEADSET_MONO_TX_8000_OSR_256 - -#define TTY_HEADSET_MONO_RX_CLASS_D_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xf8, 0xA8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x28, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x29, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x40, 0x40)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x40, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x41, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x42, 0xFF, 0xFF)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x43, 0xFF, 0xc4)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x44, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0xD5)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3F, 0xFF, 0x0f)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x45, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x46, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x47, 0xFF, 0xc4)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x48, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x49, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4a, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0a, 0x0a)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0xF4)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0f, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define TTY_HEADSET_MONO_RX_CLASS_D_16000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xf8, 0xA8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x28, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x29, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x40, 0x40)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x40, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x41, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x42, 0xFF, 0xFF)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x43, 0xFF, 0xd4)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x44, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0xD5)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3F, 0xFF, 0x0f)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x45, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x46, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x47, 0xFF, 0xd4)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x48, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x49, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4a, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0a, 0x0a)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0xF4)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0f, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define TTY_HEADSET_MONO_RX_CLASS_D_48000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xf8, 0xA8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x28, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x29, 0xfF, 0xCA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x40, 0x40)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x40, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x41, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x42, 0xFF, 0xBB)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x43, 0xFF, 0xF2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x44, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0xD5)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3F, 0xFF, 0x0f)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x45, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x46, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x47, 0xFF, 0xF2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x48, 0xFF, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x49, 0xFF, 0xff)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4a, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0a, 0x0a)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x05, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x3E8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0xF4)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0x0f, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -/***************************************************************************\ - FFA -\***************************************************************************/ -#define HANDSET_RX_8000_OSR_256_FFA \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x44)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xff, 0x8C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x4E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x36, 0xc0, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3d, 0xFF, 0xD5)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x21, 0x21)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x2710}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x40)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x05, 0x04)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x36, 0xc0, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HANDSET_RX_16000_OSR_256_FFA HANDSET_RX_8000_OSR_256_FFA - -#define HANDSET_RX_48000_OSR_64_FFA \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x47)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xfF, 0x8C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x42)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x36, 0xc0, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3d, 0xFF, 0xD5)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x21, 0x21)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x2710}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x40)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x05, 0x04)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x36, 0xc0, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HANDSET_RX_48000_OSR_256_FFA \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x44)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xfF, 0x8C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x4e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x36, 0xc0, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3d, 0xFF, 0x55)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x21, 0x21)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x2710}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x40)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x05, 0x04)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x36, 0xc0, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x40, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HANDSET_TX_8000_OSR_256_FFA \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x13, 0xfc, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xff, 0x65)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x15, 0xff, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xff, 0x5E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x10, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xF0, 0xd0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x14)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8b, 0xff, 0xCE)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8c, 0x03, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x50, 0x40)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x10, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HANDSET_TX_16000_OSR_256_FFA HANDSET_TX_8000_OSR_256_FFA - -#define HANDSET_TX_48000_OSR_256_FFA \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x13, 0xfc, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xff, 0x65)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x15, 0xff, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xff, 0x5A)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x10, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xF0, 0xd0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x14)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8b, 0xff, 0xCE)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8c, 0x03, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x50, 0x40)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x10, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_STEREO_SPEAKER_STEREO_RX_CAPLESS_48000_OSR_256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_FLASH_IMAGE}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xac)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x4E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xff, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xff, 0x82)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x37, 0xe6, 0xa0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0x2b)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x23, 0x23)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x8A, 0x8A)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xa0)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x7530}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xf0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x98)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x88)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x78)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x68)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x58)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x48)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x38)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x28)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x18)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFF, 0xaC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0xaC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x7530}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } -#endif /* __MARIMBA_PROFILE_H__ */ - - - - diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/mi2s.h b/arch/arm/mach-msm/include/mach/qdsp5v2/mi2s.h deleted file mode 100644 index 2106bfcb00f16a72ca921b901ad0f6592c99b069..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/mi2s.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef _MACH_QDSP5_V2_MI2S_H -#define _MACH_QDSP5_V2_MI2S_H - -#define WT_16_BIT 0 -#define WT_24_BIT 1 -#define WT_32_BIT 2 -#define WT_MAX 4 - -enum mi2s_ret_enum_type { - MI2S_FALSE = 0, - MI2S_TRUE -}; - -#define MI2S_CHAN_MONO_RAW 0 -#define MI2S_CHAN_MONO_PACKED 1 -#define MI2S_CHAN_STEREO 2 -#define MI2S_CHAN_4CHANNELS 3 -#define MI2S_CHAN_6CHANNELS 4 -#define MI2S_CHAN_8CHANNELS 5 -#define MI2S_CHAN_MAX_OUTBOUND_CHANNELS MI2S__CHAN_8CHANNELS - -#define MI2S_SD_0 0x01 -#define MI2S_SD_1 0x02 -#define MI2S_SD_2 0x04 -#define MI2S_SD_3 0x08 - -#define MI2S_SD_LINE_MASK (MI2S_SD_0 | MI2S_SD_1 | MI2S_SD_2 | MI2S_SD_3) - -bool mi2s_set_hdmi_output_path(uint8_t channels, uint8_t size, - uint8_t sd_line); - -bool mi2s_set_hdmi_input_path(uint8_t channels, uint8_t size, uint8_t sd_line); - -bool mi2s_set_codec_output_path(uint8_t channels, uint8_t size); - -bool mi2s_set_codec_input_path(uint8_t channels, uint8_t size); - -#endif /* #ifndef MI2S_H */ diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/mp3_funcs.h b/arch/arm/mach-msm/include/mach/qdsp5v2/mp3_funcs.h deleted file mode 100644 index b3f7c54486ad70fb7c6483c89a8bbf545d510765..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/mp3_funcs.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (c) 2010, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef MP3_FUNCS_H -#define MP3_FUNCS_H - -/* Function Prototypes */ -long mp3_ioctl(struct file *file, unsigned int cmd, unsigned long arg); -void audpp_cmd_cfg_mp3_params(struct audio *audio); - -#endif /* !MP3_FUNCS_H */ diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/msm_lpa.h b/arch/arm/mach-msm/include/mach/qdsp5v2/msm_lpa.h deleted file mode 100644 index cdfa19b258c5d74f0e0a0e88a6a28f30041f8a37..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/msm_lpa.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef _MACH_QDSP5_V2_MSM_LPA_H -#define _MACH_QDSP5_V2_MSM_LPA_H - -struct lpa_mem_config { - u32 llb_min_addr; - u32 llb_max_addr; - u32 sb_min_addr; - u32 sb_max_addr; -}; - -struct msm_lpa_platform_data { - u32 obuf_hlb_size; - u32 dsp_proc_id; - u32 app_proc_id; - struct lpa_mem_config nosb_config; /* no summing */ - struct lpa_mem_config sb_config; /* summing required */ -}; - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/pcm_funcs.h b/arch/arm/mach-msm/include/mach/qdsp5v2/pcm_funcs.h deleted file mode 100644 index b8fe2ba20c3d4f21cacd94b146aadfa3dca4923f..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/pcm_funcs.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (c) 2010, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef PCM_FUNCS_H -#define PCM_FUNCS_H - -long pcm_ioctl(struct file *file, unsigned int cmd, unsigned long arg); -void audpp_cmd_cfg_pcm_params(struct audio *audio); - -#endif /* !PCM_FUNCS_H */ diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afecmdi.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afecmdi.h deleted file mode 100644 index b4ff5b82594aba1ca7dab640d0c60e6ec8fcf40f..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afecmdi.h +++ /dev/null @@ -1,125 +0,0 @@ -/* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef __MACH_QDSP5_V2_QDSP5AFECMDI_H -#define __MACH_QDSP5_V2_QDSP5AFECMDI_H - -#define QDSP5_DEVICE_mI2S_CODEC_RX 1 /* internal codec rx path */ -#define QDSP5_DEVICE_mI2S_CODEC_TX 2 /* internal codec tx path */ -#define QDSP5_DEVICE_AUX_CODEC_RX 3 /* external codec rx path */ -#define QDSP5_DEVICE_AUX_CODEC_TX 4 /* external codec tx path */ -#define QDSP5_DEVICE_mI2S_HDMI_RX 5 /* HDMI/FM block rx path */ -#define QDSP5_DEVICE_mI2S_HDMI_TX 6 /* HDMI/FM block tx path */ -#define QDSP5_DEVICE_ID_MAX 7 - -#define AFE_CMD_CODEC_CONFIG_CMD 0x1 -#define AFE_CMD_CODEC_CONFIG_LEN sizeof(struct afe_cmd_codec_config) - -struct afe_cmd_codec_config{ - uint16_t cmd_id; - uint16_t device_id; - uint16_t activity; - uint16_t sample_rate; - uint16_t channel_mode; - uint16_t volume; - uint16_t reserved; -} __attribute__ ((packed)); - -#define AFE_CMD_DEVICE_VOLUME_CTRL 0x2 -#define AFE_CMD_DEVICE_VOLUME_CTRL_LEN \ - sizeof(struct afe_cmd_device_volume_ctrl) - -struct afe_cmd_device_volume_ctrl { - uint16_t cmd_id; - uint16_t device_id; - uint16_t device_volume; - uint16_t reserved; -} __attribute__ ((packed)); - -#define AFE_CMD_AUX_CODEC_CONFIG_CMD 0x3 -#define AFE_CMD_AUX_CODEC_CONFIG_LEN sizeof(struct afe_cmd_aux_codec_config) - -struct afe_cmd_aux_codec_config{ - uint16_t cmd_id; - uint16_t dma_path_ctl; - uint16_t pcm_ctl; - uint16_t eight_khz_int_mode; - uint16_t aux_codec_intf_ctl; - uint16_t data_format_padding_info; -} __attribute__ ((packed)); - -#define AFE_CMD_FM_RX_ROUTING_CMD 0x6 -#define AFE_CMD_FM_RX_ROUTING_LEN sizeof(struct afe_cmd_fm_codec_config) - -struct afe_cmd_fm_codec_config{ - uint16_t cmd_id; - uint16_t enable; - uint16_t device_id; -} __attribute__ ((packed)); - -#define AFE_CMD_FM_PLAYBACK_VOLUME_CMD 0x8 -#define AFE_CMD_FM_PLAYBACK_VOLUME_LEN sizeof(struct afe_cmd_fm_volume_config) - -struct afe_cmd_fm_volume_config{ - uint16_t cmd_id; - uint16_t volume; - uint16_t reserved; -} __attribute__ ((packed)); - -#define AFE_CMD_FM_CALIBRATION_GAIN_CMD 0x11 -#define AFE_CMD_FM_CALIBRATION_GAIN_LEN \ - sizeof(struct afe_cmd_fm_calibgain_config) - -struct afe_cmd_fm_calibgain_config{ - uint16_t cmd_id; - uint16_t device_id; - uint16_t calibration_gain; -} __attribute__ ((packed)); - -#define AFE_CMD_LOOPBACK 0xD -#define AFE_CMD_EXT_LOOPBACK 0xE -#define AFE_CMD_LOOPBACK_LEN sizeof(struct afe_cmd_loopback) -#define AFE_LOOPBACK_ENABLE_COMMAND 0xFFFF -#define AFE_LOOPBACK_DISABLE_COMMAND 0x0000 - -struct afe_cmd_loopback { - uint16_t cmd_id; - uint16_t enable_flag; - uint16_t reserved[2]; -} __attribute__ ((packed)); - -struct afe_cmd_ext_loopback { - uint16_t cmd_id; - uint16_t enable_flag; - uint16_t source_id; - uint16_t dst_id; - uint16_t reserved[2]; -} __packed; - -#define AFE_CMD_CFG_RMC_PARAMS 0x12 -#define AFE_CMD_CFG_RMC_LEN \ - sizeof(struct afe_cmd_cfg_rmc) - -struct afe_cmd_cfg_rmc { - unsigned short cmd_id; - signed short rmc_mode; - unsigned short rmc_ipw_length_ms; - unsigned short rmc_peak_length_ms; - unsigned short rmc_init_pulse_length_ms; - unsigned short rmc_total_int_length_ms; - unsigned short rmc_rampupdn_length_ms; - unsigned short rmc_delay_length_ms; - unsigned short rmc_detect_start_threshdb; - signed short rmc_init_pulse_threshdb; -} __attribute__((packed)); - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afemsg.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afemsg.h deleted file mode 100644 index 292683adbd0f9963df5a3d971744cd13a5e7904e..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afemsg.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef __MACH_QDSP5_V2_QDSP5AFEMSG_H -#define __MACH_QDSP5_V2_QDSP5AFEMSG_H - -#define AFE_APU_MSG_CODEC_CONFIG_ACK 0x0001 -#define AFE_APU_MSG_CODEC_CONFIG_ACK_LEN \ - sizeof(struct afe_msg_codec_config_ack) - -#define AFE_APU_MSG_VOC_TIMING_SUCCESS 0x0002 - -#define AFE_MSG_CODEC_CONFIG_ENABLED 0x1 -#define AFE_MSG_CODEC_CONFIG_DISABLED 0xFFFF - -struct afe_msg_codec_config_ack { - uint16_t device_id; - uint16_t device_activity; - uint16_t reserved; -} __attribute__((packed)); - -#endif /* QDSP5AFEMSG_H */ diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaycmdi.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaycmdi.h deleted file mode 100644 index dad7fabbf2cc0567334d1678fc45e7586ef033d1..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaycmdi.h +++ /dev/null @@ -1,145 +0,0 @@ -#ifndef QDSP5AUDPLAYCMDI_H -#define QDSP5AUDPLAYCMDI_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - Q D S P 5 A U D I O P L A Y T A S K C O M M A N D S - -GENERAL DESCRIPTION - Command Interface for AUDPLAYTASK on QDSP5 - -REFERENCES - None - -EXTERNALIZED FUNCTIONS - - audplay_cmd_dec_data_avail - Send buffer to AUDPLAY task - - -Copyright (c) 1992-2009, The Linux Foundation. All rights reserved. - -This software is licensed under the terms of the GNU General Public -License version 2, as published by the Free Software Foundation, and -may be copied, distributed, and modified under those terms. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ - -#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL 0x0000 -#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_LEN \ - sizeof(struct audplay_cmd_bitstream_data_avail) - -/* Type specification of dec_data_avail message sent to AUDPLAYTASK -*/ -struct audplay_cmd_bitstream_data_avail{ - /*command ID*/ - unsigned int cmd_id; - - /* Decoder ID for which message is being sent */ - unsigned int decoder_id; - - /* Start address of data in ARM global memory */ - unsigned int buf_ptr; - - /* Number of 16-bit words of bit-stream data contiguously - * available at the above-mentioned address - */ - unsigned int buf_size; - - /* Partition number used by audPlayTask to communicate with DSP's RTOS - * kernel - */ - unsigned int partition_number; - -} __attribute__((packed)); - -#define AUDPLAY_CMD_CHANNEL_INFO 0x0001 -#define AUDPLAY_CMD_CHANNEL_INFO_LEN \ - sizeof(struct audplay_cmd_channel_info) - -struct audplay_cmd_channel_select { - unsigned int cmd_id; - unsigned int stream_id; - unsigned int channel_select; -} __attribute__((packed)); - -struct audplay_cmd_threshold_update { - unsigned int cmd_id; - unsigned int threshold_update; - unsigned int threshold_value; -} __attribute__((packed)); - -union audplay_cmd_channel_info { - struct audplay_cmd_channel_select ch_select; - struct audplay_cmd_threshold_update thr_update; -}; - -#define AUDPLAY_CMD_HPCM_BUF_CFG 0x0003 -#define AUDPLAY_CMD_HPCM_BUF_CFG_LEN \ - sizeof(struct audplay_cmd_hpcm_buf_cfg) - -struct audplay_cmd_hpcm_buf_cfg { - unsigned int cmd_id; - unsigned int hostpcm_config; - unsigned int feedback_frequency; - unsigned int byte_swap; - unsigned int max_buffers; - unsigned int partition_number; -} __attribute__((packed)); - -#define AUDPLAY_CMD_BUFFER_REFRESH 0x0004 -#define AUDPLAY_CMD_BUFFER_REFRESH_LEN \ - sizeof(struct audplay_cmd_buffer_update) - -struct audplay_cmd_buffer_refresh { - unsigned int cmd_id; - unsigned int num_buffers; - unsigned int buf_read_count; - unsigned int buf0_address; - unsigned int buf0_length; - unsigned int buf1_address; - unsigned int buf1_length; -} __attribute__((packed)); - -#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2 0x0005 -#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2_LEN \ - sizeof(struct audplay_cmd_bitstream_data_avail_nt2) - -/* Type specification of dec_data_avail message sent to AUDPLAYTASK - * for NT2 */ -struct audplay_cmd_bitstream_data_avail_nt2 { - /*command ID*/ - unsigned int cmd_id; - - /* Decoder ID for which message is being sent */ - unsigned int decoder_id; - - /* Start address of data in ARM global memory */ - unsigned int buf_ptr; - - /* Number of 16-bit words of bit-stream data contiguously - * available at the above-mentioned address - */ - unsigned int buf_size; - - /* Partition number used by audPlayTask to communicate with DSP's RTOS - * kernel - */ - unsigned int partition_number; - - /* bitstream write pointer */ - unsigned int dspBitstreamWritePtr; - -} __attribute__((packed)); - -#define AUDPLAY_CMD_OUTPORT_FLUSH 0x0006 - -struct audplay_cmd_outport_flush { - unsigned int cmd_id; -} __attribute__((packed)); - -#endif /* QDSP5AUDPLAYCMD_H */ diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaymsg.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaymsg.h deleted file mode 100644 index 653f0e715fbd10df68026be7a4e07c7a6ace15f7..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaymsg.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef QDSP5AUDPLAYMSG_H -#define QDSP5AUDPLAYMSG_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - Q D S P 5 A U D I O P L A Y T A S K M S G - -GENERAL DESCRIPTION - Message sent by AUDPLAY task - -REFERENCES - None - - -Copyright (c) 1992-2009, The Linux Foundation. All rights reserved. - -This software is licensed under the terms of the GNU General Public -License version 2, as published by the Free Software Foundation, and -may be copied, distributed, and modified under those terms. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ - -#define AUDPLAY_MSG_DEC_NEEDS_DATA 0x0001 -#define AUDPLAY_MSG_DEC_NEEDS_DATA_MSG_LEN \ - sizeof(audplay_msg_dec_needs_data) - -struct audplay_msg_dec_needs_data { - /* reserved*/ - unsigned int dec_id; - - /*The read pointer offset of external memory till which bitstream - has been dmed in*/ - unsigned int adecDataReadPtrOffset; - - /*The buffer size of external memory. */ - unsigned int adecDataBufSize; - - unsigned int bitstream_free_len; - unsigned int bitstream_write_ptr; - unsigned int bitstarem_buf_start; - unsigned int bitstream_buf_len; -} __attribute__((packed)); - -#define AUDPLAY_UP_STREAM_INFO 0x0003 -#define AUDPLAY_UP_STREAM_INFO_LEN \ - sizeof(struct audplay_msg_stream_info) - -struct audplay_msg_stream_info { - unsigned int decoder_id; - unsigned int channel_info; - unsigned int sample_freq; - unsigned int bitstream_info; - unsigned int bit_rate; -} __attribute__((packed)); - -#define AUDPLAY_MSG_BUFFER_UPDATE 0x0004 -#define AUDPLAY_MSG_BUFFER_UPDATE_LEN \ - sizeof(struct audplay_msg_buffer_update) - -struct audplay_msg_buffer_update { - unsigned int buffer_write_count; - unsigned int num_of_buffer; - unsigned int buf0_address; - unsigned int buf0_length; - unsigned int buf1_address; - unsigned int buf1_length; -} __attribute__((packed)); - -#define AUDPLAY_UP_OUTPORT_FLUSH_ACK 0x0005 - -#endif /* QDSP5AUDPLAYMSG_H */ diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppcmdi.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppcmdi.h deleted file mode 100644 index bdcf5d8eae2b66ea4aacfaf7e1b33af7df1da211..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppcmdi.h +++ /dev/null @@ -1,1088 +0,0 @@ -#ifndef __MACH_QDSP5_V2_QDSP5AUDPPCMDI_H -#define __MACH_QDSP5_V2_QDSP5AUDPPCMDI_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - - A U D I O P O S T P R O C E S S I N G I N T E R N A L C O M M A N D S - -GENERAL DESCRIPTION - This file contains defintions of format blocks of commands - that are accepted by AUDPP Task - -REFERENCES - None - -EXTERNALIZED FUNCTIONS - None - -Copyright(c) 1992-2011, The Linux Foundation. All rights reserved. - -This software is licensed under the terms of the GNU General Public -License version 2, as published by the Free Software Foundation, and -may be copied, distributed, and modified under those terms. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ - -/* - * ARM to AUDPPTASK Commands - * - * ARM uses three command queues to communicate with AUDPPTASK - * 1)uPAudPPCmd1Queue : Used for more frequent and shorter length commands - * Location : MEMA - * Buffer Size : 6 words - * No of buffers in a queue : 20 for gaming audio and 5 for other images - * 2)uPAudPPCmd2Queue : Used for commands which are not much lengthier - * Location : MEMA - * Buffer Size : 23 - * No of buffers in a queue : 2 - * 3)uPAudOOCmd3Queue : Used for lengthier and more frequent commands - * Location : MEMA - * Buffer Size : 145 - * No of buffers in a queue : 3 - */ - -/* - * Commands Related to uPAudPPCmd1Queue - */ - -/* - * Command Structure to enable or disable the active decoders - */ - -#define AUDPP_CMD_CFG_DEC_TYPE 0x0001 -#define AUDPP_CMD_CFG_DEC_TYPE_LEN sizeof(struct audpp_cmd_cfg_dec_type) - -/* Enable the decoder */ -#define AUDPP_CMD_DEC_TYPE_M 0x000F - -#define AUDPP_CMD_ENA_DEC_V 0x4000 -#define AUDPP_CMD_DIS_DEC_V 0x0000 -#define AUDPP_CMD_DEC_STATE_M 0x4000 - -#define AUDPP_CMD_UPDATDE_CFG_DEC 0x8000 -#define AUDPP_CMD_DONT_UPDATE_CFG_DEC 0x0000 - - -/* Type specification of cmd_cfg_dec */ - -struct audpp_cmd_cfg_dec_type { - unsigned short cmd_id; - unsigned short stream_id; - unsigned short dec_cfg; - unsigned short dm_mode; -} __attribute__((packed)); - -/* - * Command Structure to Pause , Resume and flushes the selected audio decoders - */ - -#define AUDPP_CMD_DEC_CTRL 0x0002 -#define AUDPP_CMD_DEC_CTRL_LEN sizeof(struct audpp_cmd_dec_ctrl) - -/* Decoder control commands for pause, resume and flush */ -#define AUDPP_CMD_FLUSH_V 0x2000 - -#define AUDPP_CMD_PAUSE_V 0x4000 -#define AUDPP_CMD_RESUME_V 0x0000 - -#define AUDPP_CMD_UPDATE_V 0x8000 -#define AUDPP_CMD_IGNORE_V 0x0000 - - -/* Type Spec for decoder control command*/ - -struct audpp_cmd_dec_ctrl{ - unsigned short cmd_id; - unsigned short stream_id; - unsigned short dec_ctrl; -} __attribute__((packed)); - -/* - * Command Structure to Configure the AVSync FeedBack Mechanism - */ - -#define AUDPP_CMD_AVSYNC 0x0003 -#define AUDPP_CMD_AVSYNC_LEN sizeof(struct audpp_cmd_avsync) - -struct audpp_cmd_avsync{ - unsigned short cmd_id; - unsigned short stream_id; - unsigned short interrupt_interval; - unsigned short sample_counter_dlsw; - unsigned short sample_counter_dmsw; - unsigned short sample_counter_msw; - unsigned short byte_counter_dlsw; - unsigned short byte_counter_dmsw; - unsigned short byte_counter_msw; -} __attribute__((packed)); - -/* - * Macros used to store the AV Sync Info from DSP - */ - -#define AUDPP_AVSYNC_CH_COUNT 1 -#define AUDPP_AVSYNC_NUM_WORDS 6 -/* Timeout of 3000ms for AV Sync Query response */ -#define AUDPP_AVSYNC_EVENT_TIMEOUT 3000 - -/* - * Command Structure to Query AVSync Info from DSP - */ - -#define AUDPP_CMD_QUERY_AVSYNC 0x0006 - -struct audpp_cmd_query_avsync{ - unsigned short cmd_id; - unsigned short stream_id; -} __attribute__((packed)); - -/* - * Command Structure to enable or disable(sleep) the AUDPPTASK - */ - -#define AUDPP_CMD_CFG 0x0004 -#define AUDPP_CMD_CFG_LEN sizeof(struct audpp_cmd_cfg) - -#define AUDPP_CMD_CFG_SLEEP 0x0000 -#define AUDPP_CMD_CFG_ENABLE 0xFFFF - -struct audpp_cmd_cfg { - unsigned short cmd_id; - unsigned short cfg; -} __attribute__((packed)); - -/* - * Command Structure to Inject or drop the specified no of samples - */ - -#define AUDPP_CMD_ADJUST_SAMP 0x0005 -#define AUDPP_CMD_ADJUST_SAMP_LEN sizeof(struct audpp_cmd_adjust_samp) - -#define AUDPP_CMD_SAMP_DROP -1 -#define AUDPP_CMD_SAMP_INSERT 0x0001 - -#define AUDPP_CMD_NUM_SAMPLES 0x0001 - -struct audpp_cmd_adjust_samp { - unsigned short cmd_id; - unsigned short object_no; - signed short sample_insert_or_drop; - unsigned short num_samples; -} __attribute__((packed)); - -/* - * Command Structure to Configure AVSync Feedback Mechanism - */ - -#define AUDPP_CMD_ROUTING_MODE 0x0007 -#define AUDPP_CMD_ROUTING_MODE_LEN \ -sizeof(struct audpp_cmd_routing_mode) - -struct audpp_cmd_routing_mode { - unsigned short cmd_id; - unsigned short object_number; - unsigned short routing_mode; -} __attribute__((packed)); - -/* - * Commands Related to uPAudPPCmd2Queue - */ - -/* - * Command Structure to configure Per decoder Parameters (Common) - */ - -#define AUDPP_CMD_CFG_ADEC_PARAMS 0x0000 -#define AUDPP_CMD_CFG_ADEC_PARAMS_COMMON_LEN \ - sizeof(struct audpp_cmd_cfg_adec_params_common) - -#define AUDPP_CMD_STATUS_MSG_FLAG_ENA_FCM 0x4000 -#define AUDPP_CMD_STATUS_MSG_FLAG_DIS_FCM 0x0000 - -#define AUDPP_CMD_STATUS_MSG_FLAG_ENA_DCM 0x8000 -#define AUDPP_CMD_STATUS_MSG_FLAG_DIS_DCM 0x0000 - -/* Sampling frequency*/ -#define AUDPP_CMD_SAMP_RATE_96000 0x0000 -#define AUDPP_CMD_SAMP_RATE_88200 0x0001 -#define AUDPP_CMD_SAMP_RATE_64000 0x0002 -#define AUDPP_CMD_SAMP_RATE_48000 0x0003 -#define AUDPP_CMD_SAMP_RATE_44100 0x0004 -#define AUDPP_CMD_SAMP_RATE_32000 0x0005 -#define AUDPP_CMD_SAMP_RATE_24000 0x0006 -#define AUDPP_CMD_SAMP_RATE_22050 0x0007 -#define AUDPP_CMD_SAMP_RATE_16000 0x0008 -#define AUDPP_CMD_SAMP_RATE_12000 0x0009 -#define AUDPP_CMD_SAMP_RATE_11025 0x000A -#define AUDPP_CMD_SAMP_RATE_8000 0x000B - - -/* - * Type specification of cmd_adec_cfg sent to all decoder - */ - -struct audpp_cmd_cfg_adec_params_common { - unsigned short cmd_id; - unsigned short dec_id; - unsigned short length; - unsigned short reserved; - unsigned short input_sampling_frequency; -} __attribute__((packed)); - -/* - * Command Structure to configure Per decoder Parameters (Wav) - */ - -#define AUDPP_CMD_CFG_ADEC_PARAMS_WAV_LEN \ - sizeof(struct audpp_cmd_cfg_adec_params_wav) - - -#define AUDPP_CMD_WAV_STEREO_CFG_MONO 0x0001 -#define AUDPP_CMD_WAV_STEREO_CFG_STEREO 0x0002 - -#define AUDPP_CMD_WAV_PCM_WIDTH_8 0x0000 -#define AUDPP_CMD_WAV_PCM_WIDTH_16 0x0001 -#define AUDPP_CMD_WAV_PCM_WIDTH_24 0x0002 - -struct audpp_cmd_cfg_adec_params_wav { - struct audpp_cmd_cfg_adec_params_common common; - unsigned short stereo_cfg; - unsigned short pcm_width; - unsigned short sign; -} __attribute__((packed)); - -/* - * Command Structure for CMD_CFG_DEV_MIXER - */ - -#define AUDPP_CMD_CFG_DEV_MIXER_PARAMS_LEN \ - sizeof(struct audpp_cmd_cfg_dev_mixer_params) - -#define AUDPP_CMD_CFG_DEV_MIXER 0x0008 - -#define AUDPP_CMD_CFG_DEV_MIXER_ID_0 0 -#define AUDPP_CMD_CFG_DEV_MIXER_ID_1 1 -#define AUDPP_CMD_CFG_DEV_MIXER_ID_2 2 -#define AUDPP_CMD_CFG_DEV_MIXER_ID_3 3 -#define AUDPP_CMD_CFG_DEV_MIXER_ID_4 4 -#define AUDPP_CMD_CFG_DEV_MIXER_ID_5 5 - -#define AUDPP_CMD_CFG_DEV_MIXER_DEV_NONE 0x0000 -#define AUDPP_CMD_CFG_DEV_MIXER_DEV_0 \ - (0x1 << AUDPP_CMD_CFG_DEV_MIXER_ID_0) -#define AUDPP_CMD_CFG_DEV_MIXER_DEV_1 \ - (0x1 << AUDPP_CMD_CFG_DEV_MIXER_ID_1) -#define AUDPP_CMD_CFG_DEV_MIXER_DEV_2 \ - (0x1 << AUDPP_CMD_CFG_DEV_MIXER_ID_2) -#define AUDPP_CMD_CFG_DEV_MIXER_DEV_3 \ - (0x1 << AUDPP_CMD_CFG_DEV_MIXER_ID_3) -#define AUDPP_CMD_CFG_DEV_MIXER_DEV_4 \ - (0x1 << AUDPP_CMD_CFG_DEV_MIXER_ID_4) -#define AUDPP_CMD_CFG_DEV_MIXER_DEV_5 \ - (0x1 << AUDPP_CMD_CFG_DEV_MIXER_ID_5) - -struct audpp_cmd_cfg_dev_mixer_params { - unsigned short cmd_id; - unsigned short stream_id; - unsigned short mixer_cmd; -} __attribute__((packed)); - - -/* - * Command Structure to configure Per decoder Parameters (ADPCM) - */ - -#define AUDPP_CMD_CFG_ADEC_PARAMS_ADPCM_LEN \ - sizeof(struct audpp_cmd_cfg_adec_params_adpcm) - - -#define AUDPP_CMD_ADPCM_STEREO_CFG_MONO 0x0001 -#define AUDPP_CMD_ADPCM_STEREO_CFG_STEREO 0x0002 - -struct audpp_cmd_cfg_adec_params_adpcm { - struct audpp_cmd_cfg_adec_params_common common; - unsigned short stereo_cfg; - unsigned short block_size; -} __attribute__((packed)); - -/* - * Command Structure to configure Per decoder Parameters (WMA) - */ - -#define AUDPP_CMD_CFG_ADEC_PARAMS_WMA_LEN \ - sizeof(struct audpp_cmd_cfg_adec_params_wma) - -struct audpp_cmd_cfg_adec_params_wma { - struct audpp_cmd_cfg_adec_params_common common; - unsigned short armdatareqthr; - unsigned short channelsdecoded; - unsigned short wmabytespersec; - unsigned short wmasamplingfreq; - unsigned short wmaencoderopts; -} __attribute__((packed)); - - -/* - * Command Structure to configure Per decoder Parameters (MP3) - */ - -#define AUDPP_CMD_CFG_ADEC_PARAMS_MP3_LEN \ - sizeof(struct audpp_cmd_cfg_adec_params_mp3) - -struct audpp_cmd_cfg_adec_params_mp3 { - struct audpp_cmd_cfg_adec_params_common common; -} __attribute__((packed)); - - -/* - * Command Structure to configure Per decoder Parameters (AAC) - */ - -#define AUDPP_CMD_CFG_ADEC_PARAMS_AAC_LEN \ - sizeof(struct audpp_cmd_cfg_adec_params_aac) - - -#define AUDPP_CMD_AAC_FORMAT_ADTS -1 -#define AUDPP_CMD_AAC_FORMAT_RAW 0x0000 -#define AUDPP_CMD_AAC_FORMAT_PSUEDO_RAW 0x0001 -#define AUDPP_CMD_AAC_FORMAT_LOAS 0x0002 - -#define AUDPP_CMD_AAC_AUDIO_OBJECT_LC 0x0002 -#define AUDPP_CMD_AAC_AUDIO_OBJECT_LTP 0x0004 -#define AUDPP_CMD_AAC_AUDIO_OBJECT_ERLC 0x0011 - -#define AUDPP_CMD_AAC_SBR_ON_FLAG_ON 0x0001 -#define AUDPP_CMD_AAC_SBR_ON_FLAG_OFF 0x0000 - -#define AUDPP_CMD_AAC_SBR_PS_ON_FLAG_ON 0x0001 -#define AUDPP_CMD_AAC_SBR_PS_ON_FLAG_OFF 0x0000 - -struct audpp_cmd_cfg_adec_params_aac { - struct audpp_cmd_cfg_adec_params_common common; - signed short format; - unsigned short audio_object; - unsigned short ep_config; - unsigned short aac_section_data_resilience_flag; - unsigned short aac_scalefactor_data_resilience_flag; - unsigned short aac_spectral_data_resilience_flag; - unsigned short sbr_on_flag; - unsigned short sbr_ps_on_flag; - unsigned short channel_configuration; -} __attribute__((packed)); - -/* - * Command Structure to configure Per decoder Parameters (V13K) - */ - -#define AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN \ - sizeof(struct audpp_cmd_cfg_adec_params_v13k) - - -#define AUDPP_CMD_STEREO_CFG_MONO 0x0001 -#define AUDPP_CMD_STEREO_CFG_STEREO 0x0002 - -struct audpp_cmd_cfg_adec_params_v13k { - struct audpp_cmd_cfg_adec_params_common common; - unsigned short stereo_cfg; -} __attribute__((packed)); - -#define AUDPP_CMD_CFG_ADEC_PARAMS_EVRC_LEN \ - sizeof(struct audpp_cmd_cfg_adec_params_evrc) - -struct audpp_cmd_cfg_adec_params_evrc { - struct audpp_cmd_cfg_adec_params_common common; - unsigned short stereo_cfg; -} __attribute__ ((packed)); - -/* - * Command Structure to configure Per decoder Parameters (AMRWB) - */ - -#define AUDPP_CMD_CFG_ADEC_PARAMS_AMRWB_LEN \ - sizeof(struct audpp_cmd_cfg_adec_params_amrwb) - -struct audpp_cmd_cfg_adec_params_amrwb { - struct audpp_cmd_cfg_adec_params_common common; - unsigned short stereo_cfg; -} __attribute__((packed)); - -/* - * Command Structure to configure Per decoder Parameters (WMAPRO) - */ - -#define AUDPP_CMD_CFG_ADEC_PARAMS_WMAPRO_LEN \ - sizeof(struct audpp_cmd_cfg_adec_params_wmapro) - -struct audpp_cmd_cfg_adec_params_wmapro { - struct audpp_cmd_cfg_adec_params_common common; - unsigned short armdatareqthr; - uint8_t validbitspersample; - uint8_t numchannels; - unsigned short formattag; - unsigned short samplingrate; - unsigned short avgbytespersecond; - unsigned short asfpacketlength; - unsigned short channelmask; - unsigned short encodeopt; - unsigned short advancedencodeopt; - uint32_t advancedencodeopt2; -} __attribute__((packed)); - -/* - * Command Structure to configure the HOST PCM interface - */ - -#define AUDPP_CMD_PCM_INTF 0x0001 -#define AUDPP_CMD_PCM_INTF_2 0x0002 -#define AUDPP_CMD_PCM_INTF_LEN sizeof(struct audpp_cmd_pcm_intf) - -#define AUDPP_CMD_PCM_INTF_MONO_V 0x0001 -#define AUDPP_CMD_PCM_INTF_STEREO_V 0x0002 - -/* These two values differentiate the two types of commands that could be issued - * Interface configuration command and Buffer update command */ - -#define AUDPP_CMD_PCM_INTF_CONFIG_CMD_V 0x0000 -#define AUDPP_CMD_PCM_INTF_BUFFER_CMD_V -1 - -#define AUDPP_CMD_PCM_INTF_RX_ENA_M 0x000F -#define AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V 0x0008 -#define AUDPP_CMD_PCM_INTF_RX_ENA_DSPTOARM_V 0x0004 - -/* These flags control the enabling and disabling of the interface together - * with host interface bit mask. */ - -#define AUDPP_CMD_PCM_INTF_ENA_V -1 -#define AUDPP_CMD_PCM_INTF_DIS_V 0x0000 - - -#define AUDPP_CMD_PCM_INTF_FULL_DUPLEX 0x0 -#define AUDPP_CMD_PCM_INTF_HALF_DUPLEX_TODSP 0x1 - - -#define AUDPP_CMD_PCM_INTF_OBJECT_NUM 0x5 -#define AUDPP_CMD_PCM_INTF_COMMON_OBJECT_NUM 0x6 - -struct audpp_cmd_pcm_intf { - unsigned short cmd_id; - unsigned short stream; - unsigned short stream_id; - signed short config; - unsigned short intf_type; - - /* DSP -> ARM Configuration */ - unsigned short read_buf1LSW; - unsigned short read_buf1MSW; - unsigned short read_buf1_len; - - unsigned short read_buf2LSW; - unsigned short read_buf2MSW; - unsigned short read_buf2_len; - /* 0:HOST_PCM_INTF disable - ** 0xFFFF: HOST_PCM_INTF enable - */ - signed short dsp_to_arm_flag; - unsigned short partition_number; - - /* ARM -> DSP Configuration */ - unsigned short write_buf1LSW; - unsigned short write_buf1MSW; - unsigned short write_buf1_len; - - unsigned short write_buf2LSW; - unsigned short write_buf2MSW; - unsigned short write_buf2_len; - - /* 0:HOST_PCM_INTF disable - ** 0xFFFF: HOST_PCM_INTF enable - */ - signed short arm_to_rx_flag; - unsigned short weight_decoder_to_rx; - unsigned short weight_arm_to_rx; - - unsigned short partition_number_arm_to_dsp; - unsigned short sample_rate; - unsigned short channel_mode; -} __attribute__((packed)); - -/* - ** BUFFER UPDATE COMMAND - */ -#define AUDPP_CMD_PCM_INTF_SEND_BUF_PARAMS_LEN \ - sizeof(struct audpp_cmd_pcm_intf_send_buffer) - -struct audpp_cmd_pcm_intf_send_buffer { - unsigned short cmd_id; - unsigned short stream; - unsigned short stream_id; - /* set config = 0xFFFF for configuration*/ - signed short config; - unsigned short intf_type; - unsigned short dsp_to_arm_buf_id; - unsigned short arm_to_dsp_buf_id; - unsigned short arm_to_dsp_buf_len; -} __attribute__((packed)); - - -/* - * Commands Related to uPAudPPCmd3Queue - */ - -/* - * Command Structure to configure post processing params (Commmon) - */ - -#define AUDPP_CMD_CFG_OBJECT_PARAMS 0x0000 -#define AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN \ - sizeof(struct audpp_cmd_cfg_object_params_common) - -#define AUDPP_CMD_OBJ0_UPDATE 0x8000 -#define AUDPP_CMD_OBJ0_DONT_UPDATE 0x0000 - - -#define AUDPP_CMD_OBJ2_UPDATE 0x8000 -#define AUDPP_CMD_OBJ2_DONT_UPDATE 0x0000 - -#define AUDPP_CMD_OBJ3_UPDATE 0x8000 -#define AUDPP_CMD_OBJ3_DONT_UPDATE 0x0000 - -#define AUDPP_CMD_OBJ4_UPDATE 0x8000 -#define AUDPP_CMD_OBJ4_DONT_UPDATE 0x0000 - -#define AUDPP_CMD_HPCM_UPDATE 0x8000 -#define AUDPP_CMD_HPCM_DONT_UPDATE 0x0000 - -#define AUDPP_CMD_COMMON_CFG_UPDATE 0x8000 -#define AUDPP_CMD_COMMON_CFG_DONT_UPDATE 0x0000 - -#define AUDPP_CMD_POPP_STREAM 0xFFFF -#define AUDPP_CMD_COPP_STREAM 0x0000 - -struct audpp_cmd_cfg_object_params_common{ - unsigned short cmd_id; - unsigned short stream; - unsigned short stream_id; - unsigned short obj_cfg; - unsigned short command_type; -} __attribute__((packed)); - -/* - * Command Structure to configure post processing params (Volume) - */ -#define AUDPP_CMD_VOLUME_PAN 0 -#define AUDPP_CMD_CFG_OBJECT_PARAMS_VOLUME_LEN \ - sizeof(struct audpp_cmd_cfg_object_params_volume) - -struct audpp_cmd_cfg_object_params_volume { - struct audpp_cmd_cfg_object_params_common common; - unsigned short volume; - unsigned short pan; -} __attribute__((packed)); - -/* - * Command Structure to configure post processing params (PCM Filter) - */ - -struct numerator { - unsigned short numerator_b0_filter_lsw; - unsigned short numerator_b0_filter_msw; - unsigned short numerator_b1_filter_lsw; - unsigned short numerator_b1_filter_msw; - unsigned short numerator_b2_filter_lsw; - unsigned short numerator_b2_filter_msw; -} __attribute__((packed)); - -struct denominator { - unsigned short denominator_a0_filter_lsw; - unsigned short denominator_a0_filter_msw; - unsigned short denominator_a1_filter_lsw; - unsigned short denominator_a1_filter_msw; -} __attribute__((packed)); - -struct shift_factor { - unsigned short shift_factor_0; -} __attribute__((packed)); - -struct pan { - unsigned short pan_filter_0; -} __attribute__((packed)); - -struct filter_1 { - struct numerator numerator_filter; - struct denominator denominator_filter; - struct shift_factor shift_factor_filter; - struct pan pan_filter; -} __attribute__((packed)); - -struct filter_2 { - struct numerator numerator_filter[2]; - struct denominator denominator_filter[2]; - struct shift_factor shift_factor_filter[2]; - struct pan pan_filter[2]; -} __attribute__((packed)); - -struct filter_3 { - struct numerator numerator_filter[3]; - struct denominator denominator_filter[3]; - struct shift_factor shift_factor_filter[3]; - struct pan pan_filter[3]; -} __attribute__((packed)); - -struct filter_4 { - struct numerator numerator_filter[4]; - struct denominator denominator_filter[4]; - struct shift_factor shift_factor_filter[4]; - struct pan pan_filter[4]; -} __attribute__((packed)); - -#define AUDPP_CMD_IIR_TUNING_FILTER 1 -#define AUDPP_CMD_CFG_OBJECT_PARAMS_PCM_LEN \ - sizeof(struct audpp_cmd_cfg_object_params_pcm) - - -struct audpp_cmd_cfg_object_params_pcm { - struct audpp_cmd_cfg_object_params_common common; - signed short active_flag; - unsigned short num_bands; - union { - struct filter_1 filter_1_params; - struct filter_2 filter_2_params; - struct filter_3 filter_3_params; - struct filter_4 filter_4_params; - } __attribute__((packed)) params_filter; -} __attribute__((packed)); - -#define AUDPP_CMD_CALIB_GAIN_RX 15 -#define AUDPP_CMD_CFG_CAL_GAIN_LEN sizeof(struct audpp_cmd_cfg_cal_gain) - - -struct audpp_cmd_cfg_cal_gain { - struct audpp_cmd_cfg_object_params_common common; - unsigned short audppcalgain; - unsigned short reserved; -} __attribute__((packed)); - - -/* - * Command Structure to configure post processing parameters (equalizer) - */ -#define AUDPP_CMD_EQUALIZER 2 -#define AUDPP_CMD_CFG_OBJECT_PARAMS_EQALIZER_LEN \ - sizeof(struct audpp_cmd_cfg_object_params_eqalizer) - -struct eq_numerator { - unsigned short numerator_coeff_0_lsw; - unsigned short numerator_coeff_0_msw; - unsigned short numerator_coeff_1_lsw; - unsigned short numerator_coeff_1_msw; - unsigned short numerator_coeff_2_lsw; - unsigned short numerator_coeff_2_msw; -} __attribute__((packed)); - -struct eq_denominator { - unsigned short denominator_coeff_0_lsw; - unsigned short denominator_coeff_0_msw; - unsigned short denominator_coeff_1_lsw; - unsigned short denominator_coeff_1_msw; -} __attribute__((packed)); - -struct eq_shiftfactor { - unsigned short shift_factor; -} __attribute__((packed)); - -struct eq_coeff_1 { - struct eq_numerator numerator; - struct eq_denominator denominator; - struct eq_shiftfactor shiftfactor; -} __attribute__((packed)); - -struct eq_coeff_2 { - struct eq_numerator numerator[2]; - struct eq_denominator denominator[2]; - struct eq_shiftfactor shiftfactor[2]; -} __attribute__((packed)); - -struct eq_coeff_3 { - struct eq_numerator numerator[3]; - struct eq_denominator denominator[3]; - struct eq_shiftfactor shiftfactor[3]; -} __attribute__((packed)); - -struct eq_coeff_4 { - struct eq_numerator numerator[4]; - struct eq_denominator denominator[4]; - struct eq_shiftfactor shiftfactor[4]; -} __attribute__((packed)); - -struct eq_coeff_5 { - struct eq_numerator numerator[5]; - struct eq_denominator denominator[5]; - struct eq_shiftfactor shiftfactor[5]; -} __attribute__((packed)); - -struct eq_coeff_6 { - struct eq_numerator numerator[6]; - struct eq_denominator denominator[6]; - struct eq_shiftfactor shiftfactor[6]; -} __attribute__((packed)); - -struct eq_coeff_7 { - struct eq_numerator numerator[7]; - struct eq_denominator denominator[7]; - struct eq_shiftfactor shiftfactor[7]; -} __attribute__((packed)); - -struct eq_coeff_8 { - struct eq_numerator numerator[8]; - struct eq_denominator denominator[8]; - struct eq_shiftfactor shiftfactor[8]; -} __attribute__((packed)); - -struct eq_coeff_9 { - struct eq_numerator numerator[9]; - struct eq_denominator denominator[9]; - struct eq_shiftfactor shiftfactor[9]; -} __attribute__((packed)); - -struct eq_coeff_10 { - struct eq_numerator numerator[10]; - struct eq_denominator denominator[10]; - struct eq_shiftfactor shiftfactor[10]; -} __attribute__((packed)); - -struct eq_coeff_11 { - struct eq_numerator numerator[11]; - struct eq_denominator denominator[11]; - struct eq_shiftfactor shiftfactor[11]; -} __attribute__((packed)); - -struct eq_coeff_12 { - struct eq_numerator numerator[12]; - struct eq_denominator denominator[12]; - struct eq_shiftfactor shiftfactor[12]; -} __attribute__((packed)); - - -struct audpp_cmd_cfg_object_params_eqalizer { - struct audpp_cmd_cfg_object_params_common common; - signed short eq_flag; - unsigned short num_bands; - union { - struct eq_coeff_1 eq_coeffs_1; - struct eq_coeff_2 eq_coeffs_2; - struct eq_coeff_3 eq_coeffs_3; - struct eq_coeff_4 eq_coeffs_4; - struct eq_coeff_5 eq_coeffs_5; - struct eq_coeff_6 eq_coeffs_6; - struct eq_coeff_7 eq_coeffs_7; - struct eq_coeff_8 eq_coeffs_8; - struct eq_coeff_9 eq_coeffs_9; - struct eq_coeff_10 eq_coeffs_10; - struct eq_coeff_11 eq_coeffs_11; - struct eq_coeff_12 eq_coeffs_12; - } __attribute__((packed)) eq_coeff; -} __attribute__((packed)); - -/* - * Command Structure to configure post processing parameters (ADRC) - */ -#define AUDPP_CMD_ADRC 3 -#define AUDPP_CMD_CFG_OBJECT_PARAMS_ADRC_LEN \ - sizeof(struct audpp_cmd_cfg_object_params_adrc) - - -#define AUDPP_CMD_ADRC_FLAG_DIS 0x0000 -#define AUDPP_CMD_ADRC_FLAG_ENA -1 -#define AUDPP_CMD_PBE_FLAG_DIS 0x0000 -#define AUDPP_CMD_PBE_FLAG_ENA -1 - -struct audpp_cmd_cfg_object_params_adrc { - struct audpp_cmd_cfg_object_params_common common; - signed short adrc_flag; - unsigned short compression_th; - unsigned short compression_slope; - unsigned short rms_time; - unsigned short attack_const_lsw; - unsigned short attack_const_msw; - unsigned short release_const_lsw; - unsigned short release_const_msw; - unsigned short adrc_delay; -}; - -/* - * Command Structure to configure post processing parameters (MB - ADRC) - */ -#define AUDPP_CMD_MBADRC 10 -#define AUDPP_MAX_MBADRC_BANDS 5 - -struct adrc_config { - uint16_t subband_enable; - uint16_t adrc_sub_mute; - uint16_t rms_time; - uint16_t compression_th; - uint16_t compression_slope; - uint16_t attack_const_lsw; - uint16_t attack_const_msw; - uint16_t release_const_lsw; - uint16_t release_const_msw; - uint16_t makeup_gain; -}; - -struct audpp_cmd_cfg_object_params_mbadrc { - struct audpp_cmd_cfg_object_params_common common; - uint16_t enable; - uint16_t num_bands; - uint16_t down_samp_level; - uint16_t adrc_delay; - uint16_t ext_buf_size; - uint16_t ext_partition; - uint16_t ext_buf_msw; - uint16_t ext_buf_lsw; - struct adrc_config adrc_band[AUDPP_MAX_MBADRC_BANDS]; -} __attribute__((packed)); - -/* - * Command Structure to configure post processing parameters(Spectrum Analizer) - */ -#define AUDPP_CMD_SPECTROGRAM 4 -#define AUDPP_CMD_CFG_OBJECT_PARAMS_SPECTRAM_LEN \ - sizeof(struct audpp_cmd_cfg_object_params_spectram) - - -struct audpp_cmd_cfg_object_params_spectram { - struct audpp_cmd_cfg_object_params_common common; - unsigned short sample_interval; - unsigned short num_coeff; -} __attribute__((packed)); - -/* - * Command Structure to configure post processing parameters (QConcert) - */ -#define AUDPP_CMD_QCONCERT 5 -#define AUDPP_CMD_CFG_OBJECT_PARAMS_QCONCERT_LEN \ - sizeof(struct audpp_cmd_cfg_object_params_qconcert) - - -#define AUDPP_CMD_QCON_ENA_FLAG_ENA -1 -#define AUDPP_CMD_QCON_ENA_FLAG_DIS 0x0000 - -#define AUDPP_CMD_QCON_OP_MODE_HEADPHONE -1 -#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_FRONT 0x0000 -#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_SIDE 0x0001 -#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_DESKTOP 0x0002 - -#define AUDPP_CMD_QCON_GAIN_UNIT 0x7FFF -#define AUDPP_CMD_QCON_GAIN_SIX_DB 0x4027 - - -#define AUDPP_CMD_QCON_EXPANSION_MAX 0x7FFF - - -struct audpp_cmd_cfg_object_params_qconcert { - struct audpp_cmd_cfg_object_params_common common; - signed short enable_flag; - signed short op_mode; - signed short gain; - signed short expansion; - signed short delay; - unsigned short stages_per_mode; - unsigned short reverb_enable; - unsigned short decay_msw; - unsigned short decay_lsw; - unsigned short decay_time_ratio_msw; - unsigned short decay_time_ratio_lsw; - unsigned short reflection_delay_time; - unsigned short late_reverb_gain; - unsigned short late_reverb_delay; - unsigned short delay_buff_size_msw; - unsigned short delay_buff_size_lsw; - unsigned short partition_num; - unsigned short delay_buff_start_msw; - unsigned short delay_buff_start_lsw; -} __attribute__((packed)); - -/* - * Command Structure to configure post processing parameters (Side Chain) - */ -#define AUDPP_CMD_SIDECHAIN_TUNING_FILTER 6 -#define AUDPP_CMD_CFG_OBJECT_PARAMS_SIDECHAIN_LEN \ - sizeof(struct audpp_cmd_cfg_object_params_sidechain) - - -#define AUDPP_CMD_SIDECHAIN_ACTIVE_FLAG_DIS 0x0000 -#define AUDPP_CMD_SIDECHAIN_ACTIVE_FLAG_ENA -1 - -struct audpp_cmd_cfg_object_params_sidechain { - struct audpp_cmd_cfg_object_params_common common; - signed short active_flag; - unsigned short num_bands; - union { - struct filter_1 filter_1_params; - struct filter_2 filter_2_params; - struct filter_3 filter_3_params; - struct filter_4 filter_4_params; - } __attribute__((packed)) params_filter; -} __attribute__((packed)); - - -/* - * Command Structure to configure post processing parameters (QAFX) - */ -#define AUDPP_CMD_QAFX 8 -#define AUDPP_CMD_CFG_OBJECT_PARAMS_QAFX_LEN \ - sizeof(struct audpp_cmd_cfg_object_params_qafx) - -#define AUDPP_CMD_QAFX_ENA_DISA 0x0000 -#define AUDPP_CMD_QAFX_ENA_ENA_CFG -1 -#define AUDPP_CMD_QAFX_ENA_DIS_CFG 0x0001 - -#define AUDPP_CMD_QAFX_CMD_TYPE_ENV 0x0100 -#define AUDPP_CMD_QAFX_CMD_TYPE_OBJ 0x0010 -#define AUDPP_CMD_QAFX_CMD_TYPE_QUERY 0x1000 - -#define AUDPP_CMD_QAFX_CMDS_ENV_OP_MODE 0x0100 -#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_POS 0x0101 -#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_ORI 0x0102 -#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_VEL 0X0103 -#define AUDPP_CMD_QAFX_CMDS_ENV_ENV_RES 0x0107 - -#define AUDPP_CMD_QAFX_CMDS_OBJ_SAMP_FREQ 0x0010 -#define AUDPP_CMD_QAFX_CMDS_OBJ_VOL 0x0011 -#define AUDPP_CMD_QAFX_CMDS_OBJ_DIST 0x0012 -#define AUDPP_CMD_QAFX_CMDS_OBJ_POS 0x0013 -#define AUDPP_CMD_QAFX_CMDS_OBJ_VEL 0x0014 - - -struct audpp_cmd_cfg_object_params_qafx { - struct audpp_cmd_cfg_object_params_common common; - signed short enable; - unsigned short command_type; - unsigned short num_commands; - unsigned short commands; -} __attribute__((packed)); - -/* - * Command Structure to enable , disable or configure the reverberation effect - * (REVERB) (Common) - */ - -#define AUDPP_CMD_REVERB_CONFIG 0x0001 -#define AUDPP_CMD_REVERB_CONFIG_COMMON_LEN \ - sizeof(struct audpp_cmd_reverb_config_common) - -#define AUDPP_CMD_ENA_ENA 0xFFFF -#define AUDPP_CMD_ENA_DIS 0x0000 -#define AUDPP_CMD_ENA_CFG 0x0001 - -#define AUDPP_CMD_CMD_TYPE_ENV 0x0104 -#define AUDPP_CMD_CMD_TYPE_OBJ 0x0015 -#define AUDPP_CMD_CMD_TYPE_QUERY 0x1000 - - -struct audpp_cmd_reverb_config_common { - unsigned short cmd_id; - unsigned short enable; - unsigned short cmd_type; -} __attribute__((packed)); - -/* - * Command Structure to enable , disable or configure the reverberation effect - * (ENV-0x0104) - */ - -#define AUDPP_CMD_REVERB_CONFIG_ENV_104_LEN \ - sizeof(struct audpp_cmd_reverb_config_env_104) - -struct audpp_cmd_reverb_config_env_104 { - struct audpp_cmd_reverb_config_common common; - unsigned short env_gain; - unsigned short decay_msw; - unsigned short decay_lsw; - unsigned short decay_timeratio_msw; - unsigned short decay_timeratio_lsw; - unsigned short delay_time; - unsigned short reverb_gain; - unsigned short reverb_delay; -} __attribute__((packed)); - -/* - * Command Structure to enable , disable or configure the reverberation effect - * (ENV-0x0015) - */ - -#define AUDPP_CMD_REVERB_CONFIG_ENV_15_LEN \ - sizeof(struct audpp_cmd_reverb_config_env_15) - -struct audpp_cmd_reverb_config_env_15 { - struct audpp_cmd_reverb_config_common common; - unsigned short object_num; - unsigned short absolute_gain; -} __attribute__((packed)); - -#define AUDPP_CMD_PBE 16 -#define AUDPP_CMD_CFG_PBE_LEN sizeof(struct audpp_cmd_cfg_pbe) - -struct audpp_cmd_cfg_pbe { - struct audpp_cmd_cfg_object_params_common common; - unsigned short pbe_enable; - signed short realbassmix; - signed short basscolorcontrol; - unsigned short mainchaindelay; - unsigned short xoverfltorder; - unsigned short bandpassfltorder; - signed short adrcdelay; - unsigned short downsamplelevel; - unsigned short comprmstav; - signed short expthreshold; - unsigned short expslope; - unsigned short compthreshold; - unsigned short compslope; - unsigned short cpmpattack_lsw; - unsigned short compattack_msw; - unsigned short comprelease_lsw; - unsigned short comprelease_msw; - unsigned short compmakeupgain; - signed short baselimthreshold; - signed short highlimthreshold; - signed short basslimmakeupgain; - signed short highlimmakeupgain; - signed short limbassgrc; - signed short limhighgrc; - signed short limdelay; - unsigned short filter_coeffs[90]; - unsigned short extbuffsize_lsw; - unsigned short extbuffsize_msw; - unsigned short extpartition; - unsigned short extbuffstart_lsw; - unsigned short extbuffstart_msw; -} __attribute__((packed)); - -#define AUDPP_CMD_PP_FEAT_QUERY_PARAMS 0x0002 - -struct audpp_cmd_cfg_object_params_volpan { - struct audpp_cmd_cfg_object_params_common common; - u16 volume ; - u16 pan; -}; - -struct rtc_audpp_read_data { - unsigned short cmd_id; - unsigned short obj_id; - unsigned short route_id; - unsigned short feature_id; - unsigned short extbufsizemsw; - unsigned short extbufsizelsw; - unsigned short extpart; - unsigned short extbufstartmsw; - unsigned short extbufstartlsw; -} __attribute__((packed)) ; - -#define AUDPP_CMD_SAMPLING_FREQUENCY 7 -#define AUDPP_CMD_QRUMBLE 9 - -#endif /* __MACH_QDSP5_V2_QDSP5AUDPPCMDI_H */ diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppmsg.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppmsg.h deleted file mode 100644 index 300232df53297968bb16408fcc4419af6cad3105..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppmsg.h +++ /dev/null @@ -1,311 +0,0 @@ -#ifndef QDSP5AUDPPMSG_H -#define QDSP5AUDPPMSG_H - -/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* - - Q D S P 5 A U D I O P O S T P R O C E S S I N G M S G - -GENERAL DESCRIPTION - Messages sent by AUDPPTASK to ARM - -REFERENCES - None - -EXTERNALIZED FUNCTIONS - None - -Copyright (c) 1992-2009, The Linux Foundation. All rights reserved. - -This software is licensed under the terms of the GNU General Public -License version 2, as published by the Free Software Foundation, and -may be copied, distributed, and modified under those terms. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/ - -/* - * AUDPPTASK uses audPPuPRlist to send messages to the ARM - * Location : MEMA - * Buffer Size : 45 - * No of Buffers in a queue : 5 for gaming audio and 1 for other images - */ - -/* - * MSG to Informs the ARM os Success/Failure of bringing up the decoder - */ - -#define AUDPP_MSG_FEAT_QUERY_DM_DONE 0x000b - -#define AUDPP_MSG_STATUS_MSG 0x0001 -#define AUDPP_MSG_STATUS_MSG_LEN \ - sizeof(struct audpp_msg_status_msg) - -#define AUDPP_MSG_STATUS_SLEEP 0x0000 -#define AUDPP_MSG_STATUS_INIT 0x0001 -#define AUDPP_MSG_STATUS_CFG 0x0002 -#define AUDPP_MSG_STATUS_PLAY 0x0003 - -#define AUDPP_MSG_REASON_NONE 0x0000 -#define AUDPP_MSG_REASON_MEM 0x0001 -#define AUDPP_MSG_REASON_NODECODER 0x0002 - -struct audpp_msg_status_msg { - unsigned short dec_id; - unsigned short status; - unsigned short reason; -} __attribute__((packed)); - -/* - * MSG to communicate the spectrum analyzer output bands to the ARM - */ -#define AUDPP_MSG_SPA_BANDS 0x0002 -#define AUDPP_MSG_SPA_BANDS_LEN \ - sizeof(struct audpp_msg_spa_bands) - -struct audpp_msg_spa_bands { - unsigned short current_object; - unsigned short spa_band_1; - unsigned short spa_band_2; - unsigned short spa_band_3; - unsigned short spa_band_4; - unsigned short spa_band_5; - unsigned short spa_band_6; - unsigned short spa_band_7; - unsigned short spa_band_8; - unsigned short spa_band_9; - unsigned short spa_band_10; - unsigned short spa_band_11; - unsigned short spa_band_12; - unsigned short spa_band_13; - unsigned short spa_band_14; - unsigned short spa_band_15; - unsigned short spa_band_16; - unsigned short spa_band_17; - unsigned short spa_band_18; - unsigned short spa_band_19; - unsigned short spa_band_20; - unsigned short spa_band_21; - unsigned short spa_band_22; - unsigned short spa_band_23; - unsigned short spa_band_24; - unsigned short spa_band_25; - unsigned short spa_band_26; - unsigned short spa_band_27; - unsigned short spa_band_28; - unsigned short spa_band_29; - unsigned short spa_band_30; - unsigned short spa_band_31; - unsigned short spa_band_32; -} __attribute__((packed)); - -/* - * MSG to communicate the PCM I/O buffer status to ARM - */ -#define AUDPP_MSG_HOST_PCM_INTF_MSG 0x0003 -#define AUDPP_MSG_HOST_PCM_INTF_MSG_LEN \ - sizeof(struct audpp_msg_host_pcm_intf_msg) - -#define AUDPP_MSG_HOSTPCM_ID_TX_ARM 0x0000 -#define AUDPP_MSG_HOSTPCM_ID_ARM_TX 0x0001 -#define AUDPP_MSG_HOSTPCM_ID_RX_ARM 0x0002 -#define AUDPP_MSG_HOSTPCM_ID_ARM_RX 0x0003 - -#define AUDPP_MSG_SAMP_FREQ_INDX_96000 0x0000 -#define AUDPP_MSG_SAMP_FREQ_INDX_88200 0x0001 -#define AUDPP_MSG_SAMP_FREQ_INDX_64000 0x0002 -#define AUDPP_MSG_SAMP_FREQ_INDX_48000 0x0003 -#define AUDPP_MSG_SAMP_FREQ_INDX_44100 0x0004 -#define AUDPP_MSG_SAMP_FREQ_INDX_32000 0x0005 -#define AUDPP_MSG_SAMP_FREQ_INDX_24000 0x0006 -#define AUDPP_MSG_SAMP_FREQ_INDX_22050 0x0007 -#define AUDPP_MSG_SAMP_FREQ_INDX_16000 0x0008 -#define AUDPP_MSG_SAMP_FREQ_INDX_12000 0x0009 -#define AUDPP_MSG_SAMP_FREQ_INDX_11025 0x000A -#define AUDPP_MSG_SAMP_FREQ_INDX_8000 0x000B - -#define AUDPP_MSG_CHANNEL_MODE_MONO 0x0001 -#define AUDPP_MSG_CHANNEL_MODE_STEREO 0x0002 - -struct audpp_msg_host_pcm_intf_msg { - unsigned short obj_num; - unsigned short numbers_of_samples; - unsigned short host_pcm_id; - unsigned short buf_indx; - unsigned short samp_freq_indx; - unsigned short channel_mode; -} __attribute__((packed)); - - -/* - * MSG to communicate 3D position of the source and listener , source volume - * source rolloff, source orientation - */ - -#define AUDPP_MSG_QAFX_POS 0x0004 -#define AUDPP_MSG_QAFX_POS_LEN \ - sizeof(struct audpp_msg_qafx_pos) - -struct audpp_msg_qafx_pos { - unsigned short current_object; - unsigned short x_pos_lis_msw; - unsigned short x_pos_lis_lsw; - unsigned short y_pos_lis_msw; - unsigned short y_pos_lis_lsw; - unsigned short z_pos_lis_msw; - unsigned short z_pos_lis_lsw; - unsigned short x_fwd_msw; - unsigned short x_fwd_lsw; - unsigned short y_fwd_msw; - unsigned short y_fwd_lsw; - unsigned short z_fwd_msw; - unsigned short z_fwd_lsw; - unsigned short x_up_msw; - unsigned short x_up_lsw; - unsigned short y_up_msw; - unsigned short y_up_lsw; - unsigned short z_up_msw; - unsigned short z_up_lsw; - unsigned short x_vel_lis_msw; - unsigned short x_vel_lis_lsw; - unsigned short y_vel_lis_msw; - unsigned short y_vel_lis_lsw; - unsigned short z_vel_lis_msw; - unsigned short z_vel_lis_lsw; - unsigned short threed_enable_flag; - unsigned short volume; - unsigned short x_pos_source_msw; - unsigned short x_pos_source_lsw; - unsigned short y_pos_source_msw; - unsigned short y_pos_source_lsw; - unsigned short z_pos_source_msw; - unsigned short z_pos_source_lsw; - unsigned short max_dist_0_msw; - unsigned short max_dist_0_lsw; - unsigned short min_dist_0_msw; - unsigned short min_dist_0_lsw; - unsigned short roll_off_factor; - unsigned short mute_after_max_flag; - unsigned short x_vel_source_msw; - unsigned short x_vel_source_lsw; - unsigned short y_vel_source_msw; - unsigned short y_vel_source_lsw; - unsigned short z_vel_source_msw; - unsigned short z_vel_source_lsw; -} __attribute__((packed)); - -/* - * MSG to provide AVSYNC feedback from DSP to ARM - */ - -#define AUDPP_MSG_AVSYNC_MSG 0x0005 -#define AUDPP_MSG_AVSYNC_MSG_LEN \ - sizeof(struct audpp_msg_avsync_msg) - -struct audpp_msg_avsync_msg { - unsigned short active_flag; - unsigned short num_samples_counter0_HSW; - unsigned short num_samples_counter0_MSW; - unsigned short num_samples_counter0_LSW; - unsigned short num_bytes_counter0_HSW; - unsigned short num_bytes_counter0_MSW; - unsigned short num_bytes_counter0_LSW; - unsigned short samp_freq_obj_0; - unsigned short samp_freq_obj_1; - unsigned short samp_freq_obj_2; - unsigned short samp_freq_obj_3; - unsigned short samp_freq_obj_4; - unsigned short samp_freq_obj_5; - unsigned short samp_freq_obj_6; - unsigned short samp_freq_obj_7; - unsigned short samp_freq_obj_8; - unsigned short samp_freq_obj_9; - unsigned short samp_freq_obj_10; - unsigned short samp_freq_obj_11; - unsigned short samp_freq_obj_12; - unsigned short samp_freq_obj_13; - unsigned short samp_freq_obj_14; - unsigned short samp_freq_obj_15; - unsigned short num_samples_counter4_HSW; - unsigned short num_samples_counter4_MSW; - unsigned short num_samples_counter4_LSW; - unsigned short num_bytes_counter4_HSW; - unsigned short num_bytes_counter4_MSW; - unsigned short num_bytes_counter4_LSW; -} __attribute__((packed)); - -/* - * MSG to provide PCM DMA Missed feedback from the DSP to ARM - */ - -#define AUDPP_MSG_PCMDMAMISSED 0x0006 -#define AUDPP_MSG_PCMDMAMISSED_LEN \ - sizeof(struct audpp_msg_pcmdmamissed); - -struct audpp_msg_pcmdmamissed { - /* - ** Bit 0 0 = PCM DMA not missed for object 0 - ** 1 = PCM DMA missed for object0 - ** Bit 1 0 = PCM DMA not missed for object 1 - ** 1 = PCM DMA missed for object1 - ** Bit 2 0 = PCM DMA not missed for object 2 - ** 1 = PCM DMA missed for object2 - ** Bit 3 0 = PCM DMA not missed for object 3 - ** 1 = PCM DMA missed for object3 - ** Bit 4 0 = PCM DMA not missed for object 4 - ** 1 = PCM DMA missed for object4 - */ - unsigned short pcmdmamissed; -} __attribute__((packed)); - -/* - * MSG to AUDPP enable or disable feedback form DSP to ARM - */ - -#define AUDPP_MSG_CFG_MSG 0x0007 -#define AUDPP_MSG_CFG_MSG_LEN \ - sizeof(struct audpp_msg_cfg_msg) - -#define AUDPP_MSG_ENA_ENA 0xFFFF -#define AUDPP_MSG_ENA_DIS 0x0000 - -struct audpp_msg_cfg_msg { - /* Enabled - 0xffff - ** Disabled - 0 - */ - unsigned short enabled; -} __attribute__((packed)); - -/* - * MSG to communicate the reverb per object volume - */ - -#define AUDPP_MSG_QREVERB_VOLUME 0x0008 -#define AUDPP_MSG_QREVERB_VOLUME_LEN \ - sizeof(struct audpp_msg_qreverb_volume) - - -struct audpp_msg_qreverb_volume { - unsigned short obj_0_gain; - unsigned short obj_1_gain; - unsigned short obj_2_gain; - unsigned short obj_3_gain; - unsigned short obj_4_gain; - unsigned short hpcm_obj_volume; -} __attribute__((packed)); - -#define AUDPP_MSG_ROUTING_ACK 0x0009 -#define AUDPP_MSG_ROUTING_ACK_LEN \ - sizeof(struct audpp_msg_routing_ack) - -struct audpp_msg_routing_ack { - unsigned short dec_id; - unsigned short routing_mode; -} __attribute__((packed)); - -#define AUDPP_MSG_FLUSH_ACK 0x000A - -#endif /* QDSP5AUDPPMSG_H */ diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreproccmdi.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreproccmdi.h deleted file mode 100644 index 3d5cf845d8644cc54dfbc91c4006365d6b2c4f72..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreproccmdi.h +++ /dev/null @@ -1,519 +0,0 @@ -/* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef QDSP5AUDPREPROCCMDI_H -#define QDSP5AUDPREPROCCMDI_H - -/* - * AUDIOPREPROC COMMANDS: - * ARM uses uPAudPreProcAudRecCmdQueue to communicate with AUDPREPROCTASK - * Location : MEMB - * Buffer size : 7 - * Number of buffers in a queue : 4 - */ - -/* - * Command to enable or disable particular encoder for new interface - */ - -#define AUDPREPROC_AUDREC_CMD_ENC_CFG 0x0000 -#define AUDPREPROC_AUDREC_CMD_ENC_CFG_LEN \ - sizeof(struct audpreproc_audrec_cmd_enc_cfg) -#define AUDREC_TASK_0 0x00 /* SBC / PCM */ -#define AUDREC_TASK_1 0x01 /* AAC / PCM / VOICE ENC */ - -#define ENCODE_ENABLE 0x8000 - -/* encoder type supported */ -#define ENC_TYPE_WAV 0x00 -#define ENC_TYPE_AAC 0x01 -#define ENC_TYPE_SBC 0x02 -#define ENC_TYPE_AMRNB 0x03 -#define ENC_TYPE_EVRC 0x04 -#define ENC_TYPE_V13K 0x05 -#define ENC_TYPE_EXT_WAV 0x0F /* to dynamically configure frame size */ - -/* structure definitions according to - * command description of ARM-DSP interface specifications - */ -struct audpreproc_audrec_cmd_enc_cfg { - unsigned short cmd_id; - unsigned short stream_id; - unsigned short audrec_enc_type; -} __attribute__((packed)); - -/* - * Command to configure parameters of selected Encoder - */ - -#define AUDPREPROC_AUDREC_CMD_PARAM_CFG 0x0001 - -#define AUDPREPROC_AUDREC_CMD_PARAM_CFG_COMMON_LEN \ - sizeof(struct audpreproc_audrec_cmd_param_cfg_common) - -#define DUAL_MIC_STEREO_RECORDING 2 - -struct audpreproc_audrec_cmd_param_cfg_common { - unsigned short cmd_id; - unsigned short stream_id; -} __attribute__((packed)); - -/* - * Command Structure to configure WAV Encoder - */ - -#define AUDPREPROC_AUDREC_CMD_PARAM_CFG_WAV_LEN \ - sizeof(struct audpreproc_audrec_cmd_parm_cfg_wav) - -#define AUDREC_CMD_MODE_MONO 0 -#define AUDREC_CMD_MODE_STEREO 1 - -struct audpreproc_audrec_cmd_parm_cfg_wav { - struct audpreproc_audrec_cmd_param_cfg_common common; - unsigned short aud_rec_samplerate_idx; - unsigned short aud_rec_stereo_mode; - unsigned short aud_rec_frame_size; -} __attribute__((packed)); - -/* - * Command Structure to configure AAC Encoder - */ - -#define AUDPREPROC_AUDREC_CMD_PARAM_CFG_AAC_LEN \ - sizeof(struct audpreproc_audrec_cmd_parm_cfg_aac) - -struct audpreproc_audrec_cmd_parm_cfg_aac { - struct audpreproc_audrec_cmd_param_cfg_common common; - unsigned short aud_rec_samplerate_idx; - unsigned short aud_rec_stereo_mode; - signed short recording_quality; -} __attribute__((packed)); - -/* - * Command Structure to configure SBC Encoder - */ - -#define AUDPREPROC_AUDREC_CMD_PARAM_CFG_SBC_LEN \ - sizeof(struct audpreproc_audrec_cmd_parm_cfg_sbc) - -/* encoder parameters mask definitions*/ - -#define AUDREC_SBC_ENC_PARAM_VER_MASK 0x000A -#define AUDREC_SBC_ENC_PARAM_ENAHANCED_SBC_BASELINE_VERSION 0x0000 -#define AUDREC_SBC_ENC_PARAM_ENAHANCED_SBC_NA_MASK 0x0400 -#define AUDREC_SBC_ENC_PARAM_BIT_ALLOC_MASK 0x0008 -#define AUDREC_SBC_ENC_PARAM_SNR_MASK 0x0100 -#define AUDREC_SBC_ENC_PARAM_MODE_MASK 0x0006 -#define AUDREC_SBC_ENC_PARAM_MODE_DUAL_MASK 0x0040 -#define AUDREC_SBC_ENC_PARAM_MODE_STEREO_MASK 0x0080 -#define AUDREC_SBC_ENC_PARAM_MODE_JOINT_STEREO_MASK 0x00C0 -#define AUDREC_SBC_ENC_PARAM_NUM_SUB_BANDS_MASK 0x0004 -#define AUDREC_SBC_ENC_PARAM_NUM_SUB_BANDS_8_MASK 0x0001 -#define AUDREC_SBC_ENC_PARAM_NUM_SUB_BLOCKS_MASK 0x0000 -#define AUDREC_SBC_ENC_PARAM_NUM_SUB_BLOCKS_4_MASK 0x0000 -#define AUDREC_SBC_ENC_PARAM_NUM_SUB_BLOCKS_8_MASK 0x0001 -#define AUDREC_SBC_ENC_PARAM_NUM_SUB_BLOCKS_12_MASK 0x0002 -#define AUDREC_SBC_ENC_PARAM_NUM_SUB_BLOCKS_16_MASK 0x0003 - -struct audpreproc_audrec_cmd_parm_cfg_sbc { - struct audpreproc_audrec_cmd_param_cfg_common common; - unsigned short aud_rec_sbc_enc_param; - unsigned short aud_rec_sbc_bit_rate_msw; - unsigned short aud_rec_sbc_bit_rate_lsw; -} __attribute__((packed)); - -/* - * Command Structure to configure AMRNB Encoder - */ - -#define AUDPREPROC_AUDREC_CMD_PARAM_CFG_AMRNB_LEN \ - sizeof(struct audpreproc_audrec_cmd_parm_cfg_amrnb) - -#define AMRNB_DTX_MODE_ENABLE -1 -#define AMRNB_DTX_MODE_DISABLE 0 - -#define AMRNB_TEST_MODE_ENABLE -1 -#define AMRNB_TEST_MODE_DISABLE 0 - -#define AMRNB_USED_MODE_MR475 0x0 -#define AMRNB_USED_MODE_MR515 0x1 -#define AMRNB_USED_MODE_MR59 0x2 -#define AMRNB_USED_MODE_MR67 0x3 -#define AMRNB_USED_MODE_MR74 0x4 -#define AMRNB_USED_MODE_MR795 0x5 -#define AMRNB_USED_MODE_MR102 0x6 -#define AMRNB_USED_MODE_MR122 0x7 - -struct audpreproc_audrec_cmd_parm_cfg_amrnb { - struct audpreproc_audrec_cmd_param_cfg_common common; - signed short dtx_mode; - signed short test_mode; - unsigned short used_mode; -} __attribute__((packed)) ; - -/* - * Command Structure to configure EVRC Encoder - */ - -#define AUDPREPROC_AUDREC_CMD_PARAM_CFG_EVRC_LEN \ - sizeof(struct audpreproc_audrec_cmd_parm_cfg_evrc) - -struct audpreproc_audrec_cmd_parm_cfg_evrc { - struct audpreproc_audrec_cmd_param_cfg_common common; - unsigned short enc_min_rate; - unsigned short enc_max_rate; - unsigned short rate_modulation_cmd; -} __attribute__((packed)); - -/* - * Command Structure to configure QCELP_13K Encoder - */ - -#define AUDPREPROC_AUDREC_CMD_PARAM_CFG_QCELP13K_LEN \ - sizeof(struct audpreproc_audrec_cmd_parm_cfg_qcelp13k) - -struct audpreproc_audrec_cmd_parm_cfg_qcelp13k { - struct audpreproc_audrec_cmd_param_cfg_common common; - unsigned short enc_min_rate; - unsigned short enc_max_rate; - unsigned short rate_modulation_cmd; - unsigned short reduced_rate_level; -} __attribute__((packed)); - -/* - * Command to configure AFE for recording paths - */ -#define AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG 0x0002 - -#define AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG_LEN \ - sizeof(struct audpreproc_afe_cmd_audio_record_cfg) - -#define AUDIO_RECORDING_TURN_ON 0xFFFF -#define AUDIO_RECORDING_TURN_OFF 0x0000 - -#define AUDPP_A2DP_PIPE_SOURCE_MIX_MASK 0x0020 -#define VOICE_DL_SOURCE_MIX_MASK 0x0010 -#define VOICE_UL_SOURCE_MIX_MASK 0x0008 -#define FM_SOURCE_MIX_MASK 0x0004 -#define AUX_CODEC_TX_SOURCE_MIX_MASK 0x0002 -#define INTERNAL_CODEC_TX_SOURCE_MIX_MASK 0x0001 - -struct audpreproc_afe_cmd_audio_record_cfg { - unsigned short cmd_id; - unsigned short stream_id; - unsigned short destination_activity; - unsigned short source_mix_mask; - unsigned short pipe_id; - unsigned short reserved; -} __attribute__((packed)); - -/* - * Command to configure Tunnel(RT) or Non-Tunnel(FTRT) mode - */ -#define AUDPREPROC_AUDREC_CMD_ROUTING_MODE 0x0003 -#define AUDPREPROC_AUDREC_CMD_ROUTING_MODE_LEN \ - sizeof(struct audpreproc_audrec_cmd_routing_mode) - -#define AUDIO_ROUTING_MODE_FTRT 0x0001 -#define AUDIO_ROUTING_MODE_RT 0x0002 - -struct audpreproc_audrec_cmd_routing_mode { - unsigned short cmd_id; - unsigned short stream_id; - unsigned short routing_mode; -} __attribute__((packed)); - -/* - * Command to configure DSP for topology where resampler moved - * in front of pre processing chain - */ -#define AUDPREPROC_AUDREC_CMD_ENC_CFG_2 0x0004 -#define AUDPREPROC_AUDREC_CMD_ENC_CFG_2_LEN \ - sizeof(struct audpreproc_audrec_cmd_enc_cfg_2) - - -struct audpreproc_audrec_cmd_enc_cfg_2 { - unsigned short cmd_id; - unsigned short stream_id; - unsigned short audrec_enc_type; -} __attribute__((packed)); - -/* - * AUDIOPREPROC COMMANDS: - * ARM uses uPAudPreProcCmdQueue to communicate with AUDPREPROCTASK - * Location : MEMB - * Buffer size : 52 - * Number of buffers in a queue : 3 - */ - -/* - * Command to configure the parameters of AGC - */ - -#define AUDPREPROC_CMD_CFG_AGC_PARAMS 0x0000 -#define AUDPREPROC_CMD_CFG_AGC_PARAMS_LEN \ - sizeof(struct audpreproc_cmd_cfg_agc_params) - -#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_SLOPE 0x0200 -#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_TH 0x0400 -#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_SLOPE 0x0800 -#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_TH 0x1000 -#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_AIG_FLAG 0x2000 -#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_STATIC_GAIN 0x4000 -#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG 0x8000 - -#define AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA -1 -#define AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS 0x0000 - -#define AUDPREPROC_CMD_ADP_GAIN_FLAG_ENA_ADP_GAIN -1 -#define AUDPREPROC_CMD_ADP_GAIN_FLAG_ENA_STATIC_GAIN 0x0000 - -#define AUDPREPROC_CMD_PARAM_MASK_RMS_TAY 0x0010 -#define AUDPREPROC_CMD_PARAM_MASK_RELEASEK 0x0020 -#define AUDPREPROC_CMD_PARAM_MASK_DELAY 0x0040 -#define AUDPREPROC_CMD_PARAM_MASK_ATTACKK 0x0080 -#define AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_SLOW 0x0100 -#define AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_FAST 0x0200 -#define AUDPREPROC_CMD_PARAM_MASK_AIG_RELEASEK 0x0400 -#define AUDPREPROC_CMD_PARAM_MASK_AIG_MIN 0x0800 -#define AUDPREPROC_CMD_PARAM_MASK_AIG_MAX 0x1000 -#define AUDPREPROC_CMD_PARAM_MASK_LEAK_UP 0x2000 -#define AUDPREPROC_CMD_PARAM_MASK_LEAK_DOWN 0x4000 -#define AUDPREPROC_CMD_PARAM_MASK_AIG_ATTACKK 0x8000 - -struct audpreproc_cmd_cfg_agc_params { - unsigned short cmd_id; - unsigned short stream_id; - unsigned short tx_agc_param_mask; - signed short tx_agc_enable_flag; - unsigned short comp_rlink_static_gain; - signed short comp_rlink_aig_flag; - unsigned short expander_rlink_th; - unsigned short expander_rlink_slope; - unsigned short compressor_rlink_th; - unsigned short compressor_rlink_slope; - unsigned short tx_adc_agc_param_mask; - unsigned short comp_rlink_aig_attackk; - unsigned short comp_rlink_aig_leak_down; - unsigned short comp_rlink_aig_leak_up; - unsigned short comp_rlink_aig_max; - unsigned short comp_rlink_aig_min; - unsigned short comp_rlink_aig_releasek; - unsigned short comp_rlink_aig_leakrate_fast; - unsigned short comp_rlink_aig_leakrate_slow; - unsigned short comp_rlink_attackk_msw; - unsigned short comp_rlink_attackk_lsw; - unsigned short comp_rlink_delay; - unsigned short comp_rlink_releasek_msw; - unsigned short comp_rlink_releasek_lsw; - unsigned short comp_rlink_rms_tav; -} __attribute__((packed)); - -/* - * Command to configure the params of Advanved AGC - */ - -#define AUDPREPROC_CMD_CFG_AGC_PARAMS_2 0x0001 -#define AUDPREPROC_CMD_CFG_AGC_PARAMS_2_LEN \ - sizeof(struct audpreproc_cmd_cfg_agc_params_2) - -#define AUDPREPROC_CMD_2_TX_AGC_ENA_FLAG_ENA -1; -#define AUDPREPROC_CMD_2_TX_AGC_ENA_FLAG_DIS 0x0000; - -struct audpreproc_cmd_cfg_agc_params_2 { - unsigned short cmd_id; - unsigned short stream_id; - unsigned short agc_param_mask; - signed short tx_agc_enable_flag; - unsigned short comp_rlink_static_gain; - unsigned short exp_rlink_th; - unsigned short exp_rlink_slope; - unsigned short comp_rlink_th; - unsigned short comp_rlink_slope; - unsigned short comp_rlink_rms_tav; - unsigned short comp_rlink_down_samp_mask; - unsigned short comp_rlink_attackk_msw; - unsigned short comp_rlink_attackk_lsw; - unsigned short comp_rlink_releasek_msw; - unsigned short comp_rlink_releasek_lsw; - unsigned short comp_rlink_delay; - unsigned short comp_rlink_makeup_gain; -} __attribute__((packed)); - -/* - * Command to configure params for ns - */ - -#define AUDPREPROC_CMD_CFG_NS_PARAMS 0x0002 -#define AUDPREPROC_CMD_CFG_NS_PARAMS_LEN \ - sizeof(struct audpreproc_cmd_cfg_ns_params) - -#define AUDPREPROC_CMD_EC_MODE_NLMS_ENA 0x0001 -#define AUDPREPROC_CMD_EC_MODE_NLMS_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_DES_ENA 0x0002 -#define AUDPREPROC_CMD_EC_MODE_DES_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_NS_ENA 0x0004 -#define AUDPREPROC_CMD_EC_MODE_NS_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_CNI_ENA 0x0008 -#define AUDPREPROC_CMD_EC_MODE_CNI_DIS 0x0000 - -#define AUDPREPROC_CMD_EC_MODE_NLES_ENA 0x0010 -#define AUDPREPROC_CMD_EC_MODE_NLES_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_HB_ENA 0x0020 -#define AUDPREPROC_CMD_EC_MODE_HB_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_VA_ENA 0x0040 -#define AUDPREPROC_CMD_EC_MODE_VA_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_PCD_ENA 0x0080 -#define AUDPREPROC_CMD_EC_MODE_PCD_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_FEHI_ENA 0x0100 -#define AUDPREPROC_CMD_EC_MODE_FEHI_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_NEHI_ENA 0x0200 -#define AUDPREPROC_CMD_EC_MODE_NEHI_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_NLPP_ENA 0x0400 -#define AUDPREPROC_CMD_EC_MODE_NLPP_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_FNE_ENA 0x0800 -#define AUDPREPROC_CMD_EC_MODE_FNE_DIS 0x0000 -#define AUDPREPROC_CMD_EC_MODE_PRENLMS_ENA 0x1000 -#define AUDPREPROC_CMD_EC_MODE_PRENLMS_DIS 0x0000 - -struct audpreproc_cmd_cfg_ns_params { - unsigned short cmd_id; - unsigned short stream_id; - unsigned short ec_mode_new; - unsigned short dens_gamma_n; - unsigned short dens_nfe_block_size; - unsigned short dens_limit_ns; - unsigned short dens_limit_ns_d; - unsigned short wb_gamma_e; - unsigned short wb_gamma_n; -} __attribute__((packed)); - -/* - * Command to configure parameters for IIR tuning filter - */ - -#define AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS 0x0003 -#define AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS_LEN \ - sizeof(struct audpreproc_cmd_cfg_iir_tuning_filter_params) - -#define AUDPREPROC_CMD_IIR_ACTIVE_FLAG_DIS 0x0000 -#define AUDPREPROC_CMD_IIR_ACTIVE_FLAG_ENA 0x0001 - -struct audpreproc_cmd_cfg_iir_tuning_filter_params { - unsigned short cmd_id; - unsigned short stream_id; - unsigned short active_flag; - unsigned short num_bands; - - unsigned short numerator_coeff_b0_filter0_lsw; - unsigned short numerator_coeff_b0_filter0_msw; - unsigned short numerator_coeff_b1_filter0_lsw; - unsigned short numerator_coeff_b1_filter0_msw; - unsigned short numerator_coeff_b2_filter0_lsw; - unsigned short numerator_coeff_b2_filter0_msw; - - unsigned short numerator_coeff_b0_filter1_lsw; - unsigned short numerator_coeff_b0_filter1_msw; - unsigned short numerator_coeff_b1_filter1_lsw; - unsigned short numerator_coeff_b1_filter1_msw; - unsigned short numerator_coeff_b2_filter1_lsw; - unsigned short numerator_coeff_b2_filter1_msw; - - unsigned short numerator_coeff_b0_filter2_lsw; - unsigned short numerator_coeff_b0_filter2_msw; - unsigned short numerator_coeff_b1_filter2_lsw; - unsigned short numerator_coeff_b1_filter2_msw; - unsigned short numerator_coeff_b2_filter2_lsw; - unsigned short numerator_coeff_b2_filter2_msw; - - unsigned short numerator_coeff_b0_filter3_lsw; - unsigned short numerator_coeff_b0_filter3_msw; - unsigned short numerator_coeff_b1_filter3_lsw; - unsigned short numerator_coeff_b1_filter3_msw; - unsigned short numerator_coeff_b2_filter3_lsw; - unsigned short numerator_coeff_b2_filter3_msw; - - unsigned short denominator_coeff_a0_filter0_lsw; - unsigned short denominator_coeff_a0_filter0_msw; - unsigned short denominator_coeff_a1_filter0_lsw; - unsigned short denominator_coeff_a1_filter0_msw; - - unsigned short denominator_coeff_a0_filter1_lsw; - unsigned short denominator_coeff_a0_filter1_msw; - unsigned short denominator_coeff_a1_filter1_lsw; - unsigned short denominator_coeff_a1_filter1_msw; - - unsigned short denominator_coeff_a0_filter2_lsw; - unsigned short denominator_coeff_a0_filter2_msw; - unsigned short denominator_coeff_a1_filter2_lsw; - unsigned short denominator_coeff_a1_filter2_msw; - - unsigned short denominator_coeff_a0_filter3_lsw; - unsigned short denominator_coeff_a0_filter3_msw; - unsigned short denominator_coeff_a1_filter3_lsw; - unsigned short denominator_coeff_a1_filter3_msw; - - unsigned short shift_factor_filter0; - unsigned short shift_factor_filter1; - unsigned short shift_factor_filter2; - unsigned short shift_factor_filter3; - - unsigned short pan_of_filter0; - unsigned short pan_of_filter1; - unsigned short pan_of_filter2; - unsigned short pan_of_filter3; -} __attribute__((packed)); - -/* - * Command to configure parameters for calibration gain rx - */ - -#define AUDPREPROC_CMD_CFG_CAL_GAIN_PARAMS 0x0004 -#define AUDPREPROC_CMD_CFG_CAL_GAIN_LEN \ - sizeof(struct audpreproc_cmd_cfg_cal_gain) - -struct audpreproc_cmd_cfg_cal_gain { - unsigned short cmd_id; - unsigned short stream_id; - unsigned short audprecalgain; - unsigned short reserved; -} __attribute__((packed)); - -#define AUDPREPROC_CMD_CFG_LVNV_PARMS 0x0006 -#define AUDPREPROC_CMD_CFG_LVNV_PARMS_LEN \ - sizeof(struct audpreproc_cmd_cfg_lvnv_param) - -struct audpreproc_cmd_cfg_lvnv_param { - unsigned short cmd_id; - unsigned short stream_id; - unsigned short cs_mode; - unsigned short lvnv_ext_buf_size; - unsigned short lvnv_ext_partition; - unsigned short lvnv_ext_buf_start_lsw; - unsigned short lvnv_ext_buf_start_msw; -}; - -#define AUDPREPROC_CMD_FEAT_QUERY_PARAMS 0x0005 - -struct rtc_audpreproc_read_data { - unsigned short cmd_id; - unsigned short stream_id; - unsigned short feature_id; - unsigned short extbufsizemsw; - unsigned short extbufsizelsw; - unsigned short extpart; - unsigned short extbufstartmsw; - unsigned short extbufstartlsw; -} __attribute__((packed)) ; - -#endif /* QDSP5AUDPREPROCCMDI_H */ diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreprocmsg.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreprocmsg.h deleted file mode 100644 index d3efbcd2f68d0ece9e56f5f71127adcc63b40918..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreprocmsg.h +++ /dev/null @@ -1,127 +0,0 @@ -/* Copyright (c) 2009-2010, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef QDSP5AUDPREPROCMSG_H -#define QDSP5AUDPREPROCMSG_H - -#define AUDPREPROC_MSG_FEAT_QUERY_DM_DONE 0x0006 - -/* - * ADSPREPROCTASK Messages - * AUDPREPROCTASK uses audPreProcUpRlist to communicate with ARM - * Location : MEMB - * Buffer size : 6 - * No of buffers in queue : 4 - */ - -/* - * Message to indicate Pre processing config command is done - */ - -#define AUDPREPROC_CMD_CFG_DONE_MSG 0x0001 -#define AUDPREPROC_CMD_CFG_DONE_MSG_LEN \ - sizeof(struct audpreproc_cmd_cfg_done_msg) - -#define AUD_PREPROC_TYPE_AGC 0x0 -#define AUD_PREPROC_NOISE_REDUCTION 0x1 -#define AUD_PREPROC_IIR_TUNNING_FILTER 0x2 - -#define AUD_PREPROC_CONFIG_ENABLED -1 -#define AUD_PREPROC_CONFIG_DISABLED 0 - -struct audpreproc_cmd_cfg_done_msg { - unsigned short stream_id; - unsigned short aud_preproc_type; - signed short aud_preproc_status_flag; -} __attribute__((packed)); - -/* - * Message to indicate Pre processing error messages - */ - -#define AUDPREPROC_ERROR_MSG 0x0002 -#define AUDPREPROC_ERROR_MSG_LEN \ - sizeof(struct audpreproc_err_msg) - -#define AUD_PREPROC_ERR_IDX_WRONG_SAMPLING_FREQUENCY 0x00 -#define AUD_PREPROC_ERR_IDX_ENC_NOT_SUPPORTED 0x01 - -struct audpreproc_err_msg { - unsigned short stream_id; - signed short aud_preproc_err_idx; -} __attribute__((packed)); - -/* - * Message to indicate encoder config command - */ - -#define AUDPREPROC_CMD_ENC_CFG_DONE_MSG 0x0003 -#define AUDPREPROC_CMD_ENC_CFG_DONE_MSG_LEN \ - sizeof(struct audpreproc_cmd_enc_cfg_done_msg) - -struct audpreproc_cmd_enc_cfg_done_msg { - unsigned short stream_id; - unsigned short rec_enc_type; -} __attribute__((packed)); - -/* - * Message to indicate encoder param config command - */ - -#define AUDPREPROC_CMD_ENC_PARAM_CFG_DONE_MSG 0x0004 -#define AUDPREPROC_CMD_ENC_PARAM_CFG_DONE_MSG_LEN \ - sizeof(struct audpreproc_cmd_enc_param_cfg_done_msg) - -struct audpreproc_cmd_enc_param_cfg_done_msg { - unsigned short stream_id; -} __attribute__((packed)); - - -/* - * Message to indicate AFE config cmd for - * audio recording is successfully recieved - */ - -#define AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG_DONE_MSG 0x0005 -#define AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG_DONE_MSG_LEN \ - sizeof(struct audpreproc_afe_cmd_audio_record_cfg_done) - -struct audpreproc_afe_cmd_audio_record_cfg_done { - unsigned short stream_id; -} __attribute__((packed)); - -/* - * Message to indicate Routing mode - * configuration success or failure - */ - -#define AUDPREPROC_CMD_ROUTING_MODE_DONE_MSG 0x0007 -#define AUDPREPROC_CMD_ROUTING_MODE_DONE_MSG_LEN \ - sizeof(struct audpreproc_cmd_routing_mode_done) - -struct audpreproc_cmd_routing_mode_done { - unsigned short stream_id; - unsigned short configuration; -} __attribute__((packed)); - - -#define AUDPREPROC_CMD_PCM_CFG_ARM_TO_PREPROC_DONE_MSG 0x0008 -#define AUDPREPROC_CMD_PCM_CFG_ARM_TO_PREPROC_DONE_MSG_LEN \ - sizeof(struct audreproc_cmd_pcm_cfg_arm_to_preproc_done) - -struct audreproc_cmd_pcm_cfg_arm_to_preproc_done { - unsigned short stream_id; - unsigned short configuration; -} __attribute__((packed)); - -#endif /* QDSP5AUDPREPROCMSG_H */ diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audreccmdi.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audreccmdi.h deleted file mode 100644 index 49642df182c64d017332bdd350457345b93c1ecc..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audreccmdi.h +++ /dev/null @@ -1,122 +0,0 @@ -/* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef QDSP5AUDRECCMDI_H -#define QDSP5AUDRECCMDI_H - -/* - * AUDRECTASK COMMANDS - * ARM uses 2 queues to communicate with the AUDRECTASK - * 1.uPAudRec[i]CmdQueue, where i=0,1,2 - * Location :MEMC - * Buffer Size : 5 - * No of Buffers in a queue : 2 - * 2.uPAudRec[i]BitstreamQueue, where i=0,1,2 - * Location : MEMC - * Buffer Size : 5 - * No of buffers in a queue : 3 - */ - -/* - * Commands on uPAudRec[i]CmdQueue, where i=0,1,2 - */ - -/* - * Command to configure memory for enabled encoder - */ - -#define AUDREC_CMD_MEM_CFG_CMD 0x0000 -#define AUDREC_CMD_ARECMEM_CFG_LEN \ - sizeof(struct audrec_cmd_arecmem_cfg) - -struct audrec_cmd_arecmem_cfg { - unsigned short cmd_id; - unsigned short audrec_up_pkt_intm_count; - unsigned short audrec_ext_pkt_start_addr_msw; - unsigned short audrec_ext_pkt_start_addr_lsw; - unsigned short audrec_ext_pkt_buf_number; -} __attribute__((packed)); - -/* - * Command to configure pcm input memory - */ - -#define AUDREC_CMD_PCM_CFG_ARM_TO_ENC 0x0001 -#define AUDREC_CMD_PCM_CFG_ARM_TO_ENC_LEN \ - sizeof(struct audrec_cmd_pcm_cfg_arm_to_enc) - -struct audrec_cmd_pcm_cfg_arm_to_enc { - unsigned short cmd_id; - unsigned short config_update_flag; - unsigned short enable_flag; - unsigned short sampling_freq; - unsigned short channels; - unsigned short frequency_of_intimation; - unsigned short max_number_of_buffers; -} __attribute__((packed)); - -#define AUDREC_PCM_CONFIG_UPDATE_FLAG_ENABLE -1 -#define AUDREC_PCM_CONFIG_UPDATE_FLAG_DISABLE 0 - -#define AUDREC_ENABLE_FLAG_VALUE -1 -#define AUDREC_DISABLE_FLAG_VALUE 0 - -/* - * Command to intimate available pcm buffer - */ - -#define AUDREC_CMD_PCM_BUFFER_PTR_REFRESH_ARM_TO_ENC 0x0002 -#define AUDREC_CMD_PCM_BUFFER_PTR_REFRESH_ARM_TO_ENC_LEN \ - sizeof(struct audrec_cmd_pcm_buffer_ptr_refresh_arm_enc) - -struct audrec_cmd_pcm_buffer_ptr_refresh_arm_enc { - unsigned short cmd_id; - unsigned short num_buffers; - unsigned short buffer_write_cnt_msw; - unsigned short buffer_write_cnt_lsw; - unsigned short buf_address_length[8];/*this array holds address - and length details of - two buffers*/ -} __attribute__((packed)); - -/* - * Command to flush - */ - -#define AUDREC_CMD_FLUSH 0x0003 -#define AUDREC_CMD_FLUSH_LEN \ - sizeof(struct audrec_cmd_flush) - -struct audrec_cmd_flush { - unsigned short cmd_id; -} __attribute__((packed)); - -/* - * Commands on uPAudRec[i]BitstreamQueue, where i=0,1,2 - */ - -/* - * Command to indicate current packet read count - */ - -#define UP_AUDREC_PACKET_EXT_PTR 0x0000 -#define UP_AUDREC_PACKET_EXT_PTR_LEN \ - sizeof(up_audrec_packet_ext_ptr) - -struct up_audrec_packet_ext_ptr { - unsigned short cmd_id; - unsigned short audrec_up_curr_read_count_lsw; - unsigned short audrec_up_curr_read_count_msw; -} __attribute__((packed)); - -#endif /* QDSP5AUDRECCMDI_H */ diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audrecmsg.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audrecmsg.h deleted file mode 100644 index eb4623585845990b43eb4e553ab011af5e79a041..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audrecmsg.h +++ /dev/null @@ -1,115 +0,0 @@ -/* Copyright (c) 2009-2010, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef QDSP5AUDRECMSG_H -#define QDSP5AUDRECMSG_H - -/* - * AUDRECTASK MESSAGES - * AUDRECTASK uses audRec[i]UpRlist, where i=0,1,2 to communicate with ARM - * Location : MEMC - * Buffer size : 5 - * No of buffers in a queue : 10 - */ - -/* - * Message to notify 2 error conditions - */ - -#define AUDREC_FATAL_ERR_MSG 0x0001 -#define AUDREC_FATAL_ERR_MSG_LEN \ - sizeof(struct audrec_fatal_err_msg) - -#define AUDREC_FATAL_ERR_MSG_NO_PKT 0x00 - -struct audrec_fatal_err_msg { - unsigned short audrec_err_id; -} __attribute__((packed)); - -/* - * Message to indicate encoded packet is delivered to external buffer - */ - -#define AUDREC_UP_PACKET_READY_MSG 0x0002 -#define AUDREC_UP_PACKET_READY_MSG_LEN \ - sizeof(struct audrec_up_pkt_ready_msg) - -struct audrec_up_pkt_ready_msg { - unsigned short audrec_packet_write_cnt_lsw; - unsigned short audrec_packet_write_cnt_msw; - unsigned short audrec_up_prev_read_cnt_lsw; - unsigned short audrec_up_prev_read_cnt_msw; -} __attribute__((packed)); - -/* - * Message indicates arecmem cfg done - */ -#define AUDREC_CMD_MEM_CFG_DONE_MSG 0x0003 - -/* buffer conntents are nill only message id is required */ - -/* - * Message to indicate pcm buffer configured - */ - -#define AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG 0x0004 -#define AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG_LEN \ - sizeof(struct audrec_cmd_pcm_cfg_arm_to_enc_msg) - -struct audrec_cmd_pcm_cfg_arm_to_enc_msg { - unsigned short configuration; -} __attribute__((packed)); - -/* - * Message to indicate encoded packet is delivered to external buffer in FTRT - */ - -#define AUDREC_UP_NT_PACKET_READY_MSG 0x0005 -#define AUDREC_UP_NT_PACKET_READY_MSG_LEN \ - sizeof(struct audrec_up_nt_packet_ready_msg) - -struct audrec_up_nt_packet_ready_msg { - unsigned short audrec_packetwrite_cnt_lsw; - unsigned short audrec_packetwrite_cnt_msw; - unsigned short audrec_upprev_readcount_lsw; - unsigned short audrec_upprev_readcount_msw; -} __attribute__((packed)); - -/* - * Message to indicate pcm buffer is consumed - */ - -#define AUDREC_CMD_PCM_BUFFER_PTR_UPDATE_ARM_TO_ENC_MSG 0x0006 -#define AUDREC_CMD_PCM_BUFFER_PTR_UPDATE_ARM_TO_ENC_MSG_LEN \ - sizeof(struct audrec_cmd_pcm_buffer_ptr_update_arm_to_enc_msg) - -struct audrec_cmd_pcm_buffer_ptr_update_arm_to_enc_msg { - unsigned short buffer_readcnt_msw; - unsigned short buffer_readcnt_lsw; - unsigned short number_of_buffers; - unsigned short buffer_address_length[]; -} __attribute__((packed)); - -/* - * Message to indicate flush acknowledgement - */ - -#define AUDREC_CMD_FLUSH_DONE_MSG 0x0007 - -/* - * Message to indicate End of Stream acknowledgement - */ - -#define AUDREC_CMD_EOS_ACK_MSG 0x0008 - -#endif /* QDSP5AUDRECMSG_H */ diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_ecodec.h b/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_ecodec.h deleted file mode 100644 index 8e7d96c5657a9692e92866ab92d87bb29fcfe08d..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_ecodec.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef __MACH_QDSP5_V2_SNDDEV_ECODEC_H -#define __MACH_QDSP5_V2_SNDDEV_ECODEC_H -#include - -struct snddev_ecodec_data { - u32 capability; /* RX or TX */ - const char *name; - u32 copp_id; /* audpp routing */ - u32 acdb_id; /* Audio Cal purpose */ - u8 channel_mode; - u32 conf_pcm_ctl_val; - u32 conf_aux_codec_intf; - u32 conf_data_format_padding_val; - s32 max_voice_rx_vol[VOC_RX_VOL_ARRAY_NUM]; /* [0]:NB, [1]:WB */ - s32 min_voice_rx_vol[VOC_RX_VOL_ARRAY_NUM]; -}; -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_icodec.h b/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_icodec.h deleted file mode 100644 index 7a811a0be7ab0fef1ef36750e423de6361e95e4f..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_icodec.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef __MACH_QDSP5_V2_SNDDEV_ICODEC_H -#define __MACH_QDSP5_V2_SNDDEV_ICODEC_H -#include -#include -#include - -struct snddev_icodec_data { - u32 capability; /* RX or TX */ - const char *name; - u32 copp_id; /* audpp routing */ - u32 acdb_id; /* Audio Cal purpose */ - /* Adie profile */ - struct adie_codec_dev_profile *profile; - /* Afe setting */ - u8 channel_mode; - enum hsed_controller *pmctl_id; /* tx only enable mic bias */ - u32 pmctl_id_sz; - u32 default_sample_rate; - void (*pamp_on) (void); - void (*pamp_off) (void); - void (*voltage_on) (void); - void (*voltage_off) (void); - s32 max_voice_rx_vol[VOC_RX_VOL_ARRAY_NUM]; /* [0]: NB,[1]: WB */ - s32 min_voice_rx_vol[VOC_RX_VOL_ARRAY_NUM]; - u32 dev_vol_type; - u32 property; /*variable used to hold the properties - internal to the device*/ -}; -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_mi2s.h b/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_mi2s.h deleted file mode 100644 index a8f5234421250ed2f3fdda8c4105d94f5f2df915..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_mi2s.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (c) 2010, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef __MACH_QDSP5_V2_SNDDEV_MI2S_H -#define __MACH_QDSP5_V2_SNDDEV_MI2S_H - -struct snddev_mi2s_data { - u32 capability; /* RX or TX */ - const char *name; - u32 copp_id; /* audpp routing */ - u32 acdb_id; /* Audio Cal purpose */ - u8 channel_mode; - u8 sd_lines; - void (*route) (void); - void (*deroute) (void); - u32 default_sample_rate; -}; - -int mi2s_config_clk_gpio(void); - -int mi2s_config_data_gpio(u32 direction, u8 sd_line_mask); - -int mi2s_unconfig_clk_gpio(void); - -int mi2s_unconfig_data_gpio(u32 direction, u8 sd_line_mask); - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_virtual.h b/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_virtual.h deleted file mode 100644 index 639e981f1cb784b8377abc0f0e0faad587059e12..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_virtual.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2010, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef __MACH_QDSP5_V2_SNDDEV_VIRTUAL_H -#define __MACH_QDSP5_V2_SNDDEV_VIRTUAL_H -#include - -struct snddev_virtual_data { - u32 capability; /* RX or TX */ - const char *name; - u32 copp_id; /* audpp routing */ - u32 acdb_id; /* Audio Cal purpose */ -}; -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/voice.h b/arch/arm/mach-msm/include/mach/qdsp5v2/voice.h deleted file mode 100644 index 93f9bad2943a032f24fc15849ac365d9401b6af0..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/voice.h +++ /dev/null @@ -1,117 +0,0 @@ -/* Copyright (c) 2009-2010, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef _MACH_QDSP5_V2_VOICE_H -#define _MACH_QDSP5_V2_VOICE_H - -#define VOICE_DALRPC_DEVICEID 0x02000075 -#define VOICE_DALRPC_PORT_NAME "DAL00" -#define VOICE_DALRPC_CPU 0 - - -/* Commands sent to Modem */ -#define CMD_VOICE_INIT 0x1 -#define CMD_ACQUIRE_DONE 0x2 -#define CMD_RELEASE_DONE 0x3 -#define CMD_DEVICE_INFO 0x4 -#define CMD_DEVICE_CHANGE 0x6 - -/* EVENTS received from MODEM */ -#define EVENT_ACQUIRE_START 0x51 -#define EVENT_RELEASE_START 0x52 -#define EVENT_CHANGE_START 0x54 -#define EVENT_NETWORK_RECONFIG 0x53 - -/* voice state */ -enum { - VOICE_INIT = 0, - VOICE_ACQUIRE, - VOICE_CHANGE, - VOICE_RELEASE, -}; - -enum { - NETWORK_CDMA = 0, - NETWORK_GSM, - NETWORK_WCDMA, - NETWORK_WCDMA_WB, -}; - -enum { - VOICE_DALRPC_CMD = DALDEVICE_FIRST_DEVICE_API_IDX -}; - -/* device state */ -enum { - DEV_INIT = 0, - DEV_READY, - DEV_CHANGE, - DEV_CONCUR, - DEV_REL_DONE, -}; - -/* Voice Event */ -enum{ - VOICE_RELEASE_START = 1, - VOICE_CHANGE_START, - VOICE_ACQUIRE_START, - VOICE_NETWORK_RECONFIG, -}; - -/* Device Event */ -#define DEV_CHANGE_READY 0x1 - -#define VOICE_CALL_START 0x1 -#define VOICE_CALL_END 0 - -#define VOICE_DEV_ENABLED 0x1 -#define VOICE_DEV_DISABLED 0 - -struct voice_header { - uint32_t id; - uint32_t data_len; -}; - -struct voice_init { - struct voice_header hdr; - void *cb_handle; -}; - - -/* Device information payload structure */ -struct voice_device { - struct voice_header hdr; - uint32_t rx_device; - uint32_t tx_device; - uint32_t rx_volume; - uint32_t rx_mute; - uint32_t tx_mute; - uint32_t rx_sample; - uint32_t tx_sample; -}; - -/*Voice command structure*/ -struct voice_network { - struct voice_header hdr; - uint32_t network_info; -}; - -struct device_data { - uint32_t dev_acdb_id; - uint32_t volume; /* in percentage */ - uint32_t mute; - uint32_t sample; - uint32_t enabled; - uint32_t dev_id; -}; - -#endif diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_def.h b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_def.h old mode 100644 new mode 100755 similarity index 86% rename from arch/arm/mach-msm/include/mach/qdsp5v2/audio_def.h rename to arch/arm/mach-msm/include/mach/qdsp6v2/audio_def.h index 35a4d5c2f794761d3fcac17d4205cf2861e38d5e..9f76419cbf8100b6e5d2182e9903a83d37dbda98 --- a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_def.h +++ b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_def.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2009,2011, The Linux Foundation. All rights reserved. +/* Copyright (c) 2009,2011,2013 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -10,8 +10,8 @@ * GNU General Public License for more details. * */ -#ifndef _MACH_QDSP5_V2_AUDIO_DEF_H -#define _MACH_QDSP5_V2_AUDIO_DEF_H +#ifndef _MACH_QDSP6_V2_AUDIO_DEF_H +#define _MACH_QDSP6_V2_AUDIO_DEF_H /* Define sound device capability */ #define SNDDEV_CAP_RX 0x1 /* RX direction */ @@ -32,4 +32,4 @@ #define SIDE_TONE_MASK 0x01 -#endif /* _MACH_QDSP5_V2_AUDIO_DEF_H */ +#endif /* _MACH_QDSP6_V2_AUDIO_DEF_H */ diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_dev_ctl.h b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_dev_ctl.h index 6b2d7ccf52ad710eab8be7ef74b62651ac27617b..5de63dc9fd1b0549712e028791d387ddd17dbe1e 100644 --- a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_dev_ctl.h +++ b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_dev_ctl.h @@ -12,7 +12,7 @@ */ #ifndef __MACH_QDSP6_V2_SNDDEV_H #define __MACH_QDSP6_V2_SNDDEV_H -#include +#include #include #define AUDIO_DEV_CTL_MAX_DEV 64 diff --git a/arch/arm/mach-msm/qdsp5/Makefile b/arch/arm/mach-msm/qdsp5/Makefile deleted file mode 100644 index 89648febc179b730af74961a380e97d13f15a29f..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -obj-y += adsp.o adsp_driver.o adsp_info.o adsp_rm.o dsp_debug.o adsp_debug.o -obj-y += adsp_video_verify_cmd.o -obj-y += adsp_videoenc_verify_cmd.o -obj-y += adsp_jpeg_verify_cmd.o adsp_jpeg_patch_event.o -obj-y += adsp_vfe_verify_cmd.o adsp_vfe_patch_event.o -obj-y += adsp_lpm_verify_cmd.o -ifdef CONFIG_MSM7X27A_AUDIO -obj-y += audio_pcm_in.o -obj-$(CONFIG_DEBUG_FS) += audio_voice_lb.o -else -obj-y += audio_in.o snd_pcm_client.o -endif -obj-$(CONFIG_MSM7X27A_AUDIO) += audio_aac_in.o audio_evrc_in.o audio_qcelp_in.o -obj-y += audio_out.o audio_mp3.o audmgr.o audpp.o audrec.o audpreproc.o -obj-y += audio_evrc.o audio_qcelp.o audio_amrnb.o audio_aac.o audio_amrnb_in.o -obj-y += audio_wma.o audio_voicememo.o audio_pcm.o audio_amrwb.o audio_wmapro.o -obj-y += snd.o snd_adie.o -obj-$(CONFIG_ARCH_MSM7X27A) += audio_fm.o -obj-$(CONFIG_ARCH_MSM7X27A) += audio_mvs.o -obj-$(CONFIG_ARCH_MSM7X27A) += audio_lpa.o audio_ac3.o diff --git a/arch/arm/mach-msm/qdsp5/adsp.c b/arch/arm/mach-msm/qdsp5/adsp.c deleted file mode 100644 index 85dc6ba5f9f4427d4b6579e84fb87f4908a0de26..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/adsp.c +++ /dev/null @@ -1,1493 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/adsp.c - * - * Register/Interrupt access for userspace aDSP library. - * - * Copyright (C) 2008 Google, Inc. - * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved. - * Author: Iliyan Malchev - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -/* TODO: - * - move shareable rpc code outside of adsp.c - * - general solution for virt->phys patchup - * - queue IDs should be relative to modules - * - disallow access to non-associated queues - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_DEBUG_FS -static struct dentry *dentry_adsp; -static struct dentry *dentry_wdata; -static struct dentry *dentry_rdata; -static int wdump, rdump; -#endif /* CONFIG_DEBUG_FS */ -static struct wake_lock adsp_wake_lock; -static inline void prevent_suspend(void) -{ - wake_lock(&adsp_wake_lock); -} -static inline void allow_suspend(void) -{ - wake_unlock(&adsp_wake_lock); -} - -#include -#include -#include -#include "adsp.h" - -static struct adsp_info adsp_info; -static struct msm_rpc_endpoint *rpc_cb_server_client; -static struct msm_adsp_module *adsp_modules; -static int adsp_open_count; - -static uint32_t rpc_adsp_rtos_atom_prog; -static uint32_t rpc_adsp_rtos_atom_vers; -static uint32_t rpc_adsp_rtos_atom_vers_comp; -static uint32_t rpc_adsp_rtos_mtoa_prog; -static uint32_t rpc_adsp_rtos_mtoa_vers; -static uint32_t rpc_adsp_rtos_mtoa_vers_comp; -static DEFINE_MUTEX(adsp_open_lock); - -static struct workqueue_struct *msm_adsp_probe_work_queue; -static void adsp_probe_work(struct work_struct *work); -static DECLARE_WORK(msm_adsp_probe_work, adsp_probe_work); - -/* protect interactions with the ADSP command/message queue */ -static spinlock_t adsp_cmd_lock; -static spinlock_t adsp_write_lock; - -static uint32_t current_image = -1; - -void adsp_set_image(struct adsp_info *info, uint32_t image) -{ - current_image = image; -} - -/* - * Checks whether the module_id is available in the - * module_entries table.If module_id is available returns `0`. - * If module_id is not available returns `-ENXIO`. - */ -static int32_t adsp_validate_module(uint32_t module_id) -{ - uint32_t *ptr; - uint32_t module_index; - uint32_t num_mod_entries; - - ptr = adsp_info.init_info_ptr->module_entries; - num_mod_entries = adsp_info.init_info_ptr->module_table_size; - - for (module_index = 0; module_index < num_mod_entries; module_index++) - if (module_id == ptr[module_index]) - return 0; - - return -ENXIO; -} - -static int32_t adsp_validate_queue(uint32_t mod_id, unsigned q_idx, - uint32_t size) -{ - int32_t i; - struct adsp_rtos_mp_mtoa_init_info_type *sptr; - - sptr = adsp_info.init_info_ptr; - for (i = 0; i < sptr->mod_to_q_entries; i++) - if (mod_id == sptr->mod_to_q_tbl[i].module) - if (q_idx == sptr->mod_to_q_tbl[i].q_type) { - if (size <= sptr->mod_to_q_tbl[i].q_max_len) - return 0; - MM_ERR("q_idx: %d is not a valid queue \ - for module %x\n", q_idx, mod_id); - return -EINVAL; - } - MM_ERR("cmd_buf size is more than allowed size\n"); - return -EINVAL; -} - -uint32_t adsp_get_module(struct adsp_info *info, uint32_t task) -{ - return info->task_to_module[current_image][task]; -} - -uint32_t adsp_get_queue_offset(struct adsp_info *info, uint32_t queue_id) -{ - return info->queue_offset[current_image][queue_id]; -} - -static int rpc_adsp_rtos_app_to_modem(uint32_t cmd, uint32_t module, - struct msm_adsp_module *adsp_module) -{ - int rc; - struct rpc_adsp_rtos_app_to_modem_args_t rpc_req; - struct rpc_reply_hdr rpc_rsp; - - rpc_req.gotit = cpu_to_be32(1); - rpc_req.cmd = cpu_to_be32(cmd); - rpc_req.proc_id = cpu_to_be32(RPC_ADSP_RTOS_PROC_APPS); - rpc_req.module = cpu_to_be32(module); - rc = msm_rpc_call_reply(adsp_module->rpc_client, - RPC_ADSP_RTOS_APP_TO_MODEM_PROC, - &rpc_req, sizeof(rpc_req), - &rpc_rsp, sizeof(rpc_rsp), - 5 * HZ); - - if (rc < 0) { - MM_ERR("error receiving RPC reply: %d (%d)\n", - rc, -ERESTARTSYS); - return rc; - } - - if (be32_to_cpu(rpc_rsp.reply_stat) != RPCMSG_REPLYSTAT_ACCEPTED) { - MM_ERR("RPC call was denied!\n"); - return -EPERM; - } - - if (be32_to_cpu(rpc_rsp.data.acc_hdr.accept_stat) != - RPC_ACCEPTSTAT_SUCCESS) { - MM_ERR("RPC call was not successful (%d)\n", - be32_to_cpu(rpc_rsp.data.acc_hdr.accept_stat)); - return -EINVAL; - } - - return 0; -} - -static int get_module_index(uint32_t id) -{ - int mod_idx; - for (mod_idx = 0; mod_idx < adsp_info.module_count; mod_idx++) - if (adsp_info.module[mod_idx].id == id) - return mod_idx; - - return -ENXIO; -} - -static struct msm_adsp_module *find_adsp_module_by_id( - struct adsp_info *info, uint32_t id) -{ - int mod_idx; - - if (id > info->max_module_id) { - return NULL; - } else { - mod_idx = get_module_index(id); - if (mod_idx < 0) - return NULL; - return info->id_to_module[mod_idx]; - } -} - -static struct msm_adsp_module *find_adsp_module_by_name( - struct adsp_info *info, const char *name) -{ - unsigned n; - for (n = 0; n < info->module_count; n++) - if (!strcmp(name, adsp_modules[n].name)) - return adsp_modules + n; - return NULL; -} - -static int adsp_rpc_init(struct msm_adsp_module *adsp_module) -{ - /* remove the original connect once compatible support is complete */ - adsp_module->rpc_client = msm_rpc_connect( - rpc_adsp_rtos_atom_prog, - rpc_adsp_rtos_atom_vers, - MSM_RPC_UNINTERRUPTIBLE); - if (IS_ERR(adsp_module->rpc_client)) - adsp_module->rpc_client = msm_rpc_connect_compatible( - rpc_adsp_rtos_atom_prog, - rpc_adsp_rtos_atom_vers_comp, - MSM_RPC_UNINTERRUPTIBLE); - - if (IS_ERR(adsp_module->rpc_client)) { - int rc = PTR_ERR(adsp_module->rpc_client); - adsp_module->rpc_client = 0; - MM_ERR("could not open rpc client: %d\n", rc); - return rc; - } - - return 0; -} - -/* - * Send RPC_ADSP_RTOS_CMD_GET_INIT_INFO cmd to ARM9 and get - * queue offsets and module entries (init info) as part of the event. - */ -static void msm_get_init_info(void) -{ - int rc; - struct rpc_adsp_rtos_app_to_modem_args_t rpc_req; - struct rpc_reply_hdr rpc_rsp; - - adsp_info.init_info_rpc_client = msm_rpc_connect( - rpc_adsp_rtos_atom_prog, - rpc_adsp_rtos_atom_vers, - MSM_RPC_UNINTERRUPTIBLE); - if (IS_ERR(adsp_info.init_info_rpc_client)) { - adsp_info.init_info_rpc_client = msm_rpc_connect_compatible( - rpc_adsp_rtos_atom_prog, - rpc_adsp_rtos_atom_vers_comp, - MSM_RPC_UNINTERRUPTIBLE); - if (IS_ERR(adsp_info.init_info_rpc_client)) { - rc = PTR_ERR(adsp_info.init_info_rpc_client); - adsp_info.init_info_rpc_client = 0; - MM_ERR("could not open rpc client: %d\n", rc); - return; - } - } - - rpc_req.gotit = cpu_to_be32(1); - rpc_req.cmd = cpu_to_be32(RPC_ADSP_RTOS_CMD_GET_INIT_INFO); - rpc_req.proc_id = cpu_to_be32(RPC_ADSP_RTOS_PROC_APPS); - rpc_req.module = 0; - - rc = msm_rpc_call_reply(adsp_info.init_info_rpc_client, - RPC_ADSP_RTOS_APP_TO_MODEM_PROC, - &rpc_req, sizeof(rpc_req), - &rpc_rsp, sizeof(rpc_rsp), - 5 * HZ); - - if (rc < 0) - MM_ERR("could not send RPC request: %d\n", rc); -} - -int msm_adsp_get(const char *name, struct msm_adsp_module **out, - struct msm_adsp_ops *ops, void *driver_data) -{ - struct msm_adsp_module *module; - int rc = 0; - static uint32_t init_info_cmd_sent; - - mutex_lock(&adsp_info.lock); - if (!init_info_cmd_sent) { - init_waitqueue_head(&adsp_info.init_info_wait); - msm_get_init_info(); - rc = wait_event_timeout(adsp_info.init_info_wait, - adsp_info.init_info_state == ADSP_STATE_INIT_INFO, - 5 * HZ); - if (!rc) { - MM_ERR("INIT_INFO failed\n"); - mutex_unlock(&adsp_info.lock); - return -ETIMEDOUT; - - } - init_info_cmd_sent++; - } - mutex_unlock(&adsp_info.lock); - - module = find_adsp_module_by_name(&adsp_info, name); - if (!module) - return -ENODEV; - - mutex_lock(&module->lock); - MM_INFO("opening module %s\n", module->name); - - if (module->ops) { - rc = -EBUSY; - goto done; - } - - rc = adsp_rpc_init(module); - if (rc) - goto done; - - module->ops = ops; - module->driver_data = driver_data; - *out = module; - rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_REGISTER_APP, - module->id, module); - if (rc) { - module->ops = NULL; - module->driver_data = NULL; - *out = NULL; - MM_ERR("REGISTER_APP failed\n"); - goto done; - } - - MM_DBG("module %s has been registered\n", module->name); - -done: - mutex_unlock(&module->lock); - return rc; -} -EXPORT_SYMBOL(msm_adsp_get); - -static int msm_adsp_disable_locked(struct msm_adsp_module *module); - -void msm_adsp_put(struct msm_adsp_module *module) -{ - unsigned long flags; - - mutex_lock(&module->lock); - if (module->ops) { - MM_INFO("closing module %s\n", module->name); - - /* lock to ensure a dsp event cannot be delivered - * during or after removal of the ops and driver_data - */ - spin_lock_irqsave(&adsp_cmd_lock, flags); - module->ops = NULL; - module->driver_data = NULL; - spin_unlock_irqrestore(&adsp_cmd_lock, flags); - - if (module->state != ADSP_STATE_DISABLED) { - MM_INFO("disabling module %s\n", module->name); - msm_adsp_disable_locked(module); - } - - msm_rpc_close(module->rpc_client); - module->rpc_client = 0; - } else { - MM_INFO("module %s is already closed\n", module->name); - } - mutex_unlock(&module->lock); -} -EXPORT_SYMBOL(msm_adsp_put); - -/* this should be common code with rpc_servers.c */ -static int rpc_send_accepted_void_reply(struct msm_rpc_endpoint *client, - uint32_t xid, uint32_t accept_status) -{ - int rc = 0; - uint8_t reply_buf[sizeof(struct rpc_reply_hdr)]; - struct rpc_reply_hdr *reply = (struct rpc_reply_hdr *)reply_buf; - - reply->xid = cpu_to_be32(xid); - reply->type = cpu_to_be32(1); /* reply */ - reply->reply_stat = cpu_to_be32(RPCMSG_REPLYSTAT_ACCEPTED); - - reply->data.acc_hdr.accept_stat = cpu_to_be32(accept_status); - reply->data.acc_hdr.verf_flavor = 0; - reply->data.acc_hdr.verf_length = 0; - - rc = msm_rpc_write(rpc_cb_server_client, reply_buf, sizeof(reply_buf)); - if (rc < 0) - MM_ERR("could not write RPC response: %d\n", rc); - return rc; -} - -int __msm_adsp_write(struct msm_adsp_module *module, unsigned dsp_queue_addr, - void *cmd_buf, size_t cmd_size) -{ - uint32_t ctrl_word; - uint32_t dsp_q_addr; - uint32_t dsp_addr; - uint32_t cmd_id = 0; - int cnt = 0; - int ret_status = 0; - unsigned long flags; - struct adsp_info *info; - - if (!module || !cmd_buf) { - MM_ERR("Called with NULL parameters\n"); - return -EINVAL; - } - info = module->info; - spin_lock_irqsave(&adsp_write_lock, flags); - - if (module->state != ADSP_STATE_ENABLED) { - spin_unlock_irqrestore(&adsp_write_lock, flags); - MM_ERR("module %s not enabled before write\n", module->name); - return -ENODEV; - } - if (adsp_validate_module(module->id)) { - spin_unlock_irqrestore(&adsp_write_lock, flags); - MM_ERR("module id validation failed %s %d\n", - module->name, module->id); - return -ENXIO; - } - if (dsp_queue_addr >= QDSP_MAX_NUM_QUEUES) { - spin_unlock_irqrestore(&adsp_write_lock, flags); - MM_ERR("Invalid Queue Index: %d\n", dsp_queue_addr); - return -ENXIO; - } - if (adsp_validate_queue(module->id, dsp_queue_addr, cmd_size)) { - spin_unlock_irqrestore(&adsp_write_lock, flags); - return -EINVAL; - } - dsp_q_addr = adsp_get_queue_offset(info, dsp_queue_addr); - dsp_q_addr &= ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M; - - /* Poll until the ADSP is ready to accept a command. - * Wait for 100us, return error if it's not responding. - * If this returns an error, we need to disable ALL modules and - * then retry. - */ - while (((ctrl_word = readl(info->write_ctrl)) & - ADSP_RTOS_WRITE_CTRL_WORD_READY_M) != - ADSP_RTOS_WRITE_CTRL_WORD_READY_V) { - if (cnt > 50) { - MM_ERR("timeout waiting for DSP write ready\n"); - ret_status = -EIO; - goto fail; - } - MM_DBG("waiting for DSP write ready\n"); - udelay(2); - cnt++; - } - - /* Set the mutex bits */ - ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M); - ctrl_word |= ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V; - - /* Clear the command bits */ - ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_CMD_M); - - /* Set the queue address bits */ - ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M); - ctrl_word |= dsp_q_addr; - - writel(ctrl_word, info->write_ctrl); - - /* Generate an interrupt to the DSP. This notifies the DSP that - * we are about to send a command on this particular queue. The - * DSP will in response change its state. - */ - writel(1, info->send_irq); - - /* Poll until the adsp responds to the interrupt; this does not - * generate an interrupt from the adsp. This should happen within - * 5ms. - */ - cnt = 0; - while ((readl(info->write_ctrl) & - ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M) == - ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V) { - if (cnt > 2500) { - MM_ERR("timeout waiting for adsp ack\n"); - ret_status = -EIO; - goto fail; - } - udelay(2); - cnt++; - } - - /* Read the ctrl word */ - ctrl_word = readl(info->write_ctrl); - - if ((ctrl_word & ADSP_RTOS_WRITE_CTRL_WORD_STATUS_M) != - ADSP_RTOS_WRITE_CTRL_WORD_NO_ERR_V) { - ret_status = -EAGAIN; - goto fail; - } else { - /* No error */ - /* Get the DSP buffer address */ - dsp_addr = (ctrl_word & ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M) + - (uint32_t)MSM_AD5_BASE; - - if (dsp_addr < (uint32_t)(MSM_AD5_BASE + QDSP_RAMC_OFFSET)) { - uint16_t *buf_ptr = (uint16_t *) cmd_buf; - uint16_t *dsp_addr16 = (uint16_t *)dsp_addr; - cmd_size /= sizeof(uint16_t); - - /* Save the command ID */ - cmd_id = (uint32_t) buf_ptr[0]; - - /* Copy the command to DSP memory */ - cmd_size++; - while (--cmd_size) - *dsp_addr16++ = *buf_ptr++; - } else { - uint32_t *buf_ptr = (uint32_t *) cmd_buf; - uint32_t *dsp_addr32 = (uint32_t *)dsp_addr; - cmd_size /= sizeof(uint32_t); - - /* Save the command ID */ - cmd_id = buf_ptr[0]; - - cmd_size++; - while (--cmd_size) - *dsp_addr32++ = *buf_ptr++; - } - - /* Set the mutex bits */ - ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M); - ctrl_word |= ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V; - - /* Set the command bits to write done */ - ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_CMD_M); - ctrl_word |= ADSP_RTOS_WRITE_CTRL_WORD_CMD_WRITE_DONE_V; - - /* Set the queue address bits */ - ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M); - ctrl_word |= dsp_q_addr; - - writel(ctrl_word, info->write_ctrl); - - /* Generate an interrupt to the DSP. It does not respond with - * an interrupt, and we do not need to wait for it to - * acknowledge, because it will hold the mutex lock until it's - * ready to receive more commands again. - */ - writel(1, info->send_irq); - - module->num_commands++; - } /* Ctrl word status bits were 00, no error in the ctrl word */ - -fail: - spin_unlock_irqrestore(&adsp_write_lock, flags); - return ret_status; -} -EXPORT_SYMBOL(msm_adsp_write); - -int msm_adsp_write(struct msm_adsp_module *module, unsigned dsp_queue_addr, - void *cmd_buf, size_t cmd_size) -{ - int rc, retries = 0; -#ifdef CONFIG_DEBUG_FS - uint16_t *ptr; - int ii; - - if (wdump > 0) { - ptr = cmd_buf; - pr_info("A->D:%x\n", module->id); - pr_info("adsp: %x %d\n", dsp_queue_addr, cmd_size); - for (ii = 0; ii < cmd_size/2; ii++) - pr_info("%x ", ptr[ii]); - pr_info("\n"); - } -#endif /* CONFIG_DEBUG_FS */ - do { - rc = __msm_adsp_write(module, dsp_queue_addr, cmd_buf, - cmd_size); - if (rc == -EAGAIN) - udelay(10); - } while (rc == -EAGAIN && retries++ < 300); - if (retries > 50) - MM_ERR("adsp: %s command took %d attempts: rc %d\n", - module->name, retries, rc); - return rc; -} - -static void *event_addr; -static void read_event(void *buf, size_t len) -{ - uint32_t dptr[3]; - struct rpc_adsp_rtos_modem_to_app_args_t *sptr; - struct adsp_rtos_mp_mtoa_type *pkt_ptr; - - sptr = event_addr; - pkt_ptr = &sptr->mtoa_pkt.adsp_rtos_mp_mtoa_data.mp_mtoa_packet; - - dptr[0] = be32_to_cpu(sptr->mtoa_pkt.mp_mtoa_header.event); - dptr[1] = be32_to_cpu(pkt_ptr->module); - dptr[2] = be32_to_cpu(pkt_ptr->image); - - if (len > EVENT_LEN) - len = EVENT_LEN; - - memcpy(buf, dptr, len); -} - -static void handle_adsp_rtos_mtoa_app(struct rpc_request_hdr *req) -{ - struct rpc_adsp_rtos_modem_to_app_args_t *args = - (struct rpc_adsp_rtos_modem_to_app_args_t *)req; - uint32_t event; - uint32_t proc_id; - uint32_t module_id; - uint32_t image; - struct msm_adsp_module *module; - struct adsp_rtos_mp_mtoa_type *pkt_ptr; - struct queue_to_offset_type *qptr; - struct queue_to_offset_type *qtbl; - struct mod_to_queue_offsets *mqptr; - struct mod_to_queue_offsets *mqtbl; - uint32_t *mptr; - uint32_t *mtbl; - uint32_t q_idx; - uint32_t num_entries; - uint32_t entries_per_image; - struct adsp_rtos_mp_mtoa_init_info_type *iptr; - struct adsp_rtos_mp_mtoa_init_info_type *sptr; - int32_t i_no, e_idx; - - event = be32_to_cpu(args->mtoa_pkt.mp_mtoa_header.event); - proc_id = be32_to_cpu(args->mtoa_pkt.mp_mtoa_header.proc_id); - - if (event == RPC_ADSP_RTOS_INIT_INFO) { - MM_INFO("INIT_INFO Event\n"); - sptr = &args->mtoa_pkt.adsp_rtos_mp_mtoa_data.mp_mtoa_init_packet; - - iptr = adsp_info.init_info_ptr; - iptr->image_count = be32_to_cpu(sptr->image_count); - if (iptr->image_count > IMG_MAX) - iptr->image_count = IMG_MAX; - iptr->num_queue_offsets = be32_to_cpu(sptr->num_queue_offsets); - num_entries = iptr->num_queue_offsets; - if (num_entries > ENTRIES_MAX) { - num_entries = ENTRIES_MAX; - iptr->num_queue_offsets = ENTRIES_MAX; - } - qptr = &sptr->queue_offsets_tbl[0][0]; - for (i_no = 0; i_no < iptr->image_count; i_no++) { - qtbl = &iptr->queue_offsets_tbl[i_no][0]; - for (e_idx = 0; e_idx < num_entries; e_idx++) { - qtbl[e_idx].offset = be32_to_cpu(qptr->offset); - qtbl[e_idx].queue = be32_to_cpu(qptr->queue); - q_idx = be32_to_cpu(qptr->queue); - iptr->queue_offsets[i_no][q_idx] = qtbl[e_idx].offset; - qptr++; - } - } - - num_entries = be32_to_cpu(sptr->num_task_module_entries); - if (num_entries > ENTRIES_MAX) - num_entries = ENTRIES_MAX; - iptr->num_task_module_entries = num_entries; - entries_per_image = num_entries / iptr->image_count; - mptr = &sptr->task_to_module_tbl[0][0]; - for (i_no = 0; i_no < iptr->image_count; i_no++) { - mtbl = &iptr->task_to_module_tbl[i_no][0]; - for (e_idx = 0; e_idx < entries_per_image; e_idx++) { - mtbl[e_idx] = be32_to_cpu(*mptr); - mptr++; - } - } - - iptr->module_table_size = be32_to_cpu(sptr->module_table_size); -#if CONFIG_ADSP_RPC_VER > 0x30001 - if (iptr->module_table_size > MODULES_MAX) - iptr->module_table_size = MODULES_MAX; -#else - if (iptr->module_table_size > ENTRIES_MAX) - iptr->module_table_size = ENTRIES_MAX; -#endif - mptr = &sptr->module_entries[0]; - for (i_no = 0; i_no < iptr->module_table_size; i_no++) - iptr->module_entries[i_no] = be32_to_cpu(mptr[i_no]); - - mqptr = &sptr->mod_to_q_tbl[0]; - mqtbl = &iptr->mod_to_q_tbl[0]; - iptr->mod_to_q_entries = be32_to_cpu(sptr->mod_to_q_entries); - if (iptr->mod_to_q_entries > ENTRIES_MAX) - iptr->mod_to_q_entries = ENTRIES_MAX; - for (e_idx = 0; e_idx < iptr->mod_to_q_entries; e_idx++) { - mqtbl[e_idx].module = be32_to_cpu(mqptr->module); - mqtbl[e_idx].q_type = be32_to_cpu(mqptr->q_type); - mqtbl[e_idx].q_max_len = be32_to_cpu(mqptr->q_max_len); - mqptr++; - } - - adsp_info.init_info_state = ADSP_STATE_INIT_INFO; - rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid, - RPC_ACCEPTSTAT_SUCCESS); - wake_up(&adsp_info.init_info_wait); - - return; - } - - pkt_ptr = &args->mtoa_pkt.adsp_rtos_mp_mtoa_data.mp_mtoa_packet; - module_id = be32_to_cpu(pkt_ptr->module); - image = be32_to_cpu(pkt_ptr->image); - - MM_DBG("rpc event=%d, proc_id=%d, module=%d, image=%d\n", - event, proc_id, module_id, image); - - module = find_adsp_module_by_id(&adsp_info, module_id); - if (!module) { - MM_ERR("module %d is not supported!\n", module_id); - rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid, - RPC_ACCEPTSTAT_GARBAGE_ARGS); - return; - } - - mutex_lock(&module->lock); - switch (event) { - case RPC_ADSP_RTOS_MOD_READY: - if (module->state == ADSP_STATE_ENABLING) { - MM_INFO("module %s: READY\n", module->name); - module->state = ADSP_STATE_ENABLED; - wake_up(&module->state_wait); - adsp_set_image(module->info, image); - break; - } else { - MM_ERR("module %s got READY event in state[%d]\n", - module->name, - module->state); - rpc_send_accepted_void_reply(rpc_cb_server_client, - req->xid, - RPC_ACCEPTSTAT_GARBAGE_ARGS); - mutex_unlock(&module->lock); - return; - } - case RPC_ADSP_RTOS_MOD_DISABLE: - MM_INFO("module %s: DISABLED\n", module->name); - module->state = ADSP_STATE_DISABLED; - wake_up(&module->state_wait); - break; - case RPC_ADSP_RTOS_SERVICE_RESET: - MM_INFO("module %s: SERVICE_RESET\n", module->name); - module->state = ADSP_STATE_DISABLED; - wake_up(&module->state_wait); - break; - case RPC_ADSP_RTOS_CMD_SUCCESS: - MM_INFO("module %s: CMD_SUCCESS\n", module->name); - break; - case RPC_ADSP_RTOS_CMD_FAIL: - MM_INFO("module %s: CMD_FAIL\n", module->name); - break; - case RPC_ADSP_RTOS_DISABLE_FAIL: - MM_INFO("module %s: DISABLE_FAIL\n", module->name); - break; - default: - MM_ERR("unknown event %d\n", event); - rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid, - RPC_ACCEPTSTAT_GARBAGE_ARGS); - mutex_unlock(&module->lock); - return; - } - rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid, - RPC_ACCEPTSTAT_SUCCESS); -#ifdef CONFIG_MSM_ADSP_REPORT_EVENTS - event_addr = (uint32_t *)req; - module->ops->event(module->driver_data, - EVENT_MSG_ID, - EVENT_LEN, - read_event); -#endif - mutex_unlock(&module->lock); -} - -static int handle_adsp_rtos_mtoa(struct rpc_request_hdr *req) -{ - switch (req->procedure) { - case RPC_ADSP_RTOS_MTOA_NULL_PROC: - rpc_send_accepted_void_reply(rpc_cb_server_client, - req->xid, - RPC_ACCEPTSTAT_SUCCESS); - break; -#if CONFIG_ADSP_RPC_VER > 0x30001 - case RPC_ADSP_RTOS_MTOA_INIT_INFO_PROC: - case RPC_ADSP_RTOS_MTOA_EVENT_INFO_PROC: -#else - case RPC_ADSP_RTOS_MODEM_TO_APP_PROC: -#endif - handle_adsp_rtos_mtoa_app(req); - break; - default: - MM_ERR("unknowned proc %d\n", req->procedure); - rpc_send_accepted_void_reply( - rpc_cb_server_client, req->xid, - RPC_ACCEPTSTAT_PROC_UNAVAIL); - break; - } - return 0; -} - -/* this should be common code with rpc_servers.c */ -static int adsp_rpc_thread(void *data) -{ - void *buffer; - struct rpc_request_hdr *req; - int rc, exit = 0; - - do { - rc = msm_rpc_read(rpc_cb_server_client, &buffer, -1, -1); - if (rc < 0) { - MM_ERR("could not read rpc: %d\n", rc); - break; - } - req = (struct rpc_request_hdr *)buffer; - - req->type = be32_to_cpu(req->type); - req->xid = be32_to_cpu(req->xid); - req->rpc_vers = be32_to_cpu(req->rpc_vers); - req->prog = be32_to_cpu(req->prog); - req->vers = be32_to_cpu(req->vers); - req->procedure = be32_to_cpu(req->procedure); - - if (req->type != 0) - goto bad_rpc; - if (req->rpc_vers != 2) - goto bad_rpc; - if (req->prog != rpc_adsp_rtos_mtoa_prog) - goto bad_rpc; - if (!msm_rpc_is_compatible_version(rpc_adsp_rtos_mtoa_vers, - req->vers)) - goto bad_rpc; - - handle_adsp_rtos_mtoa(req); - kfree(buffer); - continue; - -bad_rpc: - MM_ERR("bogus rpc from modem\n"); - kfree(buffer); - } while (!exit); - do_exit(0); -} - -static size_t read_event_size; -static void *read_event_addr; - -static void read_event_16(void *buf, size_t len) -{ - uint16_t *dst = buf; - uint16_t *src = read_event_addr; - len /= 2; - if (len > read_event_size) - len = read_event_size; - while (len--) - *dst++ = *src++; -} - -static void read_event_32(void *buf, size_t len) -{ - uint32_t *dst = buf; - uint32_t *src = read_event_addr; - len /= 2; - if (len > read_event_size) - len = read_event_size; - while (len--) - *dst++ = *src++; -} - -static int adsp_rtos_read_ctrl_word_cmd_tast_to_h_v( - struct adsp_info *info, void *dsp_addr) -{ - struct msm_adsp_module *module; - unsigned rtos_task_id; - unsigned msg_id; - unsigned msg_length; -#ifdef CONFIG_DEBUG_FS - uint16_t *ptr16; - uint32_t *ptr32; - int ii; -#endif /* CONFIG_DEBUG_FS */ - void (*func)(void *, size_t); - - if (dsp_addr >= (void *)(MSM_AD5_BASE + QDSP_RAMC_OFFSET)) { - uint32_t *dsp_addr32 = dsp_addr; - uint32_t tmp = *dsp_addr32++; - rtos_task_id = (tmp & ADSP_RTOS_READ_CTRL_WORD_TASK_ID_M) >> 8; - msg_id = (tmp & ADSP_RTOS_READ_CTRL_WORD_MSG_ID_M); - read_event_size = tmp >> 16; - read_event_addr = dsp_addr32; - msg_length = read_event_size * sizeof(uint32_t); - func = read_event_32; - } else { - uint16_t *dsp_addr16 = dsp_addr; - uint16_t tmp = *dsp_addr16++; - rtos_task_id = (tmp & ADSP_RTOS_READ_CTRL_WORD_TASK_ID_M) >> 8; - msg_id = tmp & ADSP_RTOS_READ_CTRL_WORD_MSG_ID_M; - read_event_size = *dsp_addr16++; - read_event_addr = dsp_addr16; - msg_length = read_event_size * sizeof(uint16_t); - func = read_event_16; - } - - if (rtos_task_id > info->max_task_id) { - MM_ERR("bogus task id %d\n", rtos_task_id); - return 0; - } - module = find_adsp_module_by_id(info, - adsp_get_module(info, rtos_task_id)); - - if (!module) { - MM_ERR("no module for task id %d\n", rtos_task_id); - return 0; - } - - module->num_events++; - - if (!module->ops) { - MM_ERR("module %s is not open\n", module->name); - return 0; - } -#ifdef CONFIG_DEBUG_FS - if (rdump > 0 && - (dsp_addr >= (void *)(MSM_AD5_BASE + QDSP_RAMC_OFFSET))) { - ptr32 = read_event_addr; - pr_info("D->A\n"); - pr_info("m_id = %x id = %x\n", module->id, msg_id); - for (ii = 0; ii < msg_length/4; ii++) - pr_info("%x ", ptr32[ii]); - pr_info("\n"); - } else if (rdump > 0) { - ptr16 = read_event_addr; - pr_info("D->A\n"); - pr_info("m_id = %x id = %x\n", module->id, msg_id); - for (ii = 0; ii < msg_length/2; ii++) - pr_info("%x ", ptr16[ii]); - pr_info("\n"); - } -#endif /* CONFIG_DEBUG_FS */ - - module->ops->event(module->driver_data, msg_id, msg_length, func); - return 0; -} - -static int adsp_get_event(struct adsp_info *info) -{ - uint32_t ctrl_word; - uint32_t ready; - void *dsp_addr; - uint32_t cmd_type; - int cnt; - unsigned long flags; - int rc = 0; - - spin_lock_irqsave(&adsp_cmd_lock, flags); - - /* Whenever the DSP has a message, it updates this control word - * and generates an interrupt. When we receive the interrupt, we - * read this register to find out what ADSP task the command is - * comming from. - * - * The ADSP should *always* be ready on the first call, but the - * irq handler calls us in a loop (to handle back-to-back command - * processing), so we give the DSP some time to return to the - * ready state. The DSP will not issue another IRQ for events - * pending between the first IRQ and the event queue being drained, - * unfortunately. - */ - - for (cnt = 0; cnt < 50; cnt++) { - ctrl_word = readl(info->read_ctrl); - - if ((ctrl_word & ADSP_RTOS_READ_CTRL_WORD_FLAG_M) == - ADSP_RTOS_READ_CTRL_WORD_FLAG_UP_CONT_V) - goto ready; - - udelay(2); - } - MM_ERR("not ready after 100uS\n"); - rc = -EBUSY; - goto done; - -ready: - /* Here we check to see if there are pending messages. If there are - * none, we siply return -EAGAIN to indicate that there are no more - * messages pending. - */ - ready = ctrl_word & ADSP_RTOS_READ_CTRL_WORD_READY_M; - if ((ready != ADSP_RTOS_READ_CTRL_WORD_READY_V) && - (ready != ADSP_RTOS_READ_CTRL_WORD_CONT_V)) { - rc = -EAGAIN; - goto done; - } - - /* DSP says that there are messages waiting for the host to read */ - - /* Get the Command Type */ - cmd_type = ctrl_word & ADSP_RTOS_READ_CTRL_WORD_CMD_TYPE_M; - - /* Get the DSP buffer address */ - dsp_addr = (void *)((ctrl_word & - ADSP_RTOS_READ_CTRL_WORD_DSP_ADDR_M) + - (uint32_t)MSM_AD5_BASE); - - /* We can only handle Task-to-Host messages */ - if (cmd_type != ADSP_RTOS_READ_CTRL_WORD_CMD_TASK_TO_H_V) { - MM_ERR("unknown dsp cmd_type %d\n", cmd_type); - rc = -EIO; - goto done; - } - - adsp_rtos_read_ctrl_word_cmd_tast_to_h_v(info, dsp_addr); - - ctrl_word = readl(info->read_ctrl); - ctrl_word &= ~ADSP_RTOS_READ_CTRL_WORD_READY_M; - - /* Write ctrl word to the DSP */ - writel(ctrl_word, info->read_ctrl); - - /* Generate an interrupt to the DSP */ - writel(1, info->send_irq); - -done: - spin_unlock_irqrestore(&adsp_cmd_lock, flags); - return rc; -} - -static irqreturn_t adsp_irq_handler(int irq, void *data) -{ - struct adsp_info *info = &adsp_info; - int cnt = 0; - for (cnt = 0; cnt < 15; cnt++) - if (adsp_get_event(info) < 0) - break; - if (cnt > info->event_backlog_max) - info->event_backlog_max = cnt; - info->events_received += cnt; - if (cnt == 15) - MM_ERR("too many (%d) events for single irq!\n", cnt); - return IRQ_HANDLED; -} - -int adsp_set_clkrate(struct msm_adsp_module *module, unsigned long clk_rate) -{ - if (!module) - return -EINVAL; - - if (module->clk && clk_rate) - return clk_set_rate(module->clk, clk_rate); - - return -EINVAL; -} - -int msm_adsp_generate_event(void *data, - struct msm_adsp_module *mod, - unsigned event_id, - unsigned event_length, - unsigned event_size, - void *msg) -{ - unsigned long flags; - void (*func)(void *, size_t); - - if (!mod) - return -EINVAL; - - if (event_size == sizeof(uint32_t)) - func = read_event_32; - else if (event_size == sizeof(uint16_t)) - func = read_event_16; - else - return -EINVAL; - - spin_lock_irqsave(&adsp_cmd_lock, flags); - read_event_addr = msg; - read_event_size = event_length; - mod->ops->event(data, event_id, event_length, func); - spin_unlock_irqrestore(&adsp_cmd_lock, flags); - return 0; -} - -int msm_adsp_enable(struct msm_adsp_module *module) -{ - int rc = 0; - struct msm_adsp_module *module_en = NULL; - - if (!module) - return -EINVAL; - - MM_INFO("enable '%s'state[%d] id[%d]\n", - module->name, module->state, module->id); - if (!strncmp(module->name, "JPEGTASK", sizeof(module->name))) - module_en = find_adsp_module_by_name(&adsp_info, "VIDEOTASK"); - else if (!strncmp(module->name, "VIDEOTASK", sizeof(module->name))) - module_en = find_adsp_module_by_name(&adsp_info, "JPEGTASK"); - if (module_en) { - mutex_lock(&module_en->lock); - if (module_en->state == ADSP_STATE_ENABLED || - module_en->state == ADSP_STATE_ENABLING) { - MM_ERR("both jpeg and video module can't"\ - " exist at a time\n"); - mutex_unlock(&module_en->lock); - return -EINVAL; - } - mutex_unlock(&module_en->lock); - } - - mutex_lock(&module->lock); - switch (module->state) { - case ADSP_STATE_DISABLED: - rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_ENABLE, - module->id, module); - if (rc) - break; - module->state = ADSP_STATE_ENABLING; - mutex_unlock(&module->lock); - rc = wait_event_timeout(module->state_wait, - module->state != ADSP_STATE_ENABLING, - 1 * HZ); - mutex_lock(&module->lock); - if (module->state == ADSP_STATE_ENABLED) { - rc = 0; - } else { - MM_ERR("module '%s' enable timed out\n", module->name); - rc = -ETIMEDOUT; - } - if (module->open_count++ == 0 && module->clk) - clk_prepare_enable(module->clk); - - mutex_lock(&adsp_open_lock); - if (adsp_open_count++ == 0) { - enable_irq(adsp_info.int_adsp); - prevent_suspend(); - } - mutex_unlock(&adsp_open_lock); - break; - case ADSP_STATE_ENABLING: - MM_DBG("module '%s' enable in progress\n", module->name); - break; - case ADSP_STATE_ENABLED: - MM_DBG("module '%s' already enabled\n", module->name); - break; - case ADSP_STATE_DISABLING: - MM_ERR("module '%s' disable in progress\n", module->name); - rc = -EBUSY; - break; - } - mutex_unlock(&module->lock); - return rc; -} -EXPORT_SYMBOL(msm_adsp_enable); - -int msm_adsp_disable_event_rsp(struct msm_adsp_module *module) -{ - int rc = 0; - - if (!module) - return -EINVAL; - - mutex_lock(&module->lock); - - rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_DISABLE_EVENT_RSP, - module->id, module); - mutex_unlock(&module->lock); - - return rc; -} -EXPORT_SYMBOL(msm_adsp_disable_event_rsp); - -static int msm_adsp_disable_locked(struct msm_adsp_module *module) -{ - int rc = 0; - - if (!module) - return -EINVAL; - - switch (module->state) { - case ADSP_STATE_DISABLED: - MM_DBG("module '%s' already disabled\n", module->name); - break; - case ADSP_STATE_ENABLING: - case ADSP_STATE_ENABLED: - rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_DISABLE, - module->id, module); - module->state = ADSP_STATE_DISABLED; - if (--module->open_count == 0 && module->clk) - clk_disable_unprepare(module->clk); - mutex_lock(&adsp_open_lock); - if (--adsp_open_count == 0) { - disable_irq(adsp_info.int_adsp); - allow_suspend(); - MM_DBG("disable interrupt\n"); - } - mutex_unlock(&adsp_open_lock); - } - return rc; -} - -int msm_adsp_disable(struct msm_adsp_module *module) -{ - int rc; - - if (!module) - return -EINVAL; - - MM_INFO("disable '%s'\n", module->name); - mutex_lock(&module->lock); - rc = msm_adsp_disable_locked(module); - mutex_unlock(&module->lock); - return rc; -} -EXPORT_SYMBOL(msm_adsp_disable); - -static int msm_adsp_probe(struct platform_device *pdev) -{ - unsigned count; - int rc, i; - - adsp_info.int_adsp = platform_get_irq(pdev, 0); - if (adsp_info.int_adsp < 0) { - MM_ERR("no irq resource?\n"); - return -ENODEV; - } - - wake_lock_init(&adsp_wake_lock, WAKE_LOCK_SUSPEND, "adsp"); - adsp_info.init_info_ptr = kzalloc( - (sizeof(struct adsp_rtos_mp_mtoa_init_info_type)), GFP_KERNEL); - if (!adsp_info.init_info_ptr) - return -ENOMEM; - - rc = adsp_init_info(&adsp_info); - if (rc) - return rc; - adsp_info.send_irq += (uint32_t) MSM_AD5_BASE; - adsp_info.read_ctrl += (uint32_t) MSM_AD5_BASE; - adsp_info.write_ctrl += (uint32_t) MSM_AD5_BASE; - count = adsp_info.module_count; - - adsp_modules = kzalloc( - (sizeof(struct msm_adsp_module) + sizeof(void *)) * - count, GFP_KERNEL); - if (!adsp_modules) - return -ENOMEM; - - adsp_info.id_to_module = (void *) (adsp_modules + count); - - spin_lock_init(&adsp_cmd_lock); - spin_lock_init(&adsp_write_lock); - mutex_init(&adsp_info.lock); - - rc = request_irq(adsp_info.int_adsp, adsp_irq_handler, - IRQF_TRIGGER_RISING, "adsp", 0); - if (rc < 0) - goto fail_request_irq; - disable_irq(adsp_info.int_adsp); - - rpc_cb_server_client = msm_rpc_open(); - if (IS_ERR(rpc_cb_server_client)) { - rpc_cb_server_client = NULL; - rc = PTR_ERR(rpc_cb_server_client); - MM_ERR("could not create rpc server (%d)\n", rc); - goto fail_rpc_open; - } - - rc = msm_rpc_register_server(rpc_cb_server_client, - rpc_adsp_rtos_mtoa_prog, - rpc_adsp_rtos_mtoa_vers); - if (rc) { - MM_ERR("could not register callback server (%d)\n", rc); - goto fail_rpc_register; - } - - /* schedule start of kernel thread later using work queue */ - queue_work(msm_adsp_probe_work_queue, &msm_adsp_probe_work); - - for (i = 0; i < count; i++) { - struct msm_adsp_module *mod = adsp_modules + i; - mutex_init(&mod->lock); - init_waitqueue_head(&mod->state_wait); - mod->info = &adsp_info; - mod->name = adsp_info.module[i].name; - mod->id = adsp_info.module[i].id; - if (adsp_info.module[i].clk_name) - mod->clk = clk_get(NULL, adsp_info.module[i].clk_name); - else - mod->clk = NULL; - if (mod->clk && adsp_info.module[i].clk_rate) - clk_set_rate(mod->clk, adsp_info.module[i].clk_rate); - mod->verify_cmd = adsp_info.module[i].verify_cmd; - mod->patch_event = adsp_info.module[i].patch_event; - INIT_HLIST_HEAD(&mod->ion_regions); - mod->pdev.name = adsp_info.module[i].pdev_name; - mod->pdev.id = -1; - adsp_info.id_to_module[i] = mod; - platform_device_register(&mod->pdev); - } - - msm_adsp_publish_cdevs(adsp_modules, count); - rmtask_init(); - - return 0; - -fail_rpc_register: - msm_rpc_close(rpc_cb_server_client); - rpc_cb_server_client = NULL; -fail_rpc_open: - enable_irq(adsp_info.int_adsp); - free_irq(adsp_info.int_adsp, 0); -fail_request_irq: - kfree(adsp_modules); - kfree(adsp_info.init_info_ptr); - return rc; -} - -static void adsp_probe_work(struct work_struct *work) -{ - /* start the kernel thread to process the callbacks */ - kthread_run(adsp_rpc_thread, NULL, "kadspd"); -} - -#ifdef CONFIG_DEBUG_FS -static int get_parameters(char *buf, long int *param1, int num_of_par) -{ - char *token; - int base, cnt; - - token = strsep(&buf, " "); - - for (cnt = 0; cnt < num_of_par; cnt++) { - if (token != NULL) { - if ((token[1] == 'x') || (token[1] == 'X')) - base = 16; - else - base = 10; - - if (strict_strtoul(token, base, ¶m1[cnt]) != 0) - return -EINVAL; - - token = strsep(&buf, " "); - } - else - return -EINVAL; - } - return 0; -} - - -static ssize_t adsp_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - pr_debug("adsp debugfs opened\n"); - return 0; -} -static ssize_t adsp_debug_write(struct file *file, const char __user *buf, - size_t cnt, loff_t *ppos) -{ - char *access_str = file->private_data; - char lbuf[32]; - int rc; - long int param[5]; - - if (cnt > sizeof(lbuf) - 1) - return -EINVAL; - rc = copy_from_user(lbuf, buf, cnt); - if (rc) { - pr_info("Unable to copy data from user space\n"); - return -EFAULT; - } - lbuf[cnt] = '\0'; - - if (!strcmp(access_str, "write_log")) { - if (get_parameters(lbuf, param, 1) == 0) { - switch (param[0]) { - case 1: - if (wdump <= 0) - wdump = 1; - pr_debug("write cmd to DSP(A->D) dump \ - started:%d\n", wdump); - break; - case 0: - if (wdump > 0) - wdump = 0; - pr_debug("Stop write cmd to \ - DSP(A->D):%d\n", wdump); - break; - default: - rc = -EINVAL; - break; - } - } else - rc = -EINVAL; - } else if (!strcmp(access_str, "read_log")) { - if (get_parameters(lbuf, param, 1) == 0) { - switch (param[0]) { - case 1: - if (rdump <= 0) - rdump = 1; - pr_debug("write cmd from DSP(D->A) dump \ - started:%d\n", wdump); - break; - case 0: - if (rdump > 0) - rdump = 0; - pr_debug("Stop write cmd from \ - DSP(D->A):%d\n", wdump); - break; - default: - rc = -EINVAL; - break; - } - } else - rc = -EINVAL; - } else { - rc = -EINVAL; - } - if (rc == 0) - rc = cnt; - else { - pr_err("%s: rc = %d\n", __func__, rc); - pr_info("\nWrong command: Use =>\n"); - pr_info("-------------------------\n"); - pr_info("To Start A->D:: echo \"1\">/sys/kernel/debug/ \ - adsp_cmd/write_log\n"); - pr_info("To Start D->A:: echo \"1\">/sys/kernel/debug/ \ - adsp_cmd/read_log\n"); - pr_info("To Stop A->D:: echo \"0\">/sys/kernel/debug/ \ - adsp_cmd/write_log\n"); - pr_info("To Stop D->A:: echo \"0\">/sys/kernel/debug/ \ - adsp_cmd/read_log\n"); - pr_info("------------------------\n"); - } - - return rc; -} -#endif - -static struct platform_driver msm_adsp_driver = { - .probe = msm_adsp_probe, - .driver = { - .owner = THIS_MODULE, - }, -}; - -static const char msm_adsp_driver_name[] = "msm_adsp"; - -#ifdef CONFIG_DEBUG_FS -static const struct file_operations adsp_debug_fops = { - .write = adsp_debug_write, - .open = adsp_debug_open, -}; -#endif - -static int __init adsp_init(void) -{ - int rc; - -#ifdef CONFIG_DEBUG_FS - dentry_adsp = debugfs_create_dir("adsp_cmd", 0); - if (!IS_ERR(dentry_adsp)) { - dentry_wdata = debugfs_create_file("write_log", \ - S_IFREG | S_IRUGO, dentry_adsp, - (void *) "write_log" , &adsp_debug_fops); - dentry_rdata = debugfs_create_file("read_log", \ - S_IFREG | S_IRUGO, dentry_adsp, - (void *) "read_log", &adsp_debug_fops); - } - rdump = 0; - wdump = 0; -#endif /* CONFIG_DEBUG_FS */ - - rpc_adsp_rtos_atom_prog = 0x3000000a; - rpc_adsp_rtos_atom_vers = 0x10001; - rpc_adsp_rtos_atom_vers_comp = 0x00010001; - rpc_adsp_rtos_mtoa_prog = 0x3000000b; -#if CONFIG_ADSP_RPC_VER > 0x30001 - rpc_adsp_rtos_mtoa_vers = 0x30002; - rpc_adsp_rtos_mtoa_vers_comp = 0x00030002; -#else - rpc_adsp_rtos_mtoa_vers = 0x30001; - rpc_adsp_rtos_mtoa_vers_comp = 0x00030001; -#endif - - msm_adsp_probe_work_queue = create_workqueue("msm_adsp_probe"); - if (msm_adsp_probe_work_queue == NULL) - return -ENOMEM; - msm_adsp_driver.driver.name = msm_adsp_driver_name; - rc = platform_driver_register(&msm_adsp_driver); - MM_INFO("%s -- %d\n", msm_adsp_driver_name, rc); - return rc; -} - -device_initcall(adsp_init); diff --git a/arch/arm/mach-msm/qdsp5/adsp.h b/arch/arm/mach-msm/qdsp5/adsp.h deleted file mode 100644 index 9b4b6820b7d97c2e155194befbfe9d9a5b25004b..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/adsp.h +++ /dev/null @@ -1,360 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/adsp.h - * - * Copyright (C) 2008 Google, Inc. - * Copyright (c) 2008-2010, 2012 The Linux Foundation. All rights reserved. - * Author: Iliyan Malchev - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _ARCH_ARM_MACH_MSM_ADSP_H -#define _ARCH_ARM_MACH_MSM_ADSP_H - -#include -#include -#include -#include -#include - -int adsp_pmem_fixup(struct msm_adsp_module *module, void **addr, - unsigned long len); -int adsp_ion_do_cache_op(struct msm_adsp_module *module, void *addr, - void *paddr, unsigned long len, - unsigned long offset, int cmd); -int adsp_ion_fixup_kvaddr(struct msm_adsp_module *module, void **addr, - unsigned long *kvaddr, unsigned long len, - struct file **filp, unsigned long *offset); -int adsp_pmem_paddr_fixup(struct msm_adsp_module *module, void **addr); - -int adsp_vfe_verify_cmd(struct msm_adsp_module *module, - unsigned int queue_id, void *cmd_data, - size_t cmd_size); -int adsp_jpeg_verify_cmd(struct msm_adsp_module *module, - unsigned int queue_id, void *cmd_data, - size_t cmd_size); -int adsp_lpm_verify_cmd(struct msm_adsp_module *module, - unsigned int queue_id, void *cmd_data, - size_t cmd_size); -int adsp_video_verify_cmd(struct msm_adsp_module *module, - unsigned int queue_id, void *cmd_data, - size_t cmd_size); -int adsp_videoenc_verify_cmd(struct msm_adsp_module *module, - unsigned int queue_id, void *cmd_data, - size_t cmd_size); -void q5audio_dsp_not_responding(void); - -struct adsp_event; - -int adsp_vfe_patch_event(struct msm_adsp_module *module, - struct adsp_event *event); - -int adsp_jpeg_patch_event(struct msm_adsp_module *module, - struct adsp_event *event); - - -struct adsp_module_info { - const char *name; - const char *pdev_name; - uint32_t id; - const char *clk_name; - unsigned long clk_rate; - int (*verify_cmd) (struct msm_adsp_module*, unsigned int, void *, - size_t); - int (*patch_event) (struct msm_adsp_module*, struct adsp_event *); -}; - -#define ADSP_EVENT_MAX_SIZE 496 -#define EVENT_LEN 12 -#define EVENT_MSG_ID ((uint16_t)~0) - -struct adsp_event { - struct list_head list; - uint32_t size; /* always in bytes */ - uint16_t msg_id; - uint16_t type; /* 0 for msgs (from aDSP), -1 for events (from ARM9) */ - int is16; /* always 0 (msg is 32-bit) when the event type is 1(ARM9) */ - union { - uint16_t msg16[ADSP_EVENT_MAX_SIZE / 2]; - uint32_t msg32[ADSP_EVENT_MAX_SIZE / 4]; - } data; -}; - -struct adsp_info { - uint32_t send_irq; - uint32_t read_ctrl; - uint32_t write_ctrl; - - uint32_t max_msg16_size; - uint32_t max_msg32_size; - - uint32_t max_task_id; - uint32_t max_module_id; - uint32_t max_queue_id; - uint32_t max_image_id; - - /* for each image id, a map of queue id to offset */ - uint32_t **queue_offset; - - /* for each image id, a map of task id to module id */ - uint32_t **task_to_module; - - /* for each module id, map of module id to module */ - struct msm_adsp_module **id_to_module; - - uint32_t module_count; - struct adsp_module_info *module; - - /* stats */ - uint32_t events_received; - uint32_t event_backlog_max; - - /* rpc_client for init_info */ - struct msm_rpc_endpoint *init_info_rpc_client; - struct adsp_rtos_mp_mtoa_init_info_type *init_info_ptr; - wait_queue_head_t init_info_wait; - unsigned init_info_state; - struct mutex lock; - - /* Interrupt value */ - int int_adsp; -}; - -#define RPC_ADSP_RTOS_ATOM_NULL_PROC 0 -#define RPC_ADSP_RTOS_MTOA_NULL_PROC 0 -#define RPC_ADSP_RTOS_APP_TO_MODEM_PROC 2 -#define RPC_ADSP_RTOS_MODEM_TO_APP_PROC 2 -#define RPC_ADSP_RTOS_MTOA_EVENT_INFO_PROC 3 -#define RPC_ADSP_RTOS_MTOA_INIT_INFO_PROC 4 - -enum rpc_adsp_rtos_proc_type { - RPC_ADSP_RTOS_PROC_NONE = 0, - RPC_ADSP_RTOS_PROC_MODEM = 1, - RPC_ADSP_RTOS_PROC_APPS = 2, -}; - -enum { - RPC_ADSP_RTOS_CMD_REGISTER_APP, - RPC_ADSP_RTOS_CMD_ENABLE, - RPC_ADSP_RTOS_CMD_DISABLE, - RPC_ADSP_RTOS_CMD_KERNEL_COMMAND, - RPC_ADSP_RTOS_CMD_16_COMMAND, - RPC_ADSP_RTOS_CMD_32_COMMAND, - RPC_ADSP_RTOS_CMD_DISABLE_EVENT_RSP, - RPC_ADSP_RTOS_CMD_REMOTE_EVENT, - RPC_ADSP_RTOS_CMD_SET_STATE, - RPC_ADSP_RTOS_CMD_REMOTE_INIT_INFO_EVENT, - RPC_ADSP_RTOS_CMD_GET_INIT_INFO, -}; - -enum rpc_adsp_rtos_mod_status_type { - RPC_ADSP_RTOS_MOD_READY, - RPC_ADSP_RTOS_MOD_DISABLE, - RPC_ADSP_RTOS_SERVICE_RESET, - RPC_ADSP_RTOS_CMD_FAIL, - RPC_ADSP_RTOS_CMD_SUCCESS, - RPC_ADSP_RTOS_INIT_INFO, - RPC_ADSP_RTOS_DISABLE_FAIL, -}; - -struct rpc_adsp_rtos_app_to_modem_args_t { - struct rpc_request_hdr hdr; - uint32_t gotit; /* if 1, the next elements are present */ - uint32_t cmd; /* e.g., RPC_ADSP_RTOS_CMD_REGISTER_APP */ - uint32_t proc_id; /* e.g., RPC_ADSP_RTOS_PROC_APPS */ - uint32_t module; /* e.g., QDSP_MODULE_AUDPPTASK */ -}; - -enum qdsp_image_type { - QDSP_IMAGE_COMBO, - QDSP_IMAGE_GAUDIO, - QDSP_IMAGE_QTV_LP, - QDSP_IMAGE_MAX, - /* DO NOT USE: Force this enum to be a 32bit type to improve speed */ - QDSP_IMAGE_32BIT_DUMMY = 0x10000 -}; - -struct adsp_rtos_mp_mtoa_header_type { - enum rpc_adsp_rtos_mod_status_type event; - enum rpc_adsp_rtos_proc_type proc_id; -}; - -/* ADSP RTOS MP Communications - Modem to APP's Event Info*/ -struct adsp_rtos_mp_mtoa_type { - uint32_t module; - uint32_t image; - uint32_t apps_okts; -}; - -/* ADSP RTOS MP Communications - Modem to APP's Init Info */ -#if CONFIG_ADSP_RPC_VER > 0x30001 -#define IMG_MAX 2 -#define ENTRIES_MAX 36 -#define MODULES_MAX 64 -#else -#define IMG_MAX 6 -#define ENTRIES_MAX 48 -#endif -#define QUEUES_MAX 64 - -struct queue_to_offset_type { - uint32_t queue; - uint32_t offset; -}; - -struct mod_to_queue_offsets { - uint32_t module; - uint32_t q_type; - uint32_t q_max_len; -}; - -struct adsp_rtos_mp_mtoa_init_info_type { - uint32_t image_count; - uint32_t num_queue_offsets; - struct queue_to_offset_type queue_offsets_tbl[IMG_MAX][ENTRIES_MAX]; - uint32_t num_task_module_entries; - uint32_t task_to_module_tbl[IMG_MAX][ENTRIES_MAX]; - - uint32_t module_table_size; -#if CONFIG_ADSP_RPC_VER > 0x30001 - uint32_t module_entries[MODULES_MAX]; -#else - uint32_t module_entries[ENTRIES_MAX]; -#endif - uint32_t mod_to_q_entries; - struct mod_to_queue_offsets mod_to_q_tbl[ENTRIES_MAX]; - /* - * queue_offsets[] is to store only queue_offsets - */ - uint32_t queue_offsets[IMG_MAX][QUEUES_MAX]; -}; - -struct adsp_rtos_mp_mtoa_s_type { - struct adsp_rtos_mp_mtoa_header_type mp_mtoa_header; -#if CONFIG_ADSP_RPC_VER == 0x30001 - uint32_t desc_field; -#endif - union { - struct adsp_rtos_mp_mtoa_init_info_type mp_mtoa_init_packet; - struct adsp_rtos_mp_mtoa_type mp_mtoa_packet; - } adsp_rtos_mp_mtoa_data; -}; - -struct rpc_adsp_rtos_modem_to_app_args_t { - struct rpc_request_hdr hdr; - uint32_t gotit; /* if 1, the next elements are present */ - struct adsp_rtos_mp_mtoa_s_type mtoa_pkt; -}; - -#define ADSP_STATE_DISABLED 0 -#define ADSP_STATE_ENABLING 1 -#define ADSP_STATE_ENABLED 2 -#define ADSP_STATE_DISABLING 3 -#define ADSP_STATE_INIT_INFO 4 - -struct msm_adsp_module { - struct mutex lock; - const char *name; - unsigned id; - struct adsp_info *info; - - struct msm_rpc_endpoint *rpc_client; - struct msm_adsp_ops *ops; - void *driver_data; - - /* statistics */ - unsigned num_commands; - unsigned num_events; - - wait_queue_head_t state_wait; - unsigned state; - - struct platform_device pdev; - struct clk *clk; - int open_count; - - struct mutex ion_regions_lock; - struct hlist_head ion_regions; - int (*verify_cmd) (struct msm_adsp_module*, unsigned int, void *, - size_t); - int (*patch_event) (struct msm_adsp_module*, struct adsp_event *); -}; - -extern void msm_adsp_publish_cdevs(struct msm_adsp_module *, unsigned); -extern int adsp_init_info(struct adsp_info *info); -extern void rmtask_init(void); - -/* Value to indicate that a queue is not defined for a particular image */ -#define QDSP_RTOS_NO_QUEUE 0xfffffffe - -/* - * Constants used to communicate with the ADSP RTOS - */ -#define ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M 0x80000000U -#define ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V 0x80000000U -#define ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_AVAIL_V 0x00000000U - -#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_M 0x70000000U -#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_WRITE_REQ_V 0x00000000U -#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_WRITE_DONE_V 0x10000000U -#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_NO_CMD_V 0x70000000U - -#define ADSP_RTOS_WRITE_CTRL_WORD_STATUS_M 0x0E000000U -#define ADSP_RTOS_WRITE_CTRL_WORD_NO_ERR_V 0x00000000U -#define ADSP_RTOS_WRITE_CTRL_WORD_NO_FREE_BUF_V 0x02000000U - -#define ADSP_RTOS_WRITE_CTRL_WORD_KERNEL_FLG_M 0x01000000U -#define ADSP_RTOS_WRITE_CTRL_WORD_HTOD_MSG_WRITE_V 0x00000000U -#define ADSP_RTOS_WRITE_CTRL_WORD_HTOD_CMD_V 0x01000000U - -#define ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M 0x00FFFFFFU -#define ADSP_RTOS_WRITE_CTRL_WORD_HTOD_CMD_ID_M 0x00FFFFFFU - -/* Combination of MUTEX and CMD bits to check if the DSP is busy */ -#define ADSP_RTOS_WRITE_CTRL_WORD_READY_M 0xF0000000U -#define ADSP_RTOS_WRITE_CTRL_WORD_READY_V 0x70000000U - -/* RTOS to Host processor command mask values */ -#define ADSP_RTOS_READ_CTRL_WORD_FLAG_M 0x80000000U -#define ADSP_RTOS_READ_CTRL_WORD_FLAG_UP_WAIT_V 0x00000000U -#define ADSP_RTOS_READ_CTRL_WORD_FLAG_UP_CONT_V 0x80000000U - -#define ADSP_RTOS_READ_CTRL_WORD_CMD_M 0x60000000U -#define ADSP_RTOS_READ_CTRL_WORD_READ_DONE_V 0x00000000U -#define ADSP_RTOS_READ_CTRL_WORD_READ_REQ_V 0x20000000U -#define ADSP_RTOS_READ_CTRL_WORD_NO_CMD_V 0x60000000U - -/* Combination of FLAG and COMMAND bits to check if MSG ready */ -#define ADSP_RTOS_READ_CTRL_WORD_READY_M 0xE0000000U -#define ADSP_RTOS_READ_CTRL_WORD_READY_V 0xA0000000U -#define ADSP_RTOS_READ_CTRL_WORD_CONT_V 0xC0000000U -#define ADSP_RTOS_READ_CTRL_WORD_DONE_V 0xE0000000U - -#define ADSP_RTOS_READ_CTRL_WORD_STATUS_M 0x18000000U -#define ADSP_RTOS_READ_CTRL_WORD_NO_ERR_V 0x00000000U - -#define ADSP_RTOS_READ_CTRL_WORD_IN_PROG_M 0x04000000U -#define ADSP_RTOS_READ_CTRL_WORD_NO_READ_IN_PROG_V 0x00000000U -#define ADSP_RTOS_READ_CTRL_WORD_READ_IN_PROG_V 0x04000000U - -#define ADSP_RTOS_READ_CTRL_WORD_CMD_TYPE_M 0x03000000U -#define ADSP_RTOS_READ_CTRL_WORD_CMD_TASK_TO_H_V 0x00000000U -#define ADSP_RTOS_READ_CTRL_WORD_CMD_KRNL_TO_H_V 0x01000000U -#define ADSP_RTOS_READ_CTRL_WORD_CMD_H_TO_KRNL_CFM_V 0x02000000U - -#define ADSP_RTOS_READ_CTRL_WORD_DSP_ADDR_M 0x00FFFFFFU - -#define ADSP_RTOS_READ_CTRL_WORD_MSG_ID_M 0x000000FFU -#define ADSP_RTOS_READ_CTRL_WORD_TASK_ID_M 0x0000FF00U - -/* Base address of DSP and DSP hardware registers */ -#define QDSP_RAMC_OFFSET 0x400000 - -#endif diff --git a/arch/arm/mach-msm/qdsp5/adsp_6210.c b/arch/arm/mach-msm/qdsp5/adsp_6210.c deleted file mode 100644 index bf69ce2eebc14abd57575f4be944cde4602027cb..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/adsp_6210.c +++ /dev/null @@ -1,283 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/adsp_6210.h - * - * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include "adsp.h" - -/* Firmware modules */ -typedef enum { - QDSP_MODULE_KERNEL, - QDSP_MODULE_AFETASK, - QDSP_MODULE_AUDPLAY0TASK, - QDSP_MODULE_AUDPLAY1TASK, - QDSP_MODULE_AUDPPTASK, - QDSP_MODULE_VIDEOTASK, - QDSP_MODULE_VIDEO_AAC_VOC, - QDSP_MODULE_PCM_DEC, - QDSP_MODULE_AUDIO_DEC_MP3, - QDSP_MODULE_AUDIO_DEC_AAC, - QDSP_MODULE_AUDIO_DEC_WMA, - QDSP_MODULE_HOSTPCM, - QDSP_MODULE_DTMF, - QDSP_MODULE_AUDRECTASK, - QDSP_MODULE_AUDPREPROCTASK, - QDSP_MODULE_SBC_ENC, - QDSP_MODULE_VOC, - QDSP_MODULE_VOC_PCM, - QDSP_MODULE_VOCENCTASK, - QDSP_MODULE_VOCDECTASK, - QDSP_MODULE_VOICEPROCTASK, - QDSP_MODULE_VIDEOENCTASK, - QDSP_MODULE_VFETASK, - QDSP_MODULE_WAV_ENC, - QDSP_MODULE_AACLC_ENC, - QDSP_MODULE_VIDEO_AMR, - QDSP_MODULE_VOC_AMR, - QDSP_MODULE_VOC_EVRC, - QDSP_MODULE_VOC_13K, - QDSP_MODULE_VOC_FGV, - QDSP_MODULE_DIAGTASK, - QDSP_MODULE_JPEGTASK, - QDSP_MODULE_LPMTASK, - QDSP_MODULE_QCAMTASK, - QDSP_MODULE_MODMATHTASK, - QDSP_MODULE_AUDPLAY2TASK, - QDSP_MODULE_AUDPLAY3TASK, - QDSP_MODULE_AUDPLAY4TASK, - QDSP_MODULE_GRAPHICSTASK, - QDSP_MODULE_MIDI, - QDSP_MODULE_GAUDIO, - QDSP_MODULE_VDEC_LP_MODE, - QDSP_MODULE_MAX, -} qdsp_module_type; - -#define QDSP_RTOS_MAX_TASK_ID 19U - -/* Table of modules indexed by task ID for the GAUDIO image */ -static qdsp_module_type qdsp_gaudio_task_to_module_table[] = { - QDSP_MODULE_KERNEL, - QDSP_MODULE_AFETASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_AUDPPTASK, - QDSP_MODULE_AUDPLAY0TASK, - QDSP_MODULE_AUDPLAY1TASK, - QDSP_MODULE_AUDPLAY2TASK, - QDSP_MODULE_AUDPLAY3TASK, - QDSP_MODULE_AUDPLAY4TASK, - QDSP_MODULE_MAX, - QDSP_MODULE_AUDRECTASK, - QDSP_MODULE_AUDPREPROCTASK, - QDSP_MODULE_MAX, - QDSP_MODULE_GRAPHICSTASK, - QDSP_MODULE_MAX -}; - -/* Queue offset table indexed by queue ID for the GAUDIO image */ -static uint32_t qdsp_gaudio_queue_offset_table[] = { - QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */ - 0x3be, /* QDSP_mpuAfeQueue */ - 0x3ee, /* QDSP_mpuGraphicsCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecPktQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */ - 0x3c2, /* QDSP_uPAudPPCmd1Queue */ - 0x3c6, /* QDSP_uPAudPPCmd2Queue */ - 0x3ca, /* QDSP_uPAudPPCmd3Queue */ - 0x3da, /* QDSP_uPAudPlay0BitStreamCtrlQueue */ - 0x3de, /* QDSP_uPAudPlay1BitStreamCtrlQueue */ - 0x3e2, /* QDSP_uPAudPlay2BitStreamCtrlQueue */ - 0x3e6, /* QDSP_uPAudPlay3BitStreamCtrlQueue */ - 0x3ea, /* QDSP_uPAudPlay4BitStreamCtrlQueue */ - 0x3ce, /* QDSP_uPAudPreProcCmdQueue */ - 0x3d6, /* QDSP_uPAudRecBitStreamQueue */ - 0x3d2, /* QDSP_uPAudRecCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */ - QDSP_RTOS_NO_QUEUE /* QDSP_vfeCommandTableQueue */ -}; - -/* Table of modules indexed by task ID for the COMBO image */ -static qdsp_module_type qdsp_combo_task_to_module_table[] = { - QDSP_MODULE_KERNEL, - QDSP_MODULE_AFETASK, - QDSP_MODULE_VOCDECTASK, - QDSP_MODULE_VOCENCTASK, - QDSP_MODULE_VIDEOTASK, - QDSP_MODULE_VIDEOENCTASK, - QDSP_MODULE_VOICEPROCTASK, - QDSP_MODULE_VFETASK, - QDSP_MODULE_JPEGTASK, - QDSP_MODULE_AUDPPTASK, - QDSP_MODULE_AUDPLAY0TASK, - QDSP_MODULE_AUDPLAY1TASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_LPMTASK, - QDSP_MODULE_AUDRECTASK, - QDSP_MODULE_AUDPREPROCTASK, - QDSP_MODULE_MODMATHTASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX -}; - -/* Queue offset table indexed by queue ID for the COMBO image */ -static uint32_t qdsp_combo_queue_offset_table[] = { - 0x585, /* QDSP_lpmCommandQueue */ - 0x52d, /* QDSP_mpuAfeQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */ - 0x541, /* QDSP_mpuModmathCmdQueue */ - 0x555, /* QDSP_mpuVDecCmdQueue */ - 0x559, /* QDSP_mpuVDecPktQueue */ - 0x551, /* QDSP_mpuVEncCmdQueue */ - 0x535, /* QDSP_rxMpuDecCmdQueue */ - 0x539, /* QDSP_rxMpuDecPktQueue */ - 0x53d, /* QDSP_txMpuEncQueue */ - 0x55d, /* QDSP_uPAudPPCmd1Queue */ - 0x561, /* QDSP_uPAudPPCmd2Queue */ - 0x565, /* QDSP_uPAudPPCmd3Queue */ - 0x575, /* QDSP_uPAudPlay0BitStreamCtrlQueue */ - 0x579, /* QDSP_uPAudPlay1BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */ - 0x569, /* QDSP_uPAudPreProcCmdQueue */ - 0x571, /* QDSP_uPAudRecBitStreamQueue */ - 0x56d, /* QDSP_uPAudRecCmdQueue */ - 0x581, /* QDSP_uPJpegActionCmdQueue */ - 0x57d, /* QDSP_uPJpegCfgCmdQueue */ - 0x531, /* QDSP_uPVocProcQueue */ - 0x545, /* QDSP_vfeCommandQueue */ - 0x54d, /* QDSP_vfeCommandScaleQueue */ - 0x549 /* QDSP_vfeCommandTableQueue */ -}; - -/* Table of modules indexed by task ID for the QTV_LP image */ -static qdsp_module_type qdsp_qtv_lp_task_to_module_table[] = { - QDSP_MODULE_KERNEL, - QDSP_MODULE_AFETASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_VIDEOTASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_AUDPPTASK, - QDSP_MODULE_AUDPLAY0TASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_AUDRECTASK, - QDSP_MODULE_AUDPREPROCTASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX -}; - -/* Queue offset table indexed by queue ID for the QTV_LP image */ -static uint32_t qdsp_qtv_lp_queue_offset_table[] = { - QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */ - 0x40c, /* QDSP_mpuAfeQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */ - 0x410, /* QDSP_mpuVDecCmdQueue */ - 0x414, /* QDSP_mpuVDecPktQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */ - 0x41c, /* QDSP_uPAudPPCmd1Queue */ - 0x420, /* QDSP_uPAudPPCmd2Queue */ - 0x424, /* QDSP_uPAudPPCmd3Queue */ - 0x430, /* QDSP_uPAudPlay0BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay1BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */ - 0x418, /* QDSP_uPAudPreProcCmdQueue */ - 0x42c, /* QDSP_uPAudRecBitStreamQueue */ - 0x428, /* QDSP_uPAudRecCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */ - QDSP_RTOS_NO_QUEUE /* QDSP_vfeCommandTableQueue */ -}; - -/* Tables to convert tasks to modules */ -static uint32_t *qdsp_task_to_module[] = { - qdsp_combo_task_to_module_table, - qdsp_gaudio_task_to_module_table, - qdsp_qtv_lp_task_to_module_table, -}; - -/* Tables to retrieve queue offsets */ -static uint32_t *qdsp_queue_offset_table[] = { - qdsp_combo_queue_offset_table, - qdsp_gaudio_queue_offset_table, - qdsp_qtv_lp_queue_offset_table, -}; - -#define QDSP_MODULE(n) \ - { .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n } - -static struct adsp_module_info module_info[] = { - QDSP_MODULE(AUDPPTASK), - QDSP_MODULE(AUDRECTASK), - QDSP_MODULE(AUDPREPROCTASK), - QDSP_MODULE(VFETASK), - QDSP_MODULE(QCAMTASK), - QDSP_MODULE(LPMTASK), - QDSP_MODULE(JPEGTASK), - QDSP_MODULE(VIDEOTASK), - QDSP_MODULE(VDEC_LP_MODE), -}; - -int adsp_init_info(struct adsp_info *info) -{ - info->send_irq = 0x00c00200; - info->read_ctrl = 0x00400038; - info->write_ctrl = 0x00400034; - - info->max_msg16_size = 193; - info->max_msg32_size = 8; - - info->max_task_id = 16; - info->max_module_id = QDSP_MODULE_MAX - 1; - info->max_queue_id = QDSP_QUEUE_MAX; - info->max_image_id = 2; - info->queue_offset = qdsp_queue_offset_table; - info->task_to_module = qdsp_task_to_module; - - info->module_count = ARRAY_SIZE(module_info); - info->module = module_info; - return 0; -} diff --git a/arch/arm/mach-msm/qdsp5/adsp_6220.c b/arch/arm/mach-msm/qdsp5/adsp_6220.c deleted file mode 100644 index 007379042831cf6be57efee40349d778e929a870..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/adsp_6220.c +++ /dev/null @@ -1,284 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/adsp_6220.h - * - * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include "adsp.h" - -/* Firmware modules */ -typedef enum { - QDSP_MODULE_KERNEL, - QDSP_MODULE_AFETASK, - QDSP_MODULE_AUDPLAY0TASK, - QDSP_MODULE_AUDPLAY1TASK, - QDSP_MODULE_AUDPPTASK, - QDSP_MODULE_VIDEOTASK, - QDSP_MODULE_VIDEO_AAC_VOC, - QDSP_MODULE_PCM_DEC, - QDSP_MODULE_AUDIO_DEC_MP3, - QDSP_MODULE_AUDIO_DEC_AAC, - QDSP_MODULE_AUDIO_DEC_WMA, - QDSP_MODULE_HOSTPCM, - QDSP_MODULE_DTMF, - QDSP_MODULE_AUDRECTASK, - QDSP_MODULE_AUDPREPROCTASK, - QDSP_MODULE_SBC_ENC, - QDSP_MODULE_VOC, - QDSP_MODULE_VOC_PCM, - QDSP_MODULE_VOCENCTASK, - QDSP_MODULE_VOCDECTASK, - QDSP_MODULE_VOICEPROCTASK, - QDSP_MODULE_VIDEOENCTASK, - QDSP_MODULE_VFETASK, - QDSP_MODULE_WAV_ENC, - QDSP_MODULE_AACLC_ENC, - QDSP_MODULE_VIDEO_AMR, - QDSP_MODULE_VOC_AMR, - QDSP_MODULE_VOC_EVRC, - QDSP_MODULE_VOC_13K, - QDSP_MODULE_VOC_FGV, - QDSP_MODULE_DIAGTASK, - QDSP_MODULE_JPEGTASK, - QDSP_MODULE_LPMTASK, - QDSP_MODULE_QCAMTASK, - QDSP_MODULE_MODMATHTASK, - QDSP_MODULE_AUDPLAY2TASK, - QDSP_MODULE_AUDPLAY3TASK, - QDSP_MODULE_AUDPLAY4TASK, - QDSP_MODULE_GRAPHICSTASK, - QDSP_MODULE_MIDI, - QDSP_MODULE_GAUDIO, - QDSP_MODULE_VDEC_LP_MODE, - QDSP_MODULE_MAX, -} qdsp_module_type; - -#define QDSP_RTOS_MAX_TASK_ID 19U - -/* Table of modules indexed by task ID for the GAUDIO image */ -static qdsp_module_type qdsp_gaudio_task_to_module_table[] = { - QDSP_MODULE_KERNEL, - QDSP_MODULE_AFETASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_AUDPPTASK, - QDSP_MODULE_AUDPLAY0TASK, - QDSP_MODULE_AUDPLAY1TASK, - QDSP_MODULE_AUDPLAY2TASK, - QDSP_MODULE_AUDPLAY3TASK, - QDSP_MODULE_AUDPLAY4TASK, - QDSP_MODULE_MAX, - QDSP_MODULE_AUDRECTASK, - QDSP_MODULE_AUDPREPROCTASK, - QDSP_MODULE_MAX, - QDSP_MODULE_GRAPHICSTASK, - QDSP_MODULE_MAX -}; - -/* Queue offset table indexed by queue ID for the GAUDIO image */ -static uint32_t qdsp_gaudio_queue_offset_table[] = { - QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */ - 0x3f0, /* QDSP_mpuAfeQueue */ - 0x420, /* QDSP_mpuGraphicsCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecPktQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */ - 0x3f4, /* QDSP_uPAudPPCmd1Queue */ - 0x3f8, /* QDSP_uPAudPPCmd2Queue */ - 0x3fc, /* QDSP_uPAudPPCmd3Queue */ - 0x40c, /* QDSP_uPAudPlay0BitStreamCtrlQueue */ - 0x410, /* QDSP_uPAudPlay1BitStreamCtrlQueue */ - 0x414, /* QDSP_uPAudPlay2BitStreamCtrlQueue */ - 0x418, /* QDSP_uPAudPlay3BitStreamCtrlQueue */ - 0x41c, /* QDSP_uPAudPlay4BitStreamCtrlQueue */ - 0x400, /* QDSP_uPAudPreProcCmdQueue */ - 0x408, /* QDSP_uPAudRecBitStreamQueue */ - 0x404, /* QDSP_uPAudRecCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */ - QDSP_RTOS_NO_QUEUE /* QDSP_vfeCommandTableQueue */ -}; - -/* Table of modules indexed by task ID for the COMBO image */ -static qdsp_module_type qdsp_combo_task_to_module_table[] = { - QDSP_MODULE_KERNEL, - QDSP_MODULE_AFETASK, - QDSP_MODULE_VOCDECTASK, - QDSP_MODULE_VOCENCTASK, - QDSP_MODULE_VIDEOTASK, - QDSP_MODULE_VIDEOENCTASK, - QDSP_MODULE_VOICEPROCTASK, - QDSP_MODULE_VFETASK, - QDSP_MODULE_JPEGTASK, - QDSP_MODULE_AUDPPTASK, - QDSP_MODULE_AUDPLAY0TASK, - QDSP_MODULE_AUDPLAY1TASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_LPMTASK, - QDSP_MODULE_AUDRECTASK, - QDSP_MODULE_AUDPREPROCTASK, - QDSP_MODULE_MODMATHTASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX -}; - -/* Queue offset table indexed by queue ID for the COMBO image */ -static uint32_t qdsp_combo_queue_offset_table[] = { - 0x6f2, /* QDSP_lpmCommandQueue */ - 0x69e, /* QDSP_mpuAfeQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */ - 0x6b2, /* QDSP_mpuModmathCmdQueue */ - 0x6c6, /* QDSP_mpuVDecCmdQueue */ - 0x6ca, /* QDSP_mpuVDecPktQueue */ - 0x6c2, /* QDSP_mpuVEncCmdQueue */ - 0x6a6, /* QDSP_rxMpuDecCmdQueue */ - 0x6aa, /* QDSP_rxMpuDecPktQueue */ - 0x6ae, /* QDSP_txMpuEncQueue */ - 0x6ce, /* QDSP_uPAudPPCmd1Queue */ - 0x6d2, /* QDSP_uPAudPPCmd2Queue */ - 0x6d6, /* QDSP_uPAudPPCmd3Queue */ - 0x6e6, /* QDSP_uPAudPlay0BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay1BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */ - 0x6da, /* QDSP_uPAudPreProcCmdQueue */ - 0x6e2, /* QDSP_uPAudRecBitStreamQueue */ - 0x6de, /* QDSP_uPAudRecCmdQueue */ - 0x6ee, /* QDSP_uPJpegActionCmdQueue */ - 0x6ea, /* QDSP_uPJpegCfgCmdQueue */ - 0x6a2, /* QDSP_uPVocProcQueue */ - 0x6b6, /* QDSP_vfeCommandQueue */ - 0x6be, /* QDSP_vfeCommandScaleQueue */ - 0x6ba /* QDSP_vfeCommandTableQueue */ -}; - -/* Table of modules indexed by task ID for the QTV_LP image */ -static qdsp_module_type qdsp_qtv_lp_task_to_module_table[] = { - QDSP_MODULE_KERNEL, - QDSP_MODULE_AFETASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_VIDEOTASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_AUDPPTASK, - QDSP_MODULE_AUDPLAY0TASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_AUDRECTASK, - QDSP_MODULE_AUDPREPROCTASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX -}; - -/* Queue offset table indexed by queue ID for the QTV_LP image */ -static uint32_t qdsp_qtv_lp_queue_offset_table[] = { - QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */ - 0x430, /* QDSP_mpuAfeQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */ - 0x434, /* QDSP_mpuVDecCmdQueue */ - 0x438, /* QDSP_mpuVDecPktQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */ - 0x440, /* QDSP_uPAudPPCmd1Queue */ - 0x444, /* QDSP_uPAudPPCmd2Queue */ - 0x448, /* QDSP_uPAudPPCmd3Queue */ - 0x454, /* QDSP_uPAudPlay0BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay1BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */ - 0x43c, /* QDSP_uPAudPreProcCmdQueue */ - 0x450, /* QDSP_uPAudRecBitStreamQueue */ - 0x44c, /* QDSP_uPAudRecCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */ - QDSP_RTOS_NO_QUEUE /* QDSP_vfeCommandTableQueue */ -}; - -/* Tables to convert tasks to modules */ -static qdsp_module_type *qdsp_task_to_module[] = { - qdsp_combo_task_to_module_table, - qdsp_gaudio_task_to_module_table, - qdsp_qtv_lp_task_to_module_table, -}; - -/* Tables to retrieve queue offsets */ -static uint32_t *qdsp_queue_offset_table[] = { - qdsp_combo_queue_offset_table, - qdsp_gaudio_queue_offset_table, - qdsp_qtv_lp_queue_offset_table, -}; - -#define QDSP_MODULE(n) \ - { .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n } - -static struct adsp_module_info module_info[] = { - QDSP_MODULE(AUDPLAY0TASK), - QDSP_MODULE(AUDPPTASK), - QDSP_MODULE(AUDPREPROCTASK), - QDSP_MODULE(AUDRECTASK), - QDSP_MODULE(VFETASK), - QDSP_MODULE(QCAMTASK), - QDSP_MODULE(LPMTASK), - QDSP_MODULE(JPEGTASK), - QDSP_MODULE(VIDEOTASK), - QDSP_MODULE(VDEC_LP_MODE), -}; - -int adsp_init_info(struct adsp_info *info) -{ - info->send_irq = 0x00c00200; - info->read_ctrl = 0x00400038; - info->write_ctrl = 0x00400034; - - info->max_msg16_size = 193; - info->max_msg32_size = 8; - - info->max_task_id = 16; - info->max_module_id = QDSP_MODULE_MAX - 1; - info->max_queue_id = QDSP_QUEUE_MAX; - info->max_image_id = 2; - info->queue_offset = qdsp_queue_offset_table; - info->task_to_module = qdsp_task_to_module; - - info->module_count = ARRAY_SIZE(module_info); - info->module = module_info; - return 0; -} diff --git a/arch/arm/mach-msm/qdsp5/adsp_6225.c b/arch/arm/mach-msm/qdsp5/adsp_6225.c deleted file mode 100644 index 6a402b7037aa5ca8418c466caa99ec7e1b3db743..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/adsp_6225.c +++ /dev/null @@ -1,328 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/adsp_6225.h - * - * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include "adsp.h" - -/* Firmware modules */ -typedef enum { - QDSP_MODULE_KERNEL, - QDSP_MODULE_AFETASK, - QDSP_MODULE_AUDPLAY0TASK, - QDSP_MODULE_AUDPLAY1TASK, - QDSP_MODULE_AUDPPTASK, - QDSP_MODULE_VIDEOTASK, - QDSP_MODULE_VIDEO_AAC_VOC, - QDSP_MODULE_PCM_DEC, - QDSP_MODULE_AUDIO_DEC_MP3, - QDSP_MODULE_AUDIO_DEC_AAC, - QDSP_MODULE_AUDIO_DEC_WMA, - QDSP_MODULE_HOSTPCM, - QDSP_MODULE_DTMF, - QDSP_MODULE_AUDRECTASK, - QDSP_MODULE_AUDPREPROCTASK, - QDSP_MODULE_SBC_ENC, - QDSP_MODULE_VOC_UMTS, - QDSP_MODULE_VOC_CDMA, - QDSP_MODULE_VOC_PCM, - QDSP_MODULE_VOCENCTASK, - QDSP_MODULE_VOCDECTASK, - QDSP_MODULE_VOICEPROCTASK, - QDSP_MODULE_VIDEOENCTASK, - QDSP_MODULE_VFETASK, - QDSP_MODULE_WAV_ENC, - QDSP_MODULE_AACLC_ENC, - QDSP_MODULE_VIDEO_AMR, - QDSP_MODULE_VOC_AMR, - QDSP_MODULE_VOC_EVRC, - QDSP_MODULE_VOC_13K, - QDSP_MODULE_VOC_FGV, - QDSP_MODULE_DIAGTASK, - QDSP_MODULE_JPEGTASK, - QDSP_MODULE_LPMTASK, - QDSP_MODULE_QCAMTASK, - QDSP_MODULE_MODMATHTASK, - QDSP_MODULE_AUDPLAY2TASK, - QDSP_MODULE_AUDPLAY3TASK, - QDSP_MODULE_AUDPLAY4TASK, - QDSP_MODULE_GRAPHICSTASK, - QDSP_MODULE_MIDI, - QDSP_MODULE_GAUDIO, - QDSP_MODULE_VDEC_LP_MODE, - QDSP_MODULE_MAX, -} qdsp_module_type; - -#define QDSP_RTOS_MAX_TASK_ID 30U - -/* Table of modules indexed by task ID for the GAUDIO image */ -static qdsp_module_type qdsp_gaudio_task_to_module_table[] = { - QDSP_MODULE_KERNEL, - QDSP_MODULE_AFETASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_AUDPPTASK, - QDSP_MODULE_AUDPLAY0TASK, - QDSP_MODULE_AUDPLAY1TASK, - QDSP_MODULE_AUDPLAY2TASK, - QDSP_MODULE_AUDPLAY3TASK, - QDSP_MODULE_AUDPLAY4TASK, - QDSP_MODULE_MAX, - QDSP_MODULE_AUDRECTASK, - QDSP_MODULE_AUDPREPROCTASK, - QDSP_MODULE_MAX, - QDSP_MODULE_GRAPHICSTASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, -}; - -/* Queue offset table indexed by queue ID for the GAUDIO image */ -static uint32_t qdsp_gaudio_queue_offset_table[] = { - QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */ - 0x3f0, /* QDSP_mpuAfeQueue */ - 0x420, /* QDSP_mpuGraphicsCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecPktQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */ - 0x3f4, /* QDSP_uPAudPPCmd1Queue */ - 0x3f8, /* QDSP_uPAudPPCmd2Queue */ - 0x3fc, /* QDSP_uPAudPPCmd3Queue */ - 0x40c, /* QDSP_uPAudPlay0BitStreamCtrlQueue */ - 0x410, /* QDSP_uPAudPlay1BitStreamCtrlQueue */ - 0x414, /* QDSP_uPAudPlay2BitStreamCtrlQueue */ - 0x418, /* QDSP_uPAudPlay3BitStreamCtrlQueue */ - 0x41c, /* QDSP_uPAudPlay4BitStreamCtrlQueue */ - 0x400, /* QDSP_uPAudPreProcCmdQueue */ - 0x408, /* QDSP_uPAudRecBitStreamQueue */ - 0x404, /* QDSP_uPAudRecCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandTableQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPDiagQueue */ -}; - -/* Table of modules indexed by task ID for the COMBO image */ -static qdsp_module_type qdsp_combo_task_to_module_table[] = { - QDSP_MODULE_KERNEL, - QDSP_MODULE_AFETASK, - QDSP_MODULE_VOCDECTASK, - QDSP_MODULE_VOCENCTASK, - QDSP_MODULE_VIDEOTASK, - QDSP_MODULE_VIDEOENCTASK, - QDSP_MODULE_VOICEPROCTASK, - QDSP_MODULE_VFETASK, - QDSP_MODULE_JPEGTASK, - QDSP_MODULE_AUDPPTASK, - QDSP_MODULE_AUDPLAY0TASK, - QDSP_MODULE_AUDPLAY1TASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_LPMTASK, - QDSP_MODULE_AUDRECTASK, - QDSP_MODULE_AUDPREPROCTASK, - QDSP_MODULE_MODMATHTASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_DIAGTASK, - QDSP_MODULE_MAX, -}; - -/* Queue offset table indexed by queue ID for the COMBO image */ -static uint32_t qdsp_combo_queue_offset_table[] = { - 0x714, /* QDSP_lpmCommandQueue */ - 0x6bc, /* QDSP_mpuAfeQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */ - 0x6d0, /* QDSP_mpuModmathCmdQueue */ - 0x6e8, /* QDSP_mpuVDecCmdQueue */ - 0x6ec, /* QDSP_mpuVDecPktQueue */ - 0x6e4, /* QDSP_mpuVEncCmdQueue */ - 0x6c4, /* QDSP_rxMpuDecCmdQueue */ - 0x6c8, /* QDSP_rxMpuDecPktQueue */ - 0x6cc, /* QDSP_txMpuEncQueue */ - 0x6f0, /* QDSP_uPAudPPCmd1Queue */ - 0x6f4, /* QDSP_uPAudPPCmd2Queue */ - 0x6f8, /* QDSP_uPAudPPCmd3Queue */ - 0x708, /* QDSP_uPAudPlay0BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay1BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */ - 0x6fc, /* QDSP_uPAudPreProcCmdQueue */ - 0x704, /* QDSP_uPAudRecBitStreamQueue */ - 0x700, /* QDSP_uPAudRecCmdQueue */ - 0x710, /* QDSP_uPJpegActionCmdQueue */ - 0x70c, /* QDSP_uPJpegCfgCmdQueue */ - 0x6c0, /* QDSP_uPVocProcQueue */ - 0x6d8, /* QDSP_vfeCommandQueue */ - 0x6e0, /* QDSP_vfeCommandScaleQueue */ - 0x6dc, /* QDSP_vfeCommandTableQueue */ - 0x6d4, /* QDSP_uPDiagQueue */ -}; - -/* Table of modules indexed by task ID for the QTV_LP image */ -static qdsp_module_type qdsp_qtv_lp_task_to_module_table[] = { - QDSP_MODULE_KERNEL, - QDSP_MODULE_AFETASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_VIDEOTASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_AUDPPTASK, - QDSP_MODULE_AUDPLAY0TASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_AUDRECTASK, - QDSP_MODULE_AUDPREPROCTASK, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, - QDSP_MODULE_MAX, -}; - -/* Queue offset table indexed by queue ID for the QTV_LP image */ -static uint32_t qdsp_qtv_lp_queue_offset_table[] = { - QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */ - 0x3fe, /* QDSP_mpuAfeQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */ - 0x402, /* QDSP_mpuVDecCmdQueue */ - 0x406, /* QDSP_mpuVDecPktQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */ - 0x40e, /* QDSP_uPAudPPCmd1Queue */ - 0x412, /* QDSP_uPAudPPCmd2Queue */ - 0x416, /* QDSP_uPAudPPCmd3Queue */ - 0x422, /* QDSP_uPAudPlay0BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay1BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */ - 0x40a, /* QDSP_uPAudPreProcCmdQueue */ - 0x41e, /* QDSP_uPAudRecBitStreamQueue */ - 0x41a, /* QDSP_uPAudRecCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandTableQueue */ - QDSP_RTOS_NO_QUEUE, /* QDSP_uPDiagQueue */ -}; - -/* Tables to convert tasks to modules */ -static qdsp_module_type *qdsp_task_to_module[] = { - qdsp_combo_task_to_module_table, - qdsp_gaudio_task_to_module_table, - qdsp_qtv_lp_task_to_module_table, -}; - -/* Tables to retrieve queue offsets */ -static uint32_t *qdsp_queue_offset_table[] = { - qdsp_combo_queue_offset_table, - qdsp_gaudio_queue_offset_table, - qdsp_qtv_lp_queue_offset_table, -}; - -#define QDSP_MODULE(n, clkname, clkrate, verify_cmd_func, patch_event_func) \ - { .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n, \ - .clk_name = clkname, .clk_rate = clkrate, \ - .verify_cmd = verify_cmd_func, .patch_event = patch_event_func } - -static struct adsp_module_info module_info[] = { - QDSP_MODULE(AUDPLAY0TASK, NULL, 0, NULL, NULL), - QDSP_MODULE(AUDPPTASK, NULL, 0, NULL, NULL), - QDSP_MODULE(AUDRECTASK, NULL, 0, NULL, NULL), - QDSP_MODULE(AUDPREPROCTASK, NULL, 0, NULL, NULL), - QDSP_MODULE(VFETASK, "vfe_clk", 0, adsp_vfe_verify_cmd, - adsp_vfe_patch_event), - QDSP_MODULE(QCAMTASK, NULL, 0, NULL, NULL), - QDSP_MODULE(LPMTASK, NULL, 0, adsp_lpm_verify_cmd, NULL), - QDSP_MODULE(JPEGTASK, "vdc_clk", 0, adsp_jpeg_verify_cmd, - adsp_jpeg_patch_event), - QDSP_MODULE(VIDEOTASK, "vdc_clk", 96000000, - adsp_video_verify_cmd, NULL), - QDSP_MODULE(VDEC_LP_MODE, NULL, 0, NULL, NULL), - QDSP_MODULE(VIDEOENCTASK, "vdc_clk", 96000000, - adsp_videoenc_verify_cmd, NULL), -}; - -int adsp_init_info(struct adsp_info *info) -{ - info->send_irq = 0x00c00200; - info->read_ctrl = 0x00400038; - info->write_ctrl = 0x00400034; - - info->max_msg16_size = 193; - info->max_msg32_size = 8; - - info->max_task_id = 16; - info->max_module_id = QDSP_MODULE_MAX - 1; - info->max_queue_id = QDSP_QUEUE_MAX; - info->max_image_id = 2; - info->queue_offset = qdsp_queue_offset_table; - info->task_to_module = qdsp_task_to_module; - - info->module_count = ARRAY_SIZE(module_info); - info->module = module_info; - return 0; -} diff --git a/arch/arm/mach-msm/qdsp5/adsp_debug.c b/arch/arm/mach-msm/qdsp5/adsp_debug.c deleted file mode 100644 index ccddd43fe4bf7bac00493b2b90a496bbaf40054e..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/adsp_debug.c +++ /dev/null @@ -1,97 +0,0 @@ -/* Copyright (c) 2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "adsp.h" - -#define MAX_LEN 64 -#ifdef CONFIG_DEBUG_FS -static struct dentry *adsp_dentry; -#endif -static char l_buf[MAX_LEN]; -static unsigned int crash_enable; - -static ssize_t q5_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - MM_DBG("q5 debugfs opened\n"); - return 0; -} - -static ssize_t q5_debug_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - int len; - - if (count < 0) - return 0; - len = count > (MAX_LEN - 1) ? (MAX_LEN - 1) : count; - if (copy_from_user(l_buf, buf, len)) { - MM_INFO("Unable to copy data from user space\n"); - return -EFAULT; - } - l_buf[len] = 0; - if (l_buf[len - 1] == '\n') { - l_buf[len - 1] = 0; - len--; - } - if (!strncmp(l_buf, "boom", MAX_LEN)) { - q5audio_dsp_not_responding(); - } else if (!strncmp(l_buf, "enable", MAX_LEN)) { - crash_enable = 1; - MM_INFO("Crash enabled : %d\n", crash_enable); - } else if (!strncmp(l_buf, "disable", MAX_LEN)) { - crash_enable = 0; - MM_INFO("Crash disabled : %d\n", crash_enable); - } else - MM_INFO("Unknown Command\n"); - - return count; -} - -static const struct file_operations q5_debug_fops = { - .write = q5_debug_write, - .open = q5_debug_open, -}; - -static int __init q5_debug_init(void) -{ -#ifdef CONFIG_DEBUG_FS - adsp_dentry = debugfs_create_file("q5_debug", S_IFREG | S_IRUGO, - NULL, (void *) NULL, &q5_debug_fops); -#endif /* CONFIG_DEBUG_FS */ - return 0; -} -device_initcall(q5_debug_init); - diff --git a/arch/arm/mach-msm/qdsp5/adsp_driver.c b/arch/arm/mach-msm/qdsp5/adsp_driver.c deleted file mode 100644 index d83a1409291f1b728de3af8075c1ed24fbec0413..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/adsp_driver.c +++ /dev/null @@ -1,745 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/adsp_driver.c - * - * Copyright (C) 2008 Google, Inc. - * Copyright (c) 2009, 2012 The Linux Foundation. All rights reserved. - * Author: Iliyan Malchev - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "adsp.h" -#include -#include -#include - -struct adsp_ion_info { - int fd; - void *vaddr; -}; - -struct adsp_ion_region { - struct hlist_node list; - void *vaddr; - unsigned long paddr; - unsigned long kvaddr; - unsigned long len; - unsigned long ion_flag; - struct file *file; - struct ion_handle *handle; - struct ion_client *client; - int fd; -}; - -struct adsp_device { - struct msm_adsp_module *module; - - spinlock_t event_queue_lock; - wait_queue_head_t event_wait; - struct list_head event_queue; - int abort; - - const char *name; - struct device *device; - struct cdev cdev; -}; - -static struct adsp_device *inode_to_device(struct inode *inode); - -#define __CONTAINS(r, v, l) ({ \ - typeof(r) __r = r; \ - typeof(v) __v = v; \ - typeof(v) __e = __v + l; \ - int res = __v >= __r->vaddr && \ - __e <= __r->vaddr + __r->len; \ - res; \ -}) - -#define CONTAINS(r1, r2) ({ \ - typeof(r2) __r2 = r2; \ - __CONTAINS(r1, __r2->vaddr, __r2->len); \ -}) - -#define IN_RANGE(r, v) ({ \ - typeof(r) __r = r; \ - typeof(v) __vv = v; \ - int res = ((__vv >= __r->vaddr) && \ - (__vv < (__r->vaddr + __r->len))); \ - res; \ -}) - -#define OVERLAPS(r1, r2) ({ \ - typeof(r1) __r1 = r1; \ - typeof(r2) __r2 = r2; \ - typeof(__r2->vaddr) __v = __r2->vaddr; \ - typeof(__v) __e = __v + __r2->len - 1; \ - int res = (IN_RANGE(__r1, __v) || IN_RANGE(__r1, __e)); \ - res; \ -}) - -static int adsp_ion_check(struct msm_adsp_module *module, - void *vaddr, unsigned long len) -{ - struct adsp_ion_region *region_elt; - struct hlist_node *node; - struct adsp_ion_region t = { .vaddr = vaddr, .len = len }; - - hlist_for_each_entry(region_elt, node, &module->ion_regions, list) { - if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) || - OVERLAPS(region_elt, &t)) { - MM_ERR("module %s:" - " region (vaddr %p len %ld)" - " clashes with registered region" - " (vaddr %p paddr %p len %ld)\n", - module->name, - vaddr, len, - region_elt->vaddr, - (void *)region_elt->paddr, - region_elt->len); - return -EINVAL; - } - } - - return 0; -} - -static int get_ion_region_info(int fd, struct adsp_ion_region *region) -{ - unsigned long ionflag; - void *temp_ptr; - int rc = -EINVAL; - - region->client = msm_ion_client_create(UINT_MAX, "Video_Client"); - if (IS_ERR_OR_NULL(region->client)) { - pr_err("Unable to create ION client\n"); - goto client_error; - } - region->handle = ion_import_dma_buf(region->client, fd); - if (IS_ERR_OR_NULL(region->handle)) { - pr_err("%s: could not get handle of the given fd\n", __func__); - goto import_error; - } - rc = ion_handle_get_flags(region->client, region->handle, &ionflag); - if (rc) { - pr_err("%s: could not get flags for the handle\n", __func__); - goto flag_error; - } - temp_ptr = ion_map_kernel(region->client, region->handle); - if (IS_ERR_OR_NULL(temp_ptr)) { - pr_err("%s: could not get virtual address\n", __func__); - goto map_error; - } - region->kvaddr = (unsigned long) temp_ptr; - region->ion_flag = (unsigned long) ionflag; - - rc = ion_phys(region->client, region->handle, ®ion->paddr, - (size_t *)(®ion->len)); - if (rc) { - pr_err("%s: could not get physical address\n", __func__); - goto ion_error; - } - return rc; -ion_error: - ion_unmap_kernel(region->client, region->handle); -map_error: - ion_free(region->client, region->handle); -flag_error: -import_error: - ion_client_destroy(region->client); -client_error: - return -EINVAL; -} - -static void free_ion_region(struct ion_client *client, - struct ion_handle *handle) -{ - ion_unmap_kernel(client, handle); - ion_free(client, handle); - ion_client_destroy(client); -} - -static int adsp_ion_add(struct msm_adsp_module *module, - struct adsp_ion_info *info) -{ - struct adsp_ion_region *region; - int rc = -EINVAL; - mutex_lock(&module->ion_regions_lock); - region = kmalloc(sizeof(struct adsp_ion_region), GFP_KERNEL); - if (!region) { - rc = -ENOMEM; - goto end; - } - INIT_HLIST_NODE(®ion->list); - if (get_ion_region_info(info->fd, region)) { - kfree(region); - goto end; - } - - rc = adsp_ion_check(module, info->vaddr, region->len); - if (rc < 0) { - free_ion_region(region->client, region->handle); - kfree(region); - goto end; - } - region->vaddr = info->vaddr; - region->fd = info->fd; - region->file = NULL; - MM_INFO("adsp_ion_add: module %s: fd %d, vaddr Ox%x, len %d\n", - module->name, region->fd, (unsigned int)region->vaddr, - (int)region->len); - hlist_add_head(®ion->list, &module->ion_regions); -end: - mutex_unlock(&module->ion_regions_lock); - return rc; -} - -static int adsp_ion_lookup_vaddr(struct msm_adsp_module *module, void **addr, - unsigned long len, struct adsp_ion_region **region) -{ - struct hlist_node *node; - void *vaddr = *addr; - struct adsp_ion_region *region_elt; - - int match_count = 0; - - *region = NULL; - - /* returns physical address or zero */ - hlist_for_each_entry(region_elt, node, &module->ion_regions, list) { - if (vaddr >= region_elt->vaddr && - vaddr < region_elt->vaddr + region_elt->len && - vaddr + len <= region_elt->vaddr + region_elt->len) { - /* offset since we could pass vaddr inside a registerd - * pmem buffer - */ - - match_count++; - if (!*region) - *region = region_elt; - } - } - - if (match_count > 1) { - MM_ERR("module %s: " - "multiple hits for vaddr %p, len %ld\n", - module->name, vaddr, len); - hlist_for_each_entry(region_elt, node, - &module->ion_regions, list) { - if (vaddr >= region_elt->vaddr && - vaddr < region_elt->vaddr + region_elt->len && - vaddr + len <= region_elt->vaddr + region_elt->len) - MM_ERR("%p, %ld --> %p\n", - region_elt->vaddr, - region_elt->len, - (void *)region_elt->paddr); - } - } - - return *region ? 0 : -1; -} - -int adsp_ion_do_cache_op(struct msm_adsp_module *module, - void *addr, void *paddr, unsigned long len, - unsigned long offset, int cmd) -{ - struct adsp_ion_region *region; - void *vaddr = addr; - int ret; - ret = adsp_ion_lookup_vaddr(module, &vaddr, len, ®ion); - if (ret) { - MM_ERR("not patching %s (paddr & kvaddr)," \ - " lookup (%p, %ld) failed\n", - module->name, vaddr, len); - return ret; - } - if ((region->ion_flag == ION_FLAG_CACHED) && region->handle) { - len = ((((len) + 31) & (~31)) + 32); - ret = msm_ion_do_cache_op(region->client, region->handle, - (void *)paddr, len, cmd); - } - return ret; -} -int adsp_ion_fixup_kvaddr(struct msm_adsp_module *module, void **addr, - unsigned long *kvaddr, unsigned long len, - struct file **filp, unsigned long *offset) -{ - struct adsp_ion_region *region; - void *vaddr = *addr; - unsigned long *paddr = (unsigned long *)addr; - int ret; - - ret = adsp_ion_lookup_vaddr(module, addr, len, ®ion); - if (ret) { - MM_ERR("not patching %s (paddr & kvaddr)," - " lookup (%p, %ld) failed\n", - module->name, vaddr, len); - return ret; - } - *paddr = region->paddr + (vaddr - region->vaddr); - *kvaddr = region->kvaddr + (vaddr - region->vaddr); - if (filp) - *filp = region->file; - if (offset) - *offset = vaddr - region->vaddr; - return 0; -} - -int adsp_pmem_fixup(struct msm_adsp_module *module, void **addr, - unsigned long len) -{ - struct adsp_ion_region *region; - void *vaddr = *addr; - unsigned long *paddr = (unsigned long *)addr; - int ret; - - ret = adsp_ion_lookup_vaddr(module, addr, len, ®ion); - if (ret) { - MM_ERR("not patching %s, lookup (%p, %ld) failed\n", - module->name, vaddr, len); - return ret; - } - - *paddr = region->paddr + (vaddr - region->vaddr); - return 0; -} - -static int adsp_verify_cmd(struct msm_adsp_module *module, - unsigned int queue_id, void *cmd_data, - size_t cmd_size) -{ - /* call the per module verifier */ - if (module->verify_cmd) - return module->verify_cmd(module, queue_id, cmd_data, - cmd_size); - else - MM_INFO("no packet verifying function " - "for task %s\n", module->name); - return 0; -} - -static long adsp_write_cmd(struct adsp_device *adev, void __user *arg) -{ - struct adsp_command_t cmd; - unsigned char buf[256]; - void *cmd_data; - long rc; - - if (copy_from_user(&cmd, (void __user *)arg, sizeof(cmd))) - return -EFAULT; - - if (cmd.len > 256) { - cmd_data = kmalloc(cmd.len, GFP_USER); - if (!cmd_data) - return -ENOMEM; - } else { - cmd_data = buf; - } - - if (copy_from_user(cmd_data, (void __user *)(cmd.data), cmd.len)) { - rc = -EFAULT; - goto end; - } - - mutex_lock(&adev->module->ion_regions_lock); - if (adsp_verify_cmd(adev->module, cmd.queue, cmd_data, cmd.len)) { - MM_ERR("module %s: verify failed.\n", adev->module->name); - rc = -EINVAL; - goto end; - } - /* complete the writes to the buffer */ - wmb(); - rc = msm_adsp_write(adev->module, cmd.queue, cmd_data, cmd.len); -end: - mutex_unlock(&adev->module->ion_regions_lock); - - if (cmd.len > 256) - kfree(cmd_data); - - return rc; -} - -static int adsp_events_pending(struct adsp_device *adev) -{ - unsigned long flags; - int yes; - spin_lock_irqsave(&adev->event_queue_lock, flags); - yes = !list_empty(&adev->event_queue); - spin_unlock_irqrestore(&adev->event_queue_lock, flags); - return yes || adev->abort; -} - -static int adsp_ion_lookup_paddr(struct msm_adsp_module *module, void **addr, - struct adsp_ion_region **region) -{ - struct hlist_node *node; - unsigned long paddr = (unsigned long)(*addr); - struct adsp_ion_region *region_elt; - - hlist_for_each_entry(region_elt, node, &module->ion_regions, list) { - if (paddr >= region_elt->paddr && - paddr < region_elt->paddr + region_elt->len) { - *region = region_elt; - return 0; - } - } - return -1; -} - -int adsp_pmem_paddr_fixup(struct msm_adsp_module *module, void **addr) -{ - struct adsp_ion_region *region; - unsigned long paddr = (unsigned long)(*addr); - unsigned long *vaddr = (unsigned long *)addr; - int ret; - - ret = adsp_ion_lookup_paddr(module, addr, ®ion); - if (ret) { - MM_ERR("not patching %s, paddr %p lookup failed\n", - module->name, vaddr); - return ret; - } - - *vaddr = (unsigned long)region->vaddr + (paddr - region->paddr); - return 0; -} - -static int adsp_patch_event(struct msm_adsp_module *module, - struct adsp_event *event) -{ - /* call the per-module msg verifier */ - if (module->patch_event) - return module->patch_event(module, event); - return 0; -} - -static long adsp_get_event(struct adsp_device *adev, void __user *arg) -{ - unsigned long flags; - struct adsp_event *data = NULL; - struct adsp_event_t evt; - int timeout; - long rc = 0; - - if (copy_from_user(&evt, arg, sizeof(struct adsp_event_t))) - return -EFAULT; - - timeout = (int)evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - adev->event_wait, adsp_events_pending(adev), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - adev->event_wait, adsp_events_pending(adev)); - } - if (rc < 0) - return rc; - - if (adev->abort) - return -ENODEV; - - spin_lock_irqsave(&adev->event_queue_lock, flags); - if (!list_empty(&adev->event_queue)) { - data = list_first_entry(&adev->event_queue, - struct adsp_event, list); - list_del(&data->list); - } - spin_unlock_irqrestore(&adev->event_queue_lock, flags); - - if (!data) - return -EAGAIN; - - /* DSP messages are type 0; they may contain physical addresses */ - if (data->type == 0) - adsp_patch_event(adev->module, data); - - /* map adsp_event --> adsp_event_t */ - if (evt.len < data->size) { - rc = -ETOOSMALL; - goto end; - } - /* order the reads to the buffer */ - rmb(); - if (data->msg_id != EVENT_MSG_ID) { - if (copy_to_user((void *)(evt.data), data->data.msg16, - data->size)) { - rc = -EFAULT; - goto end; - } - } else { - if (copy_to_user((void *)(evt.data), data->data.msg32, - data->size)) { - rc = -EFAULT; - goto end; - } - } - - evt.type = data->type; /* 0 --> from aDSP, 1 --> from ARM9 */ - evt.msg_id = data->msg_id; - evt.flags = data->is16; - evt.len = data->size; - if (copy_to_user(arg, &evt, sizeof(evt))) - rc = -EFAULT; -end: - kfree(data); - return rc; -} - -static int adsp_ion_del(struct msm_adsp_module *module) -{ - struct hlist_node *node, *tmp; - struct adsp_ion_region *region; - - mutex_lock(&module->ion_regions_lock); - hlist_for_each_safe(node, tmp, &module->ion_regions) { - region = hlist_entry(node, struct adsp_ion_region, list); - hlist_del(node); - MM_INFO("adsp_ion_del: module %s: fd %d, vaddr Ox%x, len %d\n", - module->name, region->fd, (unsigned int)region->vaddr, - (int)region->len); - free_ion_region(region->client, region->handle); - kfree(region); - } - mutex_unlock(&module->ion_regions_lock); - BUG_ON(!hlist_empty(&module->ion_regions)); - - return 0; -} - -static long adsp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - struct adsp_device *adev = filp->private_data; - - switch (cmd) { - case ADSP_IOCTL_ENABLE: - return msm_adsp_enable(adev->module); - - case ADSP_IOCTL_DISABLE: - return msm_adsp_disable(adev->module); - - case ADSP_IOCTL_DISABLE_EVENT_RSP: - return msm_adsp_disable_event_rsp(adev->module); - - case ADSP_IOCTL_DISABLE_ACK: - MM_ERR("ADSP_IOCTL_DISABLE_ACK is not implemented\n"); - break; - - case ADSP_IOCTL_WRITE_COMMAND: - return adsp_write_cmd(adev, (void __user *) arg); - - case ADSP_IOCTL_GET_EVENT: - return adsp_get_event(adev, (void __user *) arg); - - case ADSP_IOCTL_SET_CLKRATE: { - unsigned long clk_rate; - if (copy_from_user(&clk_rate, (void *) arg, sizeof(clk_rate))) - return -EFAULT; - return adsp_set_clkrate(adev->module, clk_rate); - } - - case ADSP_IOCTL_REGISTER_PMEM: { - struct adsp_ion_info info; - if (copy_from_user(&info, (void *) arg, sizeof(info))) - return -EFAULT; - return adsp_ion_add(adev->module, &info); - } - - case ADSP_IOCTL_ABORT_EVENT_READ: - adev->abort = 1; - wake_up(&adev->event_wait); - break; - - case ADSP_IOCTL_UNREGISTER_PMEM: - return adsp_ion_del(adev->module); - - default: - break; - } - return -EINVAL; -} - -static int adsp_release(struct inode *inode, struct file *filp) -{ - struct adsp_device *adev = filp->private_data; - struct msm_adsp_module *module = adev->module; - int rc = 0; - - MM_INFO("release '%s'\n", adev->name); - - /* clear module before putting it to avoid race with open() */ - adev->module = NULL; - - rc = adsp_ion_del(module); - - msm_adsp_put(module); - return rc; -} - -static void adsp_event(void *driver_data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - struct adsp_device *adev = driver_data; - struct adsp_event *event; - unsigned long flags; - - if (len > ADSP_EVENT_MAX_SIZE) { - MM_ERR("event too large (%d bytes)\n", len); - return; - } - - event = kmalloc(sizeof(*event), GFP_ATOMIC); - if (!event) { - MM_ERR("cannot allocate buffer\n"); - return; - } - - if (id != EVENT_MSG_ID) { - event->type = 0; - event->is16 = 0; - event->msg_id = id; - event->size = len; - - getevent(event->data.msg16, len); - } else { - event->type = 1; - event->is16 = 1; - event->msg_id = id; - event->size = len; - getevent(event->data.msg32, len); - } - - spin_lock_irqsave(&adev->event_queue_lock, flags); - list_add_tail(&event->list, &adev->event_queue); - spin_unlock_irqrestore(&adev->event_queue_lock, flags); - wake_up(&adev->event_wait); -} - -static struct msm_adsp_ops adsp_ops = { - .event = adsp_event, -}; - -static int adsp_open(struct inode *inode, struct file *filp) -{ - struct adsp_device *adev; - int rc; - - rc = nonseekable_open(inode, filp); - if (rc < 0) - return rc; - - adev = inode_to_device(inode); - if (!adev) - return -ENODEV; - - MM_INFO("open '%s'\n", adev->name); - - rc = msm_adsp_get(adev->name, &adev->module, &adsp_ops, adev); - if (rc) - return rc; - - MM_INFO("opened module '%s' adev %p\n", adev->name, adev); - filp->private_data = adev; - adev->abort = 0; - INIT_HLIST_HEAD(&adev->module->ion_regions); - mutex_init(&adev->module->ion_regions_lock); - - return 0; -} - -static unsigned adsp_device_count; -static struct adsp_device *adsp_devices; - -static struct adsp_device *inode_to_device(struct inode *inode) -{ - unsigned n = MINOR(inode->i_rdev); - if (n < adsp_device_count) { - if (adsp_devices[n].device) - return adsp_devices + n; - } - return NULL; -} - -static dev_t adsp_devno; -static struct class *adsp_class; - -static struct file_operations adsp_fops = { - .owner = THIS_MODULE, - .open = adsp_open, - .unlocked_ioctl = adsp_ioctl, - .release = adsp_release, -}; - -static void adsp_create(struct adsp_device *adev, const char *name, - struct device *parent, dev_t devt) -{ - struct device *dev; - int rc; - - dev = device_create(adsp_class, parent, devt, "%s", name); - if (IS_ERR(dev)) - return; - - init_waitqueue_head(&adev->event_wait); - INIT_LIST_HEAD(&adev->event_queue); - spin_lock_init(&adev->event_queue_lock); - - cdev_init(&adev->cdev, &adsp_fops); - adev->cdev.owner = THIS_MODULE; - - rc = cdev_add(&adev->cdev, devt, 1); - if (rc < 0) { - device_destroy(adsp_class, devt); - } else { - adev->device = dev; - adev->name = name; - } -} - -void msm_adsp_publish_cdevs(struct msm_adsp_module *modules, unsigned n) -{ - int rc; - - adsp_devices = kzalloc(sizeof(struct adsp_device) * n, GFP_KERNEL); - if (!adsp_devices) - return; - - adsp_class = class_create(THIS_MODULE, "adsp"); - if (IS_ERR(adsp_class)) - goto fail_create_class; - - rc = alloc_chrdev_region(&adsp_devno, 0, n, "adsp"); - if (rc < 0) - goto fail_alloc_region; - - adsp_device_count = n; - for (n = 0; n < adsp_device_count; n++) { - adsp_create(adsp_devices + n, - modules[n].name, &modules[n].pdev.dev, - MKDEV(MAJOR(adsp_devno), n)); - } - - return; - -fail_alloc_region: - class_unregister(adsp_class); -fail_create_class: - kfree(adsp_devices); -} diff --git a/arch/arm/mach-msm/qdsp5/adsp_info.c b/arch/arm/mach-msm/qdsp5/adsp_info.c deleted file mode 100644 index 69a2d180860e4a324c683597801224f87a98e6c7..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/adsp_info.c +++ /dev/null @@ -1,144 +0,0 @@ -/* arch/arm/mach-msm/adsp_info.c - * - * Copyright (c) 2008-2009, 2011-2012 The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include "adsp.h" - -/* Firmware modules */ -#define QDSP_MODULE_KERNEL 0x0106dd4e -#define QDSP_MODULE_AFETASK 0x0106dd6f -#define QDSP_MODULE_AUDPLAY0TASK 0x0106dd70 -#define QDSP_MODULE_AUDPLAY1TASK 0x0106dd71 -#define QDSP_MODULE_AUDPPTASK 0x0106dd72 -#define QDSP_MODULE_VIDEOTASK 0x0106dd73 -#define QDSP_MODULE_VIDEO_AAC_VOC 0x0106dd74 -#define QDSP_MODULE_PCM_DEC 0x0106dd75 -#define QDSP_MODULE_AUDIO_DEC_MP3 0x0106dd76 -#define QDSP_MODULE_AUDIO_DEC_AAC 0x0106dd77 -#define QDSP_MODULE_AUDIO_DEC_WMA 0x0106dd78 -#define QDSP_MODULE_HOSTPCM 0x0106dd79 -#define QDSP_MODULE_DTMF 0x0106dd7a -#define QDSP_MODULE_AUDRECTASK 0x0106dd7b -#define QDSP_MODULE_AUDPREPROCTASK 0x0106dd7c -#define QDSP_MODULE_SBC_ENC 0x0106dd7d -#define QDSP_MODULE_VOC_UMTS 0x0106dd9a -#define QDSP_MODULE_VOC_CDMA 0x0106dd98 -#define QDSP_MODULE_VOC_PCM 0x0106dd7f -#define QDSP_MODULE_VOCENCTASK 0x0106dd80 -#define QDSP_MODULE_VOCDECTASK 0x0106dd81 -#define QDSP_MODULE_VOICEPROCTASK 0x0106dd82 -#define QDSP_MODULE_VIDEOENCTASK 0x0106dd83 -#define QDSP_MODULE_VFETASK 0x0106dd84 -#define QDSP_MODULE_WAV_ENC 0x0106dd85 -#define QDSP_MODULE_AACLC_ENC 0x0106dd86 -#define QDSP_MODULE_VIDEO_AMR 0x0106dd87 -#define QDSP_MODULE_VOC_AMR 0x0106dd88 -#define QDSP_MODULE_VOC_EVRC 0x0106dd89 -#define QDSP_MODULE_VOC_13K 0x0106dd8a -#define QDSP_MODULE_VOC_FGV 0x0106dd8b -#define QDSP_MODULE_DIAGTASK 0x0106dd8c -#define QDSP_MODULE_JPEGTASK 0x0106dd8d -#define QDSP_MODULE_LPMTASK 0x0106dd8e -#define QDSP_MODULE_QCAMTASK 0x0106dd8f -#define QDSP_MODULE_MODMATHTASK 0x0106dd90 -#define QDSP_MODULE_AUDPLAY2TASK 0x0106dd91 -#define QDSP_MODULE_AUDPLAY3TASK 0x0106dd92 -#define QDSP_MODULE_AUDPLAY4TASK 0x0106dd93 -#define QDSP_MODULE_GRAPHICSTASK 0x0106dd94 -#define QDSP_MODULE_MIDI 0x0106dd95 -#define QDSP_MODULE_GAUDIO 0x0106dd96 -#define QDSP_MODULE_VDEC_LP_MODE 0x0106dd97 -#define QDSP_MODULE_VIDEO_AAC_VOC_TURBO 0x01089f77 -#define QDSP_MODULE_VIDEO_AMR_TURBO 0x01089f78 -#define QDSP_MODULE_WM_TURBO_MODE 0x01089f79 -#define QDSP_MODULE_VDEC_LP_MODE_TURBO 0x01089f7a -#define QDSP_MODULE_AUDREC0TASK 0x0109696f -#define QDSP_MODULE_AUDREC1TASK 0x01096970 -#define QDSP_MODULE_RMTASK 0x01090f8e -#define QDSP_MODULE_MAX 0x7fffffff - - /* DO NOT USE: Force this enum to be a 32bit type to improve speed */ -#define QDSP_MODULE_32BIT_DUMMY 0x10000 - -static uint32_t *qdsp_task_to_module[IMG_MAX]; -static uint32_t *qdsp_queue_offset_table[IMG_MAX]; - -#define QDSP_MODULE(n, clkname, clkrate, verify_cmd_func, patch_event_func) \ - { .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n, \ - .clk_name = clkname, .clk_rate = clkrate, \ - .verify_cmd = verify_cmd_func, .patch_event = patch_event_func } - -static struct adsp_module_info module_info[] = { - QDSP_MODULE(AUDPLAY0TASK, NULL, 0, NULL, NULL), - QDSP_MODULE(AUDPLAY1TASK, NULL, 0, NULL, NULL), - QDSP_MODULE(AUDPLAY2TASK, NULL, 0, NULL, NULL), - QDSP_MODULE(AUDPLAY3TASK, NULL, 0, NULL, NULL), - QDSP_MODULE(AUDPPTASK, NULL, 0, NULL, NULL), - QDSP_MODULE(AUDPREPROCTASK, NULL, 0, NULL, NULL), - QDSP_MODULE(RMTASK, NULL, 0, NULL, NULL), -#if !defined(CONFIG_ARCH_MSM7X30) - QDSP_MODULE(AUDRECTASK, NULL, 0, NULL, NULL), - QDSP_MODULE(VFETASK, NULL, 0, adsp_vfe_verify_cmd, - adsp_vfe_patch_event), - QDSP_MODULE(QCAMTASK, NULL, 0, NULL, NULL), - QDSP_MODULE(LPMTASK, NULL, 0, adsp_lpm_verify_cmd, NULL), - QDSP_MODULE(JPEGTASK, "vdc_clk", 96000000, adsp_jpeg_verify_cmd, - adsp_jpeg_patch_event), - QDSP_MODULE(VIDEOTASK, "vdc_clk", 96000000, - adsp_video_verify_cmd, NULL), - QDSP_MODULE(VDEC_LP_MODE, NULL, 0, NULL, NULL), - QDSP_MODULE(VIDEOENCTASK, "vdc_clk", 96000000, - adsp_videoenc_verify_cmd, NULL), - QDSP_MODULE(VIDEO_AAC_VOC_TURBO, NULL, 0, NULL, NULL), - QDSP_MODULE(VIDEO_AMR_TURBO, NULL, 0, NULL, NULL), - QDSP_MODULE(WM_TURBO_MODE, NULL, 0, NULL, NULL), - QDSP_MODULE(VDEC_LP_MODE_TURBO, NULL, 0, NULL, NULL), -#if defined(CONFIG_MSM7X27A_AUDIO) - QDSP_MODULE(AUDREC1TASK, NULL, 0, NULL, NULL), -#endif -#else - QDSP_MODULE(AFETASK , NULL, 0, NULL, NULL), - QDSP_MODULE(AUDREC0TASK, NULL, 0, NULL, NULL), - QDSP_MODULE(AUDREC1TASK, NULL, 0, NULL, NULL), -#endif -}; - -int adsp_init_info(struct adsp_info *info) -{ - uint32_t img_num; - - info->send_irq = 0x00c00200; - info->read_ctrl = 0x00400038; - info->write_ctrl = 0x00400034; - - info->max_msg16_size = 193; - info->max_msg32_size = 8; - for (img_num = 0; img_num < IMG_MAX; img_num++) - qdsp_queue_offset_table[img_num] = - &info->init_info_ptr->queue_offsets[img_num][0]; - - for (img_num = 0; img_num < IMG_MAX; img_num++) - qdsp_task_to_module[img_num] = - &info->init_info_ptr->task_to_module_tbl[img_num][0]; - info->max_task_id = 30; - info->max_module_id = QDSP_MODULE_MAX - 1; - info->max_queue_id = QDSP_MAX_NUM_QUEUES; - info->max_image_id = 2; - info->queue_offset = qdsp_queue_offset_table; - info->task_to_module = qdsp_task_to_module; - - info->module_count = ARRAY_SIZE(module_info); - info->module = module_info; - return 0; -} diff --git a/arch/arm/mach-msm/qdsp5/adsp_jpeg_patch_event.c b/arch/arm/mach-msm/qdsp5/adsp_jpeg_patch_event.c deleted file mode 100644 index 768ac310d775036dabd17aa821731f0eda8f1a32..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/adsp_jpeg_patch_event.c +++ /dev/null @@ -1,39 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/adsp_jpeg_patch_event.c - * - * Verification code for aDSP JPEG events. - * - * Copyright (C) 2008 Google, Inc. - * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include "adsp.h" - -int adsp_jpeg_patch_event(struct msm_adsp_module *module, - struct adsp_event *event) -{ - if (event->msg_id == JPEG_MSG_ENC_OP_PRODUCED) { - jpeg_msg_enc_op_produced *op = (jpeg_msg_enc_op_produced *)event->data.msg16; - return adsp_pmem_paddr_fixup(module, (void **)&op->op_buf_addr); - } - if (event->msg_id == JPEG_MSG_DEC_OP_PRODUCED) { - jpeg_msg_dec_op_produced *op = (jpeg_msg_dec_op_produced *) - event->data.msg16; - return adsp_pmem_paddr_fixup(module, - (void **)&op->luma_op_buf_addr) || - adsp_pmem_paddr_fixup(module, - (void **)&op->chroma_op_buf_addr); - } - - return 0; -} diff --git a/arch/arm/mach-msm/qdsp5/adsp_jpeg_verify_cmd.c b/arch/arm/mach-msm/qdsp5/adsp_jpeg_verify_cmd.c deleted file mode 100644 index a5dd4ad3e5b4b5ed2de3e53314d50f059d519d9d..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/adsp_jpeg_verify_cmd.c +++ /dev/null @@ -1,201 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/adsp_jpeg_verify_cmd.c - * - * Verification code for aDSP JPEG packets from userspace. - * - * Copyright (C) 2008 Google, Inc. - * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include "adsp.h" -#include - -static uint32_t dec_fmt; - -static inline void get_sizes(jpeg_cmd_enc_cfg *cmd, uint32_t *luma_size, - uint32_t *chroma_size) -{ - uint32_t fmt, luma_width, luma_height; - - fmt = cmd->process_cfg & JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_M; - luma_width = (cmd->ip_size_cfg & JPEG_CMD_IP_SIZE_CFG_LUMA_WIDTH_M) - >> 16; - luma_height = cmd->frag_cfg & JPEG_CMD_FRAG_SIZE_LUMA_HEIGHT_M; - *luma_size = luma_width * luma_height; - if (fmt == JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V2) - *chroma_size = *luma_size/2; - else - *chroma_size = *luma_size; -} - -static inline int verify_jpeg_cmd_enc_cfg(struct msm_adsp_module *module, - void *cmd_data, size_t cmd_size) -{ - jpeg_cmd_enc_cfg *cmd = (jpeg_cmd_enc_cfg *)cmd_data; - uint32_t luma_size, chroma_size; - int i, num_frags; - - if (cmd_size != sizeof(jpeg_cmd_enc_cfg)) { - MM_ERR("module %s: JPEG ENC CFG invalid \ - cmd_size %d\n", module->name, cmd_size); - return -1; - } - - get_sizes(cmd, &luma_size, &chroma_size); - num_frags = (cmd->process_cfg >> 10) & 0xf; - num_frags = ((num_frags == 1) ? num_frags : num_frags * 2); - for (i = 0; i < num_frags; i += 2) { - if (adsp_pmem_fixup(module, (void **)(&cmd->frag_cfg_part[i]), luma_size) || - adsp_pmem_fixup(module, (void **)(&cmd->frag_cfg_part[i+1]), chroma_size)) - return -1; - } - - if (adsp_pmem_fixup(module, (void **)&cmd->op_buf_0_cfg_part1, - cmd->op_buf_0_cfg_part2) || - adsp_pmem_fixup(module, (void **)&cmd->op_buf_1_cfg_part1, - cmd->op_buf_1_cfg_part2)) - return -1; - return 0; -} - -static inline int verify_jpeg_cmd_dec_cfg(struct msm_adsp_module *module, - void *cmd_data, size_t cmd_size) -{ - jpeg_cmd_dec_cfg *cmd = (jpeg_cmd_dec_cfg *)cmd_data; - uint32_t div; - - if (cmd_size != sizeof(jpeg_cmd_dec_cfg)) { - MM_ERR("module %s: JPEG DEC CFG invalid \ - cmd_size %d\n", module->name, cmd_size); - return -1; - } - - if (adsp_pmem_fixup(module, (void **)&cmd->ip_stream_buf_cfg_part1, - cmd->ip_stream_buf_cfg_part2) || - adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_0_cfg_part1, - cmd->op_stream_buf_0_cfg_part2) || - adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_1_cfg_part1, - cmd->op_stream_buf_1_cfg_part2)) - return -1; - dec_fmt = cmd->op_data_format & - JPEG_CMD_DEC_OP_DATA_FORMAT_M; - div = (dec_fmt == JPEG_CMD_DEC_OP_DATA_FORMAT_H2V2) ? 2 : 1; - if (adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_0_cfg_part3, - cmd->op_stream_buf_0_cfg_part2 / div) || - adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_1_cfg_part3, - cmd->op_stream_buf_1_cfg_part2 / div)) - return -1; - return 0; -} - -static int verify_jpeg_cfg_cmd(struct msm_adsp_module *module, - void *cmd_data, size_t cmd_size) -{ - uint32_t cmd_id = ((uint32_t *)cmd_data)[0]; - switch(cmd_id) { - case JPEG_CMD_ENC_CFG: - return verify_jpeg_cmd_enc_cfg(module, cmd_data, cmd_size); - case JPEG_CMD_DEC_CFG: - return verify_jpeg_cmd_dec_cfg(module, cmd_data, cmd_size); - default: - if (cmd_id > 1) { - MM_ERR("module %s: invalid JPEG CFG cmd_id %d\n", - module->name, cmd_id); - return -1; - } - } - return 0; -} - -static int verify_jpeg_action_cmd(struct msm_adsp_module *module, - void *cmd_data, size_t cmd_size) -{ - uint32_t cmd_id = ((uint32_t *)cmd_data)[0]; - switch (cmd_id) { - case JPEG_CMD_ENC_OP_CONSUMED: - { - jpeg_cmd_enc_op_consumed *cmd = - (jpeg_cmd_enc_op_consumed *)cmd_data; - - if (cmd_size != sizeof(jpeg_cmd_enc_op_consumed)) { - MM_ERR("module %s: JPEG_CMD_ENC_OP_CONSUMED \ - invalid size %d\n", module->name, cmd_size); - return -1; - } - - if (adsp_pmem_fixup(module, (void **)&cmd->op_buf_addr, - cmd->op_buf_size)) - return -1; - } - break; - case JPEG_CMD_DEC_OP_CONSUMED: - { - uint32_t div; - jpeg_cmd_dec_op_consumed *cmd = - (jpeg_cmd_dec_op_consumed *)cmd_data; - - if (cmd_size != sizeof(jpeg_cmd_dec_op_consumed)) { - MM_ERR("module %s: JPEG_CMD_DEC_OP_CONSUMED \ - invalid size %d\n", module->name, cmd_size); - return -1; - } - - div = (dec_fmt == JPEG_CMD_DEC_OP_DATA_FORMAT_H2V2) ? 2 : 1; - if (adsp_pmem_fixup(module, (void **)&cmd->luma_op_buf_addr, - cmd->luma_op_buf_size) || - adsp_pmem_fixup(module, (void **)&cmd->chroma_op_buf_addr, - cmd->luma_op_buf_size / div)) - return -1; - } - break; - - case JPEG_CMD_DEC_IP: - { - jpeg_cmd_dec_ip *cmd = - (jpeg_cmd_dec_ip *)cmd_data; - - if (cmd_size != sizeof(jpeg_cmd_dec_ip)) { - MM_ERR("module %s: JPEG_CMD_DEC_IP invalid \ - size %d\n", module->name, cmd_size); - return -1; - } - if (adsp_pmem_fixup(module, (void **)&cmd->ip_buf_addr, - cmd->ip_buf_size)) - return -1; - } - break; - - default: - if (cmd_id > 7) { - MM_ERR("module %s: invalid cmd_id %d\n", - module->name, cmd_id); - return -1; - } - } - return 0; -} - -int adsp_jpeg_verify_cmd(struct msm_adsp_module *module, - unsigned int queue_id, void *cmd_data, - size_t cmd_size) -{ - switch(queue_id) { - case QDSP_uPJpegCfgCmdQueue: - return verify_jpeg_cfg_cmd(module, cmd_data, cmd_size); - case QDSP_uPJpegActionCmdQueue: - return verify_jpeg_action_cmd(module, cmd_data, cmd_size); - default: - return -1; - } -} - diff --git a/arch/arm/mach-msm/qdsp5/adsp_lpm_verify_cmd.c b/arch/arm/mach-msm/qdsp5/adsp_lpm_verify_cmd.c deleted file mode 100644 index 6424975b26929ad6e4a74c17e32814f00ea7b9ce..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/adsp_lpm_verify_cmd.c +++ /dev/null @@ -1,66 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/adsp_lpm_verify_cmd.c - * - * Verificion code for aDSP LPM packets from userspace. - * - * Copyright (C) 2008 Google, Inc. - * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include "adsp.h" -#include - -int adsp_lpm_verify_cmd(struct msm_adsp_module *module, - unsigned int queue_id, void *cmd_data, - size_t cmd_size) -{ - uint32_t cmd_id, col_height, input_row_incr, output_row_incr, - input_size, output_size; - uint32_t size_mask = 0x0fff; - lpm_cmd_start *cmd; - - if (queue_id != QDSP_lpmCommandQueue) { - MM_ERR("module %s: wrong queue id %d\n", - module->name, queue_id); - return -1; - } - - cmd = (lpm_cmd_start *)cmd_data; - cmd_id = cmd->cmd_id; - - if (cmd_id == LPM_CMD_START) { - if (cmd_size != sizeof(lpm_cmd_start)) { - MM_ERR("module %s: wrong size %d, \ - expect %d\n", module->name, - cmd_size, sizeof(lpm_cmd_start)); - return -1; - } - col_height = cmd->ip_data_cfg_part1 & size_mask; - input_row_incr = cmd->ip_data_cfg_part2 & size_mask; - output_row_incr = cmd->op_data_cfg_part1 & size_mask; - input_size = col_height * input_row_incr; - output_size = col_height * output_row_incr; - if ((cmd->ip_data_cfg_part4 && adsp_pmem_fixup(module, - (void **)(&cmd->ip_data_cfg_part4), - input_size)) || - (cmd->op_data_cfg_part3 && adsp_pmem_fixup(module, - (void **)(&cmd->op_data_cfg_part3), - output_size))) - return -1; - } else if (cmd_id > 1) { - MM_ERR("module %s: invalid cmd_id %d\n", module->name, cmd_id); - return -1; - } - return 0; -} - diff --git a/arch/arm/mach-msm/qdsp5/adsp_rm.c b/arch/arm/mach-msm/qdsp5/adsp_rm.c deleted file mode 100644 index 95489f846c552660a4f3fc798ddf3c6658204300..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/adsp_rm.c +++ /dev/null @@ -1,194 +0,0 @@ -/* Copyright (c) 2010, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "adsp.h" - -#define MAX_CLIENTS 5 -#define MAX_AUDIO_CLIENTS 5 -#define MAX_RM_CLIENTS MAX_AUDIO_CLIENTS - -static char *rm_errs[] = { - "", - "PCM Blocks not Sufficient", - "TASK is already occupied", - "Concurrency not supported", - "MIPS not sufficient", - "DDP invalid/no licence" - }; -static struct client { - wait_queue_head_t wait; - unsigned int wait_state; - struct aud_codec_config_ack cfg_msg; -} rmclient[MAX_RM_CLIENTS]; - -static struct rm { - struct msm_adsp_module *mod; - int cnt; - int state; - - struct aud_codec_config_ack cfg_msg; - struct mutex lock; -} rmtask; - -static void rm_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)); -static struct msm_adsp_ops rm_ops = { - .event = rm_dsp_event, -}; - -int32_t get_adsp_resource(unsigned short client_id, - void *cmd_buf, size_t cmd_size) -{ - int rc = 0; - int client_idx; - - client_idx = ((client_id >> 8) * MAX_CLIENTS) + (client_id & 0xFF); - if (client_idx >= MAX_RM_CLIENTS) - return -EINVAL; - - mutex_lock(&rmtask.lock); - if (rmtask.state != ADSP_STATE_ENABLED) { - rc = msm_adsp_get("RMTASK", &rmtask.mod, &rm_ops, NULL); - if (rc) { - MM_ERR("Failed to get module RMTASK\n"); - mutex_unlock(&rmtask.lock); - return rc; - } - rc = msm_adsp_enable(rmtask.mod); - if (rc) { - MM_ERR("RMTASK enable Failed\n"); - msm_adsp_put(rmtask.mod); - mutex_unlock(&rmtask.lock); - return rc; - } - rmtask.state = ADSP_STATE_ENABLED; - } - rmclient[client_idx].wait_state = -1; - mutex_unlock(&rmtask.lock); - msm_adsp_write(rmtask.mod, QDSP_apuRmtQueue, cmd_buf, cmd_size); - rc = wait_event_interruptible_timeout(rmclient[client_idx].wait, - rmclient[client_idx].wait_state != -1, 5 * HZ); - mutex_lock(&rmtask.lock); - if (unlikely(rc < 0)) { - if (rc == -ERESTARTSYS) - MM_ERR("wait_event_interruptible " - "returned -ERESTARTSYS\n"); - else - MM_ERR("wait_event_interruptible " - "returned error\n"); - if (!rmtask.cnt) - goto disable_rm; - goto unlock; - } else if (rc == 0) { - MM_ERR("RMTASK Msg not received\n"); - rc = -ETIMEDOUT; - if (!rmtask.cnt) - goto disable_rm; - goto unlock; - } - if (!(rmclient[client_idx].cfg_msg.enable)) { - MM_ERR("Reason for failure: %s\n", - rm_errs[rmclient[client_idx].cfg_msg.reason]); - rc = -EBUSY; - if (!rmtask.cnt) - goto disable_rm; - goto unlock; - } - rmtask.cnt++; - mutex_unlock(&rmtask.lock); - return 0; - -disable_rm: - msm_adsp_disable(rmtask.mod); - msm_adsp_put(rmtask.mod); - rmtask.state = ADSP_STATE_DISABLED; -unlock: - mutex_unlock(&rmtask.lock); - return rc; -} -EXPORT_SYMBOL(get_adsp_resource); - -int32_t put_adsp_resource(unsigned short client_id, void *cmd_buf, - size_t cmd_size) -{ - mutex_lock(&rmtask.lock); - if (rmtask.state != ADSP_STATE_ENABLED) { - mutex_unlock(&rmtask.lock); - return 0; - } - - msm_adsp_write(rmtask.mod, QDSP_apuRmtQueue, cmd_buf, cmd_size); - rmtask.cnt--; - if (!rmtask.cnt) { - msm_adsp_disable(rmtask.mod); - msm_adsp_put(rmtask.mod); - rmtask.state = ADSP_STATE_DISABLED; - } - mutex_unlock(&rmtask.lock); - return 0; -} -EXPORT_SYMBOL(put_adsp_resource); - -static void rm_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - unsigned short client_id; - int client_idx; - - MM_DBG("Msg ID = %d\n", id); - - switch (id) { - case RMT_CODEC_CONFIG_ACK: { - getevent(&rmtask.cfg_msg, sizeof(rmtask.cfg_msg)); - client_id = ((rmtask.cfg_msg.client_id << 8) | - rmtask.cfg_msg.task_id); - client_idx = ((client_id >> 8) * MAX_CLIENTS) + - (client_id & 0xFF); - memcpy(&rmclient[client_idx].cfg_msg, &rmtask.cfg_msg, - sizeof(rmtask.cfg_msg)); - rmclient[client_idx].wait_state = 1; - wake_up(&rmclient[client_idx].wait); - break; - } - case RMT_DSP_OUT_OF_MIPS: { - struct rmt_dsp_out_of_mips msg; - getevent(&msg, sizeof(msg)); - MM_ERR("RMT_DSP_OUT_OF_MIPS: Not enough resorces in ADSP \ - to handle all sessions :%hx\n", msg.dec_info); - break; - } - default: - MM_DBG("Unknown Msg Id\n"); - break; - } -} - -void rmtask_init(void) -{ - int i; - - for (i = 0; i < MAX_RM_CLIENTS; i++) - init_waitqueue_head(&rmclient[i].wait); - mutex_init(&rmtask.lock); -} diff --git a/arch/arm/mach-msm/qdsp5/adsp_vfe_patch_event.c b/arch/arm/mach-msm/qdsp5/adsp_vfe_patch_event.c deleted file mode 100644 index c89a37dafa7ec2f49eaba1d159ec15353e0e2747..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/adsp_vfe_patch_event.c +++ /dev/null @@ -1,54 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/adsp_vfe_patch_event.c - * - * Verification code for aDSP VFE packets from userspace. - * - * Copyright (C) 2008 Google, Inc. - * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include "adsp.h" - -static int patch_op_event(struct msm_adsp_module *module, - struct adsp_event *event) -{ - vfe_msg_op1 *op = (vfe_msg_op1 *)event->data.msg16; - if (adsp_pmem_paddr_fixup(module, (void **)&op->op1_buf_y_addr) || - adsp_pmem_paddr_fixup(module, (void **)&op->op1_buf_cbcr_addr)) - return -1; - return 0; -} - -static int patch_af_wb_event(struct msm_adsp_module *module, - struct adsp_event *event) -{ - vfe_msg_stats_wb_exp *af = (vfe_msg_stats_wb_exp *)event->data.msg16; - return adsp_pmem_paddr_fixup(module, (void **)&af->wb_exp_stats_op_buf); -} - -int adsp_vfe_patch_event(struct msm_adsp_module *module, - struct adsp_event *event) -{ - switch(event->msg_id) { - case VFE_MSG_OP1: - case VFE_MSG_OP2: - return patch_op_event(module, event); - case VFE_MSG_STATS_AF: - case VFE_MSG_STATS_WB_EXP: - return patch_af_wb_event(module, event); - default: - break; - } - - return 0; -} diff --git a/arch/arm/mach-msm/qdsp5/adsp_vfe_verify_cmd.c b/arch/arm/mach-msm/qdsp5/adsp_vfe_verify_cmd.c deleted file mode 100644 index dba012e25258b8e1f23f06bd6319377de7aece28..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/adsp_vfe_verify_cmd.c +++ /dev/null @@ -1,244 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/adsp_vfe_verify_cmd.c - * - * Verification code for aDSP VFE packets from userspace. - * - * Copyright (C) 2008 Google, Inc. - * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include "adsp.h" -#include - -static uint32_t size1_y, size2_y, size1_cbcr, size2_cbcr; -static uint32_t af_size = 4228; -static uint32_t awb_size = 8196; - -static inline int verify_cmd_op_ack(struct msm_adsp_module *module, - void *cmd_data, size_t cmd_size) -{ - vfe_cmd_op1_ack *cmd = (vfe_cmd_op1_ack *)cmd_data; - void **addr_y = (void **)&cmd->op1_buf_y_addr; - void **addr_cbcr = (void **)(&cmd->op1_buf_cbcr_addr); - - if (cmd_size != sizeof(vfe_cmd_op1_ack)) - return -1; - if ((*addr_y && adsp_pmem_fixup(module, addr_y, size1_y)) || - (*addr_cbcr && adsp_pmem_fixup(module, addr_cbcr, size1_cbcr))) - return -1; - return 0; -} - -static inline int verify_cmd_stats_autofocus_cfg(struct msm_adsp_module *module, - void *cmd_data, size_t cmd_size) -{ - int i; - vfe_cmd_stats_autofocus_cfg *cmd = - (vfe_cmd_stats_autofocus_cfg *)cmd_data; - - if (cmd_size != sizeof(vfe_cmd_stats_autofocus_cfg)) - return -1; - - for (i = 0; i < 3; i++) { - void **addr = (void **)(&cmd->af_stats_op_buf[i]); - if (*addr && adsp_pmem_fixup(module, addr, af_size)) - return -1; - } - return 0; -} - -static inline int verify_cmd_stats_wb_exp_cfg(struct msm_adsp_module *module, - void *cmd_data, size_t cmd_size) -{ - vfe_cmd_stats_wb_exp_cfg *cmd = - (vfe_cmd_stats_wb_exp_cfg *)cmd_data; - int i; - - if (cmd_size != sizeof(vfe_cmd_stats_wb_exp_cfg)) - return -1; - - for (i = 0; i < 3; i++) { - void **addr = (void **)(&cmd->wb_exp_stats_op_buf[i]); - if (*addr && adsp_pmem_fixup(module, addr, awb_size)) - return -1; - } - return 0; -} - -static inline int verify_cmd_stats_af_ack(struct msm_adsp_module *module, - void *cmd_data, size_t cmd_size) -{ - vfe_cmd_stats_af_ack *cmd = (vfe_cmd_stats_af_ack *)cmd_data; - void **addr = (void **)&cmd->af_stats_op_buf; - - if (cmd_size != sizeof(vfe_cmd_stats_af_ack)) - return -1; - - if (*addr && adsp_pmem_fixup(module, addr, af_size)) - return -1; - return 0; -} - -static inline int verify_cmd_stats_wb_exp_ack(struct msm_adsp_module *module, - void *cmd_data, size_t cmd_size) -{ - vfe_cmd_stats_wb_exp_ack *cmd = - (vfe_cmd_stats_wb_exp_ack *)cmd_data; - void **addr = (void **)&cmd->wb_exp_stats_op_buf; - - if (cmd_size != sizeof(vfe_cmd_stats_wb_exp_ack)) - return -1; - - if (*addr && adsp_pmem_fixup(module, addr, awb_size)) - return -1; - return 0; -} - -static int verify_vfe_command(struct msm_adsp_module *module, - void *cmd_data, size_t cmd_size) -{ - uint32_t cmd_id = ((uint32_t *)cmd_data)[0]; - switch (cmd_id) { - case VFE_CMD_OP1_ACK: - return verify_cmd_op_ack(module, cmd_data, cmd_size); - case VFE_CMD_OP2_ACK: - return verify_cmd_op_ack(module, cmd_data, cmd_size); - case VFE_CMD_STATS_AUTOFOCUS_CFG: - return verify_cmd_stats_autofocus_cfg(module, cmd_data, - cmd_size); - case VFE_CMD_STATS_WB_EXP_CFG: - return verify_cmd_stats_wb_exp_cfg(module, cmd_data, cmd_size); - case VFE_CMD_STATS_AF_ACK: - return verify_cmd_stats_af_ack(module, cmd_data, cmd_size); - case VFE_CMD_STATS_WB_EXP_ACK: - return verify_cmd_stats_wb_exp_ack(module, cmd_data, cmd_size); - default: - if (cmd_id > 29) { - MM_ERR("module %s: invalid VFE command id %d\n", - module->name, cmd_id); - return -1; - } - } - return 0; -} - -static int verify_vfe_command_scale(struct msm_adsp_module *module, - void *cmd_data, size_t cmd_size) -{ - uint32_t cmd_id = ((uint32_t *)cmd_data)[0]; - // FIXME: check the size - if (cmd_id > 1) { - MM_ERR("module %s: invalid VFE SCALE command id %d\n", - module->name, cmd_id); - return -1; - } - return 0; -} - - -static uint32_t get_size(uint32_t hw) -{ - uint32_t height, width; - uint32_t height_mask = 0x3ffc; - uint32_t width_mask = 0x3ffc000; - - height = (hw & height_mask) >> 2; - width = (hw & width_mask) >> 14 ; - return height * width; -} - -static int verify_vfe_command_table(struct msm_adsp_module *module, - void *cmd_data, size_t cmd_size) -{ - uint32_t cmd_id = ((uint32_t *)cmd_data)[0]; - int i; - - switch (cmd_id) { - case VFE_CMD_AXI_IP_CFG: - { - vfe_cmd_axi_ip_cfg *cmd = (vfe_cmd_axi_ip_cfg *)cmd_data; - uint32_t size; - if (cmd_size != sizeof(vfe_cmd_axi_ip_cfg)) { - MM_ERR("module %s: invalid VFE TABLE \ - (VFE_CMD_AXI_IP_CFG) command size %d\n", - module->name, cmd_size); - return -1; - } - size = get_size(cmd->ip_cfg_part2); - - for (i = 0; i < 8; i++) { - void **addr = (void **) - &cmd->ip_buf_addr[i]; - if (*addr && adsp_pmem_fixup(module, addr, size)) - return -1; - } - } - case VFE_CMD_AXI_OP_CFG: - { - vfe_cmd_axi_op_cfg *cmd = (vfe_cmd_axi_op_cfg *)cmd_data; - void **addr1_y, **addr2_y, **addr1_cbcr, **addr2_cbcr; - - if (cmd_size != sizeof(vfe_cmd_axi_op_cfg)) { - MM_ERR("module %s: invalid VFE TABLE \ - (VFE_CMD_AXI_OP_CFG) command size %d\n", - module->name, cmd_size); - return -1; - } - size1_y = get_size(cmd->op1_y_cfg_part2); - size1_cbcr = get_size(cmd->op1_cbcr_cfg_part2); - size2_y = get_size(cmd->op2_y_cfg_part2); - size2_cbcr = get_size(cmd->op2_cbcr_cfg_part2); - for (i = 0; i < 8; i++) { - addr1_y = (void **)(&cmd->op1_buf1_addr[2*i]); - addr1_cbcr = (void **)(&cmd->op1_buf1_addr[2*i+1]); - addr2_y = (void **)(&cmd->op2_buf1_addr[2*i]); - addr2_cbcr = (void **)(&cmd->op2_buf1_addr[2*i+1]); -/* - printk("module %s: [%d] %p %p %p %p\n", - module->name, i, - *addr1_y, *addr1_cbcr, *addr2_y, *addr2_cbcr); -*/ - if ((*addr1_y && adsp_pmem_fixup(module, addr1_y, size1_y)) || - (*addr1_cbcr && adsp_pmem_fixup(module, addr1_cbcr, size1_cbcr)) || - (*addr2_y && adsp_pmem_fixup(module, addr2_y, size2_y)) || - (*addr2_cbcr && adsp_pmem_fixup(module, addr2_cbcr, size2_cbcr))) - return -1; - } - } - default: - if (cmd_id > 4) { - MM_ERR("module %s: invalid VFE TABLE command \ - id %d\n", module->name, cmd_id); - return -1; - } - } - return 0; -} - -int adsp_vfe_verify_cmd(struct msm_adsp_module *module, - unsigned int queue_id, void *cmd_data, - size_t cmd_size) -{ - switch (queue_id) { - case QDSP_vfeCommandQueue: - return verify_vfe_command(module, cmd_data, cmd_size); - case QDSP_vfeCommandScaleQueue: - return verify_vfe_command_scale(module, cmd_data, cmd_size); - case QDSP_vfeCommandTableQueue: - return verify_vfe_command_table(module, cmd_data, cmd_size); - default: - MM_ERR("module %s: unknown queue id %d\n", - module->name, queue_id); - return -1; - } -} diff --git a/arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c b/arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c deleted file mode 100644 index 4d03dca2e57a4806f91f5e028e9ba7588eb234e8..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c +++ /dev/null @@ -1,265 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c - * - * Verificion code for aDSP VDEC packets from userspace. - * - * Copyright (C) 2008 Google, Inc. - * Copyright (c) 2008-2010, 2012 The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include - -#include -#include "adsp.h" -#include - -#define MAX_FLUSH_SIZE 160 - -static inline void *high_low_short_to_ptr(unsigned short high, - unsigned short low) -{ - return (void *)((((unsigned long)high) << 16) | ((unsigned long)low)); -} - -static inline void ptr_to_high_low_short(void *ptr, unsigned short *high, - unsigned short *low) -{ - *high = (unsigned short)((((unsigned long)ptr) >> 16) & 0xffff); - *low = (unsigned short)((unsigned long)ptr & 0xffff); -} - -static int pmem_fixup_high_low(unsigned short *high, - unsigned short *low, - unsigned short size_high, - unsigned short size_low, - struct msm_adsp_module *module, - unsigned long *addr, unsigned long *size, - struct file **filp, unsigned long *offset) -{ - void *phys_addr; - unsigned long phys_size; - unsigned long kvaddr; - - phys_addr = high_low_short_to_ptr(*high, *low); - phys_size = (unsigned long)high_low_short_to_ptr(size_high, size_low); - MM_DBG("virt %x %x\n", (unsigned int)phys_addr, - (unsigned int)phys_size); - if (phys_addr) { - if (adsp_ion_fixup_kvaddr(module, &phys_addr, - &kvaddr, phys_size, filp, offset)) { - MM_ERR("ah%x al%x sh%x sl%x addr %x size %x\n", - *high, *low, size_high, - size_low, (unsigned int)phys_addr, - (unsigned int)phys_size); - return -EINVAL; - } - } - ptr_to_high_low_short(phys_addr, high, low); - MM_DBG("phys %x %x\n", (unsigned int)phys_addr, - (unsigned int)phys_size); - if (addr) - *addr = kvaddr; - if (size) - *size = phys_size; - return 0; -} - -static int verify_vdec_pkt_cmd(struct msm_adsp_module *module, - void *cmd_data, size_t cmd_size) -{ - void *phys_addr; - unsigned short cmd_id = ((unsigned short *)cmd_data)[0]; - viddec_cmd_subframe_pkt *pkt; - unsigned long subframe_pkt_addr; - unsigned long subframe_pkt_size; - unsigned short *frame_header_pkt; - int i, num_addr, col_addr = 0, skip; - int start_pos = 0, xdim_pos = 1, ydim_pos = 2; - unsigned short *frame_buffer_high, *frame_buffer_low; - unsigned long frame_buffer_size; - unsigned short frame_buffer_size_high, frame_buffer_size_low; - struct file *filp = NULL; - unsigned long offset = 0; - unsigned long Codec_Id = 0; - - MM_DBG("cmd_size %d cmd_id %d cmd_data %x\n", cmd_size, cmd_id, - (unsigned int)cmd_data); - if (cmd_id != VIDDEC_CMD_SUBFRAME_PKT) { - MM_INFO("adsp_video: unknown video packet %u\n", cmd_id); - return 0; - } - if (cmd_size < sizeof(viddec_cmd_subframe_pkt)) - return -1; - - pkt = (viddec_cmd_subframe_pkt *)cmd_data; - phys_addr = high_low_short_to_ptr(pkt->subframe_packet_high, - pkt->subframe_packet_low); - - if (pmem_fixup_high_low(&(pkt->subframe_packet_high), - &(pkt->subframe_packet_low), - pkt->subframe_packet_size_high, - pkt->subframe_packet_size_low, - module, - &subframe_pkt_addr, - &subframe_pkt_size, - &filp, &offset)) - return -1; - Codec_Id = pkt->codec_selection_word; - /*Invalidate cache before accessing the cached pmem buffer*/ - if (adsp_ion_do_cache_op(module, phys_addr, (void *)subframe_pkt_addr, - subframe_pkt_size*2, offset, ION_IOC_INV_CACHES)){ - MM_ERR("Cache operation failed for" \ - " phys addr high %x addr low %x\n", - pkt->subframe_packet_high, pkt->subframe_packet_low); - return -EINVAL; - } - /* deref those ptrs and check if they are a frame header packet */ - frame_header_pkt = (unsigned short *)subframe_pkt_addr; - switch (frame_header_pkt[0]) { - case 0xB201: /* h.264 vld in dsp */ - if (Codec_Id == 0x8) { - num_addr = 16; - skip = 0; - start_pos = 5; - } else { - num_addr = 16; - skip = 0; - start_pos = 6; - col_addr = 17; - } - break; - case 0x8201: /* h.264 vld in arm */ - num_addr = 16; - skip = 0; - start_pos = 6; - break; - case 0x4D01: /* mpeg-4 and h.263 vld in arm */ - num_addr = 3; - skip = 0; - start_pos = 5; - break; - case 0x9201: /*For Real Decoder*/ - num_addr = 2; - skip = 0; - start_pos = 5; - break; - case 0xBD01: /* mpeg-4 and h.263 vld in dsp */ - num_addr = 3; - skip = 0; - start_pos = 6; - if (((frame_header_pkt[5] & 0x000c) >> 2) == 0x2) /* B-frame */ - start_pos = 8; - break; - case 0x0001: /* wmv */ - num_addr = 2; - skip = 0; - start_pos = 5; - break; - case 0xC201: /*WMV main profile*/ - num_addr = 3; - skip = 0; - start_pos = 6; - break; - case 0xDD01: /* VP6 */ - num_addr = 3; - skip = 0; - start_pos = 10; - break; - case 0xFD01: /* VP8 */ - num_addr = 3; - skip = 0; - start_pos = 24; - break; - default: - return 0; - } - - frame_buffer_high = &frame_header_pkt[start_pos]; - frame_buffer_low = &frame_header_pkt[start_pos + 1]; - frame_buffer_size = (frame_header_pkt[xdim_pos] * - frame_header_pkt[ydim_pos] * 3) / 2; - ptr_to_high_low_short((void *)frame_buffer_size, - &frame_buffer_size_high, - &frame_buffer_size_low); - for (i = 0; i < num_addr; i++) { - if (frame_buffer_high && frame_buffer_low) { - if (pmem_fixup_high_low(frame_buffer_high, - frame_buffer_low, - frame_buffer_size_high, - frame_buffer_size_low, - module, - NULL, NULL, NULL, NULL)) - return -EINVAL; - } - frame_buffer_high += 2; - frame_buffer_low += 2; - } - /* Patch the output buffer. */ - frame_buffer_high += 2*skip; - frame_buffer_low += 2*skip; - if (frame_buffer_high && frame_buffer_low) { - if (pmem_fixup_high_low(frame_buffer_high, - frame_buffer_low, - frame_buffer_size_high, - frame_buffer_size_low, - module, - NULL, NULL, NULL, NULL)) - return -EINVAL; - } - if (col_addr) { - frame_buffer_high += 2; - frame_buffer_low += 2; - /* Patch the Co-located buffers.*/ - frame_buffer_size = (72 * frame_header_pkt[xdim_pos] * - frame_header_pkt[ydim_pos]) >> 16; - ptr_to_high_low_short((void *)frame_buffer_size, - &frame_buffer_size_high, - &frame_buffer_size_low); - for (i = 0; i < col_addr; i++) { - if (frame_buffer_high && frame_buffer_low) { - if (pmem_fixup_high_low(frame_buffer_high, - frame_buffer_low, - frame_buffer_size_high, - frame_buffer_size_low, - module, - NULL, NULL, NULL, NULL)) - return -EINVAL; - } - frame_buffer_high += 2; - frame_buffer_low += 2; - } - } - /*Flush the cached mem subframe packet before sending to DSP*/ - if (adsp_ion_do_cache_op(module, phys_addr, (void *)subframe_pkt_addr, - MAX_FLUSH_SIZE, offset, ION_IOC_CLEAN_CACHES)){ - MM_ERR("Cache operation failed for" \ - " phys addr high %x addr low %x\n", - pkt->subframe_packet_high, pkt->subframe_packet_low); - return -EINVAL; - } - return 0; -} - -int adsp_video_verify_cmd(struct msm_adsp_module *module, - unsigned int queue_id, void *cmd_data, - size_t cmd_size) -{ - switch (queue_id) { - case QDSP_mpuVDecPktQueue: - return verify_vdec_pkt_cmd(module, cmd_data, cmd_size); - default: - MM_INFO("unknown video queue %u\n", queue_id); - return 0; - } -} - diff --git a/arch/arm/mach-msm/qdsp5/adsp_videoenc_verify_cmd.c b/arch/arm/mach-msm/qdsp5/adsp_videoenc_verify_cmd.c deleted file mode 100644 index 1b16628b27d83e31a183bcda78abb801a1528b93..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/adsp_videoenc_verify_cmd.c +++ /dev/null @@ -1,235 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c - * - * Verificion code for aDSP VENC packets from userspace. - * - * Copyright (C) 2008 Google, Inc. - * Copyright (c) 2008-2009, 2012 The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include - -#include -#include "adsp.h" -#include - - -static unsigned short x_dimension, y_dimension; - -static inline void *high_low_short_to_ptr(unsigned short high, - unsigned short low) -{ - return (void *)((((unsigned long)high) << 16) | ((unsigned long)low)); -} - -static inline void ptr_to_high_low_short(void *ptr, unsigned short *high, - unsigned short *low) -{ - *high = (unsigned short)((((unsigned long)ptr) >> 16) & 0xffff); - *low = (unsigned short)((unsigned long)ptr & 0xffff); -} - -static int pmem_fixup_high_low(unsigned short *high, - unsigned short *low, - unsigned short size_high, - unsigned short size_low, - struct msm_adsp_module *module, - unsigned long *addr, unsigned long *size) -{ - void *phys_addr; - unsigned long phys_size; - unsigned long kvaddr; - - phys_addr = high_low_short_to_ptr(*high, *low); - phys_size = (unsigned long)high_low_short_to_ptr(size_high, size_low); - MM_DBG("virt %x %x\n", (unsigned int)phys_addr, - (unsigned int)phys_size); - if (adsp_ion_fixup_kvaddr(module, &phys_addr, &kvaddr, phys_size, - NULL, NULL)) { - MM_ERR("ah%x al%x sh%x sl%x addr %x size %x\n", - *high, *low, size_high, - size_low, (unsigned int)phys_addr, - (unsigned int) phys_size); - return -1; - } - ptr_to_high_low_short(phys_addr, high, low); - MM_DBG("phys %x %x\n", (unsigned int)phys_addr, - (unsigned int)phys_size); - if (addr) - *addr = kvaddr; - if (size) - *size = phys_size; - return 0; -} - -static int verify_venc_cmd(struct msm_adsp_module *module, - void *cmd_data, size_t cmd_size) -{ - unsigned short cmd_id = ((unsigned short *)cmd_data)[0]; - unsigned long frame_buf_size, luma_buf_size, chroma_buf_size; - unsigned short frame_buf_size_high, frame_buf_size_low; - unsigned short luma_buf_size_high, luma_buf_size_low; - unsigned short chroma_buf_size_high, chroma_buf_size_low; - videnc_cmd_cfg *config_cmd; - videnc_cmd_frame_start *frame_cmd; - videnc_cmd_dis *dis_cmd; - - MM_DBG("cmd_size %d cmd_id %d cmd_data %x\n", - cmd_size, cmd_id, (unsigned int)cmd_data); - switch (cmd_id) { - case VIDENC_CMD_ACTIVE: - if (cmd_size < sizeof(videnc_cmd_active)) - return -1; - break; - case VIDENC_CMD_IDLE: - if (cmd_size < sizeof(videnc_cmd_idle)) - return -1; - x_dimension = y_dimension = 0; - break; - case VIDENC_CMD_STATUS_QUERY: - if (cmd_size < sizeof(videnc_cmd_status_query)) - return -1; - break; - case VIDENC_CMD_RC_CFG: - if (cmd_size < sizeof(videnc_cmd_rc_cfg)) - return -1; - break; - case VIDENC_CMD_INTRA_REFRESH: - if (cmd_size < sizeof(videnc_cmd_intra_refresh)) - return -1; - break; - case VIDENC_CMD_DIGITAL_ZOOM: - if (cmd_size < sizeof(videnc_cmd_digital_zoom)) - return -1; - break; - case VIDENC_CMD_DIS_CFG: - if (cmd_size < sizeof(videnc_cmd_dis_cfg)) - return -1; - break; - case VIDENC_CMD_VENC_CLOCK: - if (cmd_size < sizeof(struct videnc_cmd_venc_clock)) - return -1; - break; - case VIDENC_CMD_CFG: - if (cmd_size < sizeof(videnc_cmd_cfg)) - return -1; - config_cmd = (videnc_cmd_cfg *)cmd_data; - x_dimension = ((config_cmd->venc_frame_dim) & 0xFF00)>>8; - x_dimension = x_dimension*16; - y_dimension = (config_cmd->venc_frame_dim) & 0xFF; - y_dimension = y_dimension * 16; - break; - case VIDENC_CMD_FRAME_START: - if (cmd_size < sizeof(videnc_cmd_frame_start)) - return -1; - frame_cmd = (videnc_cmd_frame_start *)cmd_data; - luma_buf_size = x_dimension * y_dimension; - chroma_buf_size = luma_buf_size>>1; - frame_buf_size = luma_buf_size + chroma_buf_size; - ptr_to_high_low_short((void *)luma_buf_size, - &luma_buf_size_high, - &luma_buf_size_low); - ptr_to_high_low_short((void *)chroma_buf_size, - &chroma_buf_size_high, - &chroma_buf_size_low); - ptr_to_high_low_short((void *)frame_buf_size, - &frame_buf_size_high, - &frame_buf_size_low); - /* Address of raw Y data. */ - if (pmem_fixup_high_low(&frame_cmd->input_luma_addr_high, - &frame_cmd->input_luma_addr_low, - luma_buf_size_high, - luma_buf_size_low, - module, - NULL, NULL)) - return -1; - /* Address of raw CbCr data */ - if (pmem_fixup_high_low(&frame_cmd->input_chroma_addr_high, - &frame_cmd->input_chroma_addr_low, - chroma_buf_size_high, - chroma_buf_size_low, - module, - NULL, NULL)) - return -1; - /* Reference VOP */ - if (pmem_fixup_high_low(&frame_cmd->ref_vop_buf_ptr_high, - &frame_cmd->ref_vop_buf_ptr_low, - frame_buf_size_high, - frame_buf_size_low, - module, - NULL, NULL)) - return -1; - /* Encoded Packet Address */ - if (pmem_fixup_high_low(&frame_cmd->enc_pkt_buf_ptr_high, - &frame_cmd->enc_pkt_buf_ptr_low, - frame_cmd->enc_pkt_buf_size_high, - frame_cmd->enc_pkt_buf_size_low, - module, - NULL, NULL)) - return -1; - /* Unfiltered VOP Buffer Address */ - if (pmem_fixup_high_low( - &frame_cmd->unfilt_recon_vop_buf_ptr_high, - &frame_cmd->unfilt_recon_vop_buf_ptr_low, - frame_buf_size_high, - frame_buf_size_low, - module, - NULL, NULL)) - return -1; - /* Filtered VOP Buffer Address */ - if (pmem_fixup_high_low(&frame_cmd->filt_recon_vop_buf_ptr_high, - &frame_cmd->filt_recon_vop_buf_ptr_low, - frame_buf_size_high, - frame_buf_size_low, - module, - NULL, NULL)) - return -1; - break; - case VIDENC_CMD_DIS: - if (cmd_size < sizeof(videnc_cmd_dis)) - return -1; - dis_cmd = (videnc_cmd_dis *)cmd_data; - luma_buf_size = x_dimension * y_dimension; - ptr_to_high_low_short((void *)luma_buf_size, - &luma_buf_size_high, - &luma_buf_size_low); - /* Prev VFE Luma Output Address */ - if (pmem_fixup_high_low(&dis_cmd->vfe_out_prev_luma_addr_high, - &dis_cmd->vfe_out_prev_luma_addr_low, - luma_buf_size_high, - luma_buf_size_low, - module, - NULL, NULL)) - return -1; - break; - default: - MM_INFO("adsp_video:unknown encoder video cmd %u\n", cmd_id); - return 0; - } - - return 0; -} - - -int adsp_videoenc_verify_cmd(struct msm_adsp_module *module, - unsigned int queue_id, void *cmd_data, - size_t cmd_size) -{ - switch (queue_id) { - case QDSP_mpuVEncCmdQueue: - return verify_venc_cmd(module, cmd_data, cmd_size); - default: - MM_INFO("unknown video queue %u\n", queue_id); - return 0; - } -} - diff --git a/arch/arm/mach-msm/qdsp5/audio_aac.c b/arch/arm/mach-msm/qdsp5/audio_aac.c deleted file mode 100644 index c89d88bfd0778c6fcc5ad97faba4e18e095fae39..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_aac.c +++ /dev/null @@ -1,1964 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/audio_aac.c - * - * aac audio decoder device - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2008-2009, 2011-2012 The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "audmgr.h" - -#define BUFSZ 32768 -#define DMASZ (BUFSZ * 2) -#define BUFSZ_MIN 4096 -#define DMASZ_MIN (BUFSZ_MIN * 2) - -#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF -#define AUDDEC_DEC_AAC 5 - -#define PCM_BUFSZ_MIN 9600 /* Hold one stereo AAC frame */ -#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most - but support 2 buffers currently */ -#define ROUTING_MODE_FTRT 1 -#define ROUTING_MODE_RT 2 -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDAAC_METAFIELD_MASK 0xFFFF0000 -#define AUDAAC_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */ -#define AUDAAC_EOS_FLG_MASK 0x01 -#define AUDAAC_EOS_NONE 0x0 /* No EOS detected */ -#define AUDAAC_EOS_SET 0x1 /* EOS set in meta field */ - -#define AUDAAC_EVENT_NUM 10 /* Default number of pre-allocated event packets */ - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; - unsigned short mfield_sz; /*only useful for data has meta field */ -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audaac_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct audaac_event{ - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audio { - struct buffer out[2]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - unsigned out_dma_sz; - - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - /* Host PCM section */ - struct buffer in[PCM_BUF_MAX_COUNT]; - struct mutex read_lock; - wait_queue_head_t read_wait; /* Wait queue for read */ - char *read_data; /* pointer to reader buffer */ - int32_t read_phys; /* physical address of reader buffer */ - uint8_t read_next; /* index to input buffers to be read next */ - uint8_t fill_next; /* index to buffer that DSP should be filling */ - uint8_t pcm_buf_count; /* number of pcm buffer allocated */ - /* ---- End of Host PCM section */ - - struct msm_adsp_module *audplay; - void *map_v_read; - void *map_v_write; - - /* configuration to use on next enable */ - uint32_t out_sample_rate; - uint32_t out_channel_mode; - struct msm_audio_aac_config aac_config; - struct audmgr audmgr; - - /* data allocated for various buffers */ - char *data; - int32_t phys; /* physical address of write buffer */ - - int mfield; /* meta field embedded in data */ - int rflush; /* Read flush */ - int eos_in_progress; - int wflush; /* Write flush */ - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - int pcm_feedback; - int buf_refresh; - int rmt_resource_released; - int teos; /* valid only if tunnel mode & no data left for decoder */ - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - int reserved; /* A byte is being reserved */ - char rsv_byte; /* Handle odd length user data */ - - const char *module_name; - unsigned queue_id; - uint16_t dec_id; - uint32_t read_ptr_offset; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audaac_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - - struct msm_audio_bitstream_info stream_info; - - int eq_enable; - int eq_needs_commit; - audpp_cmd_cfg_object_params_eqalizer eq; - audpp_cmd_cfg_object_params_volume vol_pan; - struct ion_client *client; - struct ion_handle *input_buff_handle; - struct ion_handle *output_buff_handle; -}; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audpp_cmd_cfg_adec_params(struct audio *audio); -static void audpp_cmd_cfg_routing_mode(struct audio *audio); -static void audplay_send_data(struct audio *audio, unsigned needed); -static void audplay_config_hostpcm(struct audio *audio); -static void audplay_buffer_refresh(struct audio *audio); -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg); -static void audaac_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); - -static int rmt_put_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_DISABLE; - cmd.dec_type = AUDDEC_DEC_AAC; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - - return put_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -static int rmt_get_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_ENABLE; - cmd.dec_type = AUDDEC_DEC_AAC; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - - return get_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -/* must be called with audio->lock held */ -static int audio_enable(struct audio *audio) -{ - struct audmgr_config cfg; - int rc; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (audio->enabled) - return 0; - - if (audio->rmt_resource_released == 1) { - audio->rmt_resource_released = 0; - rc = rmt_get_resource(audio); - if (rc) { - MM_ERR("ADSP resources are not available for AAC \ - session 0x%08x on decoder: %d\n Ignoring \ - error and going ahead with the playback\n", - (int)audio, audio->dec_id); - } - } - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_tail = 0; - audio->out_needed = 0; - - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) { - cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; - cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000; - cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK; - cfg.codec = RPC_AUD_DEF_CODEC_AAC; - cfg.snd_method = RPC_SND_METHOD_MIDI; - - rc = audmgr_enable(&audio->audmgr, &cfg); - if (rc < 0) - return rc; - } - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - audio->enabled = 1; - return 0; -} - -/* must be called with audio->lock held */ -static int audio_disable(struct audio *audio) -{ - int rc = 0; - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - audio->stopped = 1; - wake_up(&audio->write_wait); - wake_up(&audio->read_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - audio->out_needed = 0; - rmt_put_resource(audio); - audio->rmt_resource_released = 1; - } - return rc; -} - -/* ------------------- dsp --------------------- */ -static void audio_update_pcm_buf_entry(struct audio *audio, uint32_t *payload) -{ - uint8_t index; - unsigned long flags; - - if (audio->rflush) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < payload[1]; index++) { - if (audio->in[audio->fill_next].addr == - payload[2 + index * 2]) { - MM_DBG("in[%d] ready\n", audio->fill_next); - audio->in[audio->fill_next].used = - payload[3 + index * 2]; - if ((++audio->fill_next) == audio->pcm_buf_count) - audio->fill_next = 0; - - } else { - MM_ERR("expected=%x ret=%x\n", - audio->in[audio->fill_next].addr, - payload[1 + index * 2]); - break; - } - } - if (audio->in[audio->fill_next].used == 0) { - audplay_buffer_refresh(audio); - } else { - MM_DBG("read cannot keep up\n"); - audio->buf_refresh = 1; - } - wake_up(&audio->read_wait); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - -} -static void audaac_update_stream_info(struct audio *audio, uint32_t *payload) -{ - unsigned long flags; - union msm_audio_event_payload e_payload; - - /* get stream info from DSP msg */ - spin_lock_irqsave(&audio->dsp_lock, flags); - - audio->stream_info.codec_type = AUDIO_CODEC_TYPE_AAC; - audio->stream_info.chan_info = (0x0000FFFF & payload[1]); - audio->stream_info.sample_rate = (0x0000FFFF & payload[2]); - audio->stream_info.bit_stream_info = (0x0000FFFF & payload[3]); - audio->stream_info.bit_rate = payload[4]; - - spin_unlock_irqrestore(&audio->dsp_lock, flags); - MM_DBG("chan_info=%d, sample_rate=%d, bit_stream_info=%d\n", - audio->stream_info.chan_info, - audio->stream_info.sample_rate, - audio->stream_info.bit_stream_info); - - /* send event to ARM to notify steam info coming */ - e_payload.stream_info = audio->stream_info; - audaac_post_event(audio, AUDIO_EVENT_STREAM_INFO, e_payload); -} -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - getevent(msg, sizeof(msg)); - - MM_DBG("msg_id=%x\n", id); - - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audplay_send_data(audio, 1); - break; - - case AUDPLAY_MSG_BUFFER_UPDATE: - audio_update_pcm_buf_entry(audio, msg); - break; - - case AUDPLAY_UP_STREAM_INFO: - audaac_update_stream_info(audio, msg); - break; - - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audplaytask)\n"); - break; - - default: - MM_ERR("unexpected message from decoder \n"); - } -} - -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status: sleep reason = \ - 0x%04x\n", reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init \n"); - if (audio->pcm_feedback) - audpp_cmd_cfg_routing_mode(audio); - else - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg \n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play \n"); - if (audio->pcm_feedback) { - audplay_config_hostpcm(audio); - audplay_buffer_refresh(audio); - } - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - default: - MM_ERR("unknown decoder status \n"); - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - audpp_dsp_set_eq(audio->dec_id, audio->eq_enable, - &audio->eq); - audpp_avsync(audio->dec_id, 22050); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audpp_avsync(audio->dec_id, 0); - audio->running = 0; - } else { - MM_DBG("CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_ROUTING_ACK: - MM_DBG("ROUTING_ACK mode=%d\n", msg[1]); - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - audio->rflush = 0; - wake_up(&audio->write_wait); - if (audio->pcm_feedback) - audplay_buffer_refresh(audio); - break; - - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - - default: - MM_ERR("UNKNOWN (%d)\n", id); - } - -} - -struct msm_adsp_ops audplay_adsp_ops_aac = { - .event = audplay_dsp_event, -}; - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id,\ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - u16 cfg_dec_cmd[AUDPP_CMD_CFG_DEC_TYPE_LEN / sizeof(unsigned short)]; - - memset(cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - cfg_dec_cmd[0] = AUDPP_CMD_CFG_DEC_TYPE; - - if (enable) - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_AAC; - else - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} - -static void audpp_cmd_cfg_adec_params(struct audio *audio) -{ - audpp_cmd_cfg_adec_params_aac cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_AAC_LEN; - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = audio->out_sample_rate; - cmd.format = audio->aac_config.format; - cmd.audio_object = audio->aac_config.audio_object; - cmd.ep_config = audio->aac_config.ep_config; - cmd.aac_section_data_resilience_flag = - audio->aac_config.aac_section_data_resilience_flag; - cmd.aac_scalefactor_data_resilience_flag = - audio->aac_config.aac_scalefactor_data_resilience_flag; - cmd.aac_spectral_data_resilience_flag = - audio->aac_config.aac_spectral_data_resilience_flag; - cmd.sbr_on_flag = audio->aac_config.sbr_on_flag; - cmd.sbr_ps_on_flag = audio->aac_config.sbr_ps_on_flag; - cmd.channel_configuration = audio->aac_config.channel_configuration; - - audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static void audpp_cmd_cfg_routing_mode(struct audio *audio) -{ - struct audpp_cmd_routing_mode cmd; - MM_DBG("\n"); /* Macro prints the file name and function */ - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; - cmd.object_number = audio->dec_id; - if (audio->pcm_feedback) - cmd.routing_mode = ROUTING_MODE_FTRT; - else - cmd.routing_mode = ROUTING_MODE_RT; - - audpp_send_queue1(&cmd, sizeof(cmd)); -} - -static int audplay_dsp_send_data_avail(struct audio *audio, - unsigned idx, unsigned len) -{ - struct audplay_cmd_bitstream_data_avail_nt2 cmd; - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2; - if (audio->mfield) - cmd.decoder_id = AUDAAC_METAFIELD_MASK | - (audio->out[idx].mfield_sz >> 1); - else - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = audio->out[idx].addr; - cmd.buf_size = len / 2; - cmd.partition_number = 0; - /* complete all the writes to the input buffer */ - wmb(); - return audplay_send_queue0(audio, &cmd, sizeof(cmd)); -} - -static void audplay_buffer_refresh(struct audio *audio) -{ - struct audplay_cmd_buffer_refresh refresh_cmd; - - refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; - refresh_cmd.num_buffers = 1; - refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; - /* AAC frame size */ - refresh_cmd.buf0_length = audio->in[audio->fill_next].size - - (audio->in[audio->fill_next].size % 1024) - + (audio->mfield ? 24 : 0); - refresh_cmd.buf_read_count = 0; - MM_DBG("buf0_addr=%x buf0_len=%d\n", refresh_cmd.buf0_address, - refresh_cmd.buf0_length); - (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); -} - -static void audplay_config_hostpcm(struct audio *audio) -{ - struct audplay_cmd_hpcm_buf_cfg cfg_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; - cfg_cmd.max_buffers = audio->pcm_buf_count; - cfg_cmd.byte_swap = 0; - cfg_cmd.hostpcm_config = (0x8000) | (0x4000); - cfg_cmd.feedback_frequency = 1; - cfg_cmd.partition_number = 0; - (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); - -} - -static void audplay_send_data(struct audio *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } else if ((audio->out[0].used == 0) && - (audio->out[1].used == 0) && - (audio->eos_in_progress)) { - wake_up(&audio->write_wait); - } - - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - MM_DBG("frame %d busy\n", audio->out_tail); - audplay_dsp_send_data_avail(audio, audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } - done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ - -static void audio_flush(struct audio *audio) -{ - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->reserved = 0; - audio->out_needed = 0; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - atomic_set(&audio->out_bytes, 0); -} - -static void audio_flush_pcm_buf(struct audio *audio) -{ - uint8_t index; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < PCM_BUF_MAX_COUNT; index++) - audio->in[index].used = 0; - audio->buf_refresh = 0; - audio->read_next = 0; - audio->fill_next = 0; - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static int audaac_validate_usr_config(struct msm_audio_aac_config *config) -{ - int ret_val = -1; - - if (config->format != AUDIO_AAC_FORMAT_ADTS && - config->format != AUDIO_AAC_FORMAT_RAW && - config->format != AUDIO_AAC_FORMAT_PSUEDO_RAW && - config->format != AUDIO_AAC_FORMAT_LOAS) - goto done; - - if (config->audio_object != AUDIO_AAC_OBJECT_LC && - config->audio_object != AUDIO_AAC_OBJECT_LTP && - config->audio_object != AUDIO_AAC_OBJECT_BSAC && - config->audio_object != AUDIO_AAC_OBJECT_ERLC) - goto done; - - if (config->audio_object == AUDIO_AAC_OBJECT_ERLC) { - if (config->ep_config > 3) - goto done; - if (config->aac_scalefactor_data_resilience_flag != - AUDIO_AAC_SCA_DATA_RES_OFF && - config->aac_scalefactor_data_resilience_flag != - AUDIO_AAC_SCA_DATA_RES_ON) - goto done; - if (config->aac_section_data_resilience_flag != - AUDIO_AAC_SEC_DATA_RES_OFF && - config->aac_section_data_resilience_flag != - AUDIO_AAC_SEC_DATA_RES_ON) - goto done; - if (config->aac_spectral_data_resilience_flag != - AUDIO_AAC_SPEC_DATA_RES_OFF && - config->aac_spectral_data_resilience_flag != - AUDIO_AAC_SPEC_DATA_RES_ON) - goto done; - } else { - config->aac_section_data_resilience_flag = - AUDIO_AAC_SEC_DATA_RES_OFF; - config->aac_scalefactor_data_resilience_flag = - AUDIO_AAC_SCA_DATA_RES_OFF; - config->aac_spectral_data_resilience_flag = - AUDIO_AAC_SPEC_DATA_RES_OFF; - } - -#ifndef CONFIG_AUDIO_AAC_PLUS - if (AUDIO_AAC_SBR_ON_FLAG_OFF != config->sbr_on_flag) - goto done; -#else - if (config->sbr_on_flag != AUDIO_AAC_SBR_ON_FLAG_OFF && - config->sbr_on_flag != AUDIO_AAC_SBR_ON_FLAG_ON) - goto done; -#endif - -#ifndef CONFIG_AUDIO_ENHANCED_AAC_PLUS - if (AUDIO_AAC_SBR_PS_ON_FLAG_OFF != config->sbr_ps_on_flag) - goto done; -#else - if (config->sbr_ps_on_flag != AUDIO_AAC_SBR_PS_ON_FLAG_OFF && - config->sbr_ps_on_flag != AUDIO_AAC_SBR_PS_ON_FLAG_ON) - goto done; -#endif - - if (config->dual_mono_mode > AUDIO_AAC_DUAL_MONO_PL_SR) - goto done; - - if (config->channel_configuration > 2) - goto done; - - ret_val = 0; - done: - return ret_val; -} - -static void audio_ioport_reset(struct audio *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audio_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->read_wait); - mutex_lock(&audio->read_lock); - audio_flush_pcm_buf(audio); - mutex_unlock(&audio->read_lock); -} - -static int audaac_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audaac_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audaac_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audaac_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audaac_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - -static long audaac_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audaac_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - audio->event_wait, audaac_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audaac_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - rc = 0; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audaac_event, list); - list_del(&drv_evt->list); - } - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audio_enable_eq(struct audio *audio, int enable) -{ - if (audio->eq_enable == enable && !audio->eq_needs_commit) - return 0; - - audio->eq_enable = enable; - - if (audio->running) { - audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq); - audio->eq_needs_commit = 0; - } - return 0; -} - -static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - unsigned long flags = 0; - uint16_t enable_mask; - int enable; - int prev_state; - - MM_DBG("cmd = %d\n", cmd); - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = audpp_avsync_byte_count(audio->dec_id); - stats.sample_count = audpp_avsync_sample_count(audio->dec_id); - if (copy_to_user((void *)arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - switch (cmd) { - case AUDIO_ENABLE_AUDPP: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - spin_lock_irqsave(&audio->dsp_lock, flags); - enable = (enable_mask & EQ_ENABLE) ? 1 : 0; - audio_enable_eq(audio, enable); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - case AUDIO_SET_VOLUME: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.volume = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_PAN: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.pan = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_EQ: - prev_state = audio->eq_enable; - audio->eq_enable = 0; - if (copy_from_user(&audio->eq.num_bands, (void *) arg, - sizeof(audio->eq) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) { - rc = -EFAULT; - break; - } - audio->eq_enable = prev_state; - audio->eq_needs_commit = 1; - rc = 0; - break; - } - - if (-EINVAL != rc) - return rc; - - if (cmd == AUDIO_GET_EVENT) { - MM_DBG("AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audaac_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audio_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) - rc = -ENODEV; - else - rc = 0; - } - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audio_disable(audio); - audio_ioport_reset(audio); - audio->stopped = 0; - break; - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH running=%d\n", audio->running); - audio->rflush = 1; - audio->wflush = 1; - audio_ioport_reset(audio); - if (audio->running) { - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - - case AUDIO_SET_CONFIG:{ - struct msm_audio_config config; - - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - - if (config.channel_count == 1) { - config.channel_count = - AUDPP_CMD_PCM_INTF_MONO_V; - } else if (config.channel_count == 2) { - config.channel_count = - AUDPP_CMD_PCM_INTF_STEREO_V; - } else { - rc = -EINVAL; - break; - } - - audio->out_sample_rate = config.sample_rate; - audio->out_channel_mode = config.channel_count; - audio->mfield = config.meta_field; - rc = 0; - break; - } - case AUDIO_GET_CONFIG:{ - struct msm_audio_config config; - config.buffer_size = (audio->out_dma_sz >> 1); - config.buffer_count = 2; - config.sample_rate = audio->out_sample_rate; - if (audio->out_channel_mode == - AUDPP_CMD_PCM_INTF_MONO_V) { - config.channel_count = 1; - } else { - config.channel_count = 2; - } - config.meta_field = 0; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - - break; - } - case AUDIO_GET_AAC_CONFIG:{ - if (copy_to_user((void *)arg, &audio->aac_config, - sizeof(audio->aac_config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_AAC_CONFIG:{ - struct msm_audio_aac_config usr_config; - - if (copy_from_user - (&usr_config, (void *)arg, - sizeof(usr_config))) { - rc = -EFAULT; - break; - } - - if (audaac_validate_usr_config(&usr_config) == 0) { - audio->aac_config = usr_config; - rc = 0; - } else - rc = -EINVAL; - - break; - } - case AUDIO_GET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - config.pcm_feedback = audio->pcm_feedback; - config.buffer_count = PCM_BUF_MAX_COUNT; - config.buffer_size = PCM_BUFSZ_MIN; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.pcm_feedback != audio->pcm_feedback) { - MM_ERR("Not sufficient permission to" - "change the playback mode\n"); - rc = -EACCES; - break; - } - if ((config.buffer_count > PCM_BUF_MAX_COUNT) || - (config.buffer_count == 1)) - config.buffer_count = PCM_BUF_MAX_COUNT; - - if (config.buffer_size < PCM_BUFSZ_MIN) - config.buffer_size = PCM_BUFSZ_MIN; - - /* Check if pcm feedback is required */ - if (config.pcm_feedback) { - audio->buf_refresh = 0; - audio->read_next = 0; - audio->fill_next = 0; - } - rc = 0; - break; - } - case AUDIO_PAUSE: - MM_DBG("AUDIO_PAUSE %ld\n", arg); - rc = audpp_pause(audio->dec_id, (int) arg); - break; - case AUDIO_GET_STREAM_INFO:{ - if (audio->stream_info.sample_rate == 0) { - /* haven't received DSP stream event, - the stream info is not updated */ - rc = -EPERM; - break; - } - if (copy_to_user((void *)arg, &audio->stream_info, - sizeof(struct msm_audio_bitstream_info))) - rc = -EFAULT; - else - rc = 0; - break; - } - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} -/* Only useful in tunnel-mode */ -static int audaac_fsync(struct file *file, loff_t a, loff_t b, int datasync) -{ - struct audio *audio = file->private_data; - struct buffer *frame; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (!audio->running || audio->pcm_feedback) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (audio->reserved) { - MM_DBG("send reserved byte\n"); - frame = audio->out + audio->out_tail; - ((char *) frame->data)[0] = audio->rsv_byte; - ((char *) frame->data)[1] = 0; - frame->used = 2; - audplay_send_data(audio, 0); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - } - - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush); - - if (audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; -} - -static ssize_t audio_read(struct file *file, char __user *buf, size_t count, - loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - int rc = 0; - - if (!audio->pcm_feedback) - return 0; /* PCM feedback is not enabled. Nothing to read */ - - mutex_lock(&audio->read_lock); - MM_DBG("to read %d \n", count); - while (count > 0) { - rc = wait_event_interruptible(audio->read_wait, - (audio->in[audio->read_next]. - used > 0) || (audio->stopped) - || (audio->rflush)); - - if (rc < 0) - break; - - if (audio->stopped || audio->rflush) { - rc = -EBUSY; - break; - } - - if (count < audio->in[audio->read_next].used) { - /* Read must happen in frame boundary. Since driver - does not know frame size, read count must be greater - or equal to size of PCM samples */ - MM_DBG("no partial frame done reading\n"); - break; - } else { - MM_DBG("read from in[%d]\n", audio->read_next); - /* order reads to the output buffer */ - rmb(); - if (copy_to_user - (buf, audio->in[audio->read_next].data, - audio->in[audio->read_next].used)) { - MM_ERR("invalid addr %x\n", (unsigned int)buf); - rc = -EFAULT; - break; - } - count -= audio->in[audio->read_next].used; - buf += audio->in[audio->read_next].used; - audio->in[audio->read_next].used = 0; - if ((++audio->read_next) == audio->pcm_buf_count) - audio->read_next = 0; - break; - /* - * Force to exit while loop - * to prevent output thread - * sleep too long if data is not - * ready at this moment. - */ - } - } - - /* don't feed output buffer to HW decoder during flushing - * buffer refresh command will be sent once flush completes - * send buf refresh command here can confuse HW decoder - */ - if (audio->buf_refresh && !audio->rflush) { - audio->buf_refresh = 0; - MM_DBG("kick start pcm feedback again\n"); - audplay_buffer_refresh(audio); - } - - mutex_unlock(&audio->read_lock); - - if (buf > start) - rc = buf - start; - - MM_DBG("read %d bytes\n", rc); - return rc; -} - -static int audaac_process_eos(struct audio *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - struct buffer *frame; - char *buf_ptr; - int rc = 0; - unsigned long flags = 0; - - MM_DBG("signal input EOS reserved=%d\n", audio->reserved); - if (audio->reserved) { - MM_DBG("Pass reserve byte\n"); - frame = audio->out + audio->out_head; - buf_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - buf_ptr[0] = audio->rsv_byte; - buf_ptr[1] = 0; - audio->out_head ^= 1; - frame->mfield_sz = 0; - audio->reserved = 0; - frame->used = 2; - audplay_send_data(audio, 0); - } - MM_DBG("Now signal input EOS after reserved bytes %d %d %d\n", - audio->out[0].used, audio->out[1].used, audio->out_needed); - frame = audio->out + audio->out_head; - - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->eos_in_progress = 1; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->eos_in_progress = 0; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - audplay_send_data(audio, 0); -done: - return rc; -} -static ssize_t audio_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - char *cpy_ptr; - int rc = 0, eos_condition = AUDAAC_EOS_NONE; - unsigned dsize; - - unsigned short mfield_size = 0; - MM_DBG("cnt=%d\n", count); - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - cpy_ptr = frame->data; - dsize = 0; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - break; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - break; - } - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - break; - } else if (mfield_size > count) { - rc = -EINVAL; - break; - } - MM_DBG("mf offset_val %x\n", mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - break; - } - /* Check if EOS flag is set and buffer has - * contains just meta field - */ - if (cpy_ptr[AUDAAC_EOS_FLG_OFFSET] & - AUDAAC_EOS_FLG_MASK) { - MM_DBG("eos set\n"); - eos_condition = AUDAAC_EOS_SET; - if (mfield_size == count) { - buf += mfield_size; - break; - } else - cpy_ptr[AUDAAC_EOS_FLG_OFFSET] &= - ~AUDAAC_EOS_FLG_MASK; - } - /* Check EOS to see if */ - cpy_ptr += mfield_size; - count -= mfield_size; - dsize += mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - - if (audio->reserved) { - MM_DBG("append reserved byte %x\n", - audio->rsv_byte); - *cpy_ptr = audio->rsv_byte; - xfer = (count > ((frame->size - mfield_size) - 1)) ? - (frame->size - mfield_size) - 1 : count; - cpy_ptr++; - dsize += 1; - audio->reserved = 0; - } else - xfer = (count > (frame->size - mfield_size)) ? - (frame->size - mfield_size) : count; - - if (copy_from_user(cpy_ptr, buf, xfer)) { - rc = -EFAULT; - break; - } - - dsize += xfer; - if (dsize & 1) { - audio->rsv_byte = ((char *) frame->data)[dsize - 1]; - MM_DBG("odd length buf reserve last byte %x\n", - audio->rsv_byte); - audio->reserved = 1; - dsize--; - } - count -= xfer; - buf += xfer; - - if (dsize > 0) { - audio->out_head ^= 1; - frame->used = dsize; - audplay_send_data(audio, 0); - } - } - MM_DBG("eos_condition %x buf[0x%x] start[0x%x]\n", eos_condition, - (int) buf, (int) start); - if (eos_condition == AUDAAC_EOS_SET) - rc = audaac_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - if (!rc) { - if (buf > start) - return buf - start; - } - return rc; -} - -static int audio_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_INFO("audio instance 0x%08x freeing\n", (int)audio); - mutex_lock(&audio->lock); - audio_disable(audio); - if (audio->rmt_resource_released == 0) - rmt_put_resource(audio); - audio_flush(audio); - audio_flush_pcm_buf(audio); - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->event_abort = 1; - wake_up(&audio->event_wait); - audaac_reset_event_queue(audio); - ion_unmap_kernel(audio->client, audio->output_buff_handle); - ion_free(audio->client, audio->output_buff_handle); - ion_unmap_kernel(audio->client, audio->input_buff_handle); - ion_free(audio->client, audio->input_buff_handle); - ion_client_destroy(audio->client); - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - kfree(audio); - return 0; -} - -static void audaac_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audaac_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audaac_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audaac_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audaac_suspend(struct early_suspend *h) -{ - struct audaac_suspend_ctl *ctl = - container_of(h, struct audaac_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audaac_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audaac_resume(struct early_suspend *h) -{ - struct audaac_suspend_ctl *ctl = - container_of(h, struct audaac_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audaac_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audaac_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audaac_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 1024; - static char buffer[1024]; - int n = 0, i; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_feedback %d\n", audio->pcm_feedback); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_buf_sz %d\n", audio->out[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_count %d \n", audio->pcm_buf_count); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_sz %d \n", audio->in[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %x \n", audio->vol_pan.volume); - n += scnprintf(buffer + n, debug_bufmax - n, - "sample rate %d \n", audio->out_sample_rate); - n += scnprintf(buffer + n, debug_bufmax - n, - "channel mode %d \n", audio->out_channel_mode); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "rflush %d\n", audio->rflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d \n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d \n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d \n", audio->out_needed); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_head %d \n", audio->out_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_tail %d \n", audio->out_tail); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[0].used %d \n", audio->out[0].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[1].used %d \n", audio->out[1].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "buffer_refresh %d \n", audio->buf_refresh); - n += scnprintf(buffer + n, debug_bufmax - n, - "read_next %d \n", audio->read_next); - n += scnprintf(buffer + n, debug_bufmax - n, - "fill_next %d \n", audio->fill_next); - for (i = 0; i < audio->pcm_buf_count; i++) - n += scnprintf(buffer + n, debug_bufmax - n, - "in[%d].used %d \n", i, audio->in[i].used); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audaac_debug_fops = { - .read = audaac_debug_read, - .open = audaac_debug_open, -}; -#endif - -static int audio_open(struct inode *inode, struct file *file) -{ - struct audio *audio = NULL; - int rc, dec_attrb, decid, index, offset = 0; - unsigned mem_sz = DMASZ; - struct audaac_event *e_node = NULL; - int len = 0; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - struct ion_client *client = NULL; -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_aac_" + 5]; -#endif - - /* Allocate audio instance, set to zero */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("no memory to allocate audio instance \n"); - rc = -ENOMEM; - goto done; - } - MM_INFO("audio instance 0x%08x created\n", (int)audio); - - /* Allocate the decoder */ - dec_attrb = AUDDEC_DEC_AAC; - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_NONTUNNEL; - audio->pcm_feedback = NON_TUNNEL_MODE_PLAYBACK; - } else if ((file->f_mode & FMODE_WRITE) && - !(file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_TUNNEL; - audio->pcm_feedback = TUNNEL_MODE_PLAYBACK; - } else { - kfree(audio); - rc = -EACCES; - goto done; - } - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - - if (decid < 0) { - MM_ERR("No free decoder available, freeing instance 0x%08x\n", - (int)audio); - rc = -ENODEV; - kfree(audio); - goto done; - } - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - client = msm_ion_client_create(UINT_MAX, "Audio_AAC_client"); - if (IS_ERR_OR_NULL(client)) { - MM_ERR("Unable to create ION client\n"); - rc = -ENOMEM; - goto client_create_error; - } - audio->client = client; - - MM_DBG("allocating mem sz = %d\n", mem_sz); - handle = ion_alloc(client, mem_sz, SZ_4K, - ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to create allocate O/P buffers\n"); - rc = -ENOMEM; - goto output_buff_alloc_error; - } - - audio->output_buff_handle = handle; - - rc = ion_phys(client, handle, &addr, &len); - if (rc) { - MM_ERR("O/P buffers:Invalid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - goto output_buff_get_phys_error; - } else { - MM_INFO("O/P buffers:valid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - } - audio->phys = (int32_t)addr; - - rc = ion_handle_get_flags(client, handle, &ionflag); - if (rc) { - MM_ERR("could not get flags for the handle\n"); - goto output_buff_get_flags_error; - } - - audio->map_v_write = ion_map_kernel(client, handle); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write buffers,freeing instance 0x%08x\n", - (int)audio); - rc = -ENOMEM; - goto output_buff_map_error; - } - audio->data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->phys, (int)audio->data); - - audio->out_dma_sz = mem_sz; - - mem_sz = (PCM_BUFSZ_MIN * PCM_BUF_MAX_COUNT); - MM_DBG("allocating mem sz = %d\n", mem_sz); - handle = ion_alloc(client, mem_sz, - SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to create allocate I/P buffers\n"); - rc = -ENOMEM; - goto input_buff_alloc_error; - } - - audio->input_buff_handle = handle; - - rc = ion_phys(client , handle, &addr, &len); - if (rc) { - MM_ERR("I/P buffers:Invalid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - goto input_buff_get_phys_error; - } else { - MM_INFO("out Got valid phy: %x sz: %x\n", - (unsigned int) audio->read_phys, (unsigned int) len); - } - audio->read_phys = (int32_t)addr; - - rc = ion_handle_get_flags(client, - handle, &ionflag); - if (rc) { - MM_ERR("could not get flags for the handle\n"); - goto input_buff_get_flags_error; - } - - audio->map_v_read = ion_map_kernel(client, handle); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("could not map read buffers, freeing instance \ - 0x%08x\n", (int)audio); - rc = -ENOMEM; - goto input_buff_map_error; - } - audio->read_data = audio->map_v_read; - MM_DBG("read buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->read_phys, (int)audio->read_data); - - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) { - rc = audmgr_open(&audio->audmgr); - if (rc) { - MM_ERR("audmgr open failed, freeing instance \ - 0x%08x\n", (int)audio); - goto err; - } - } - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audplay_adsp_ops_aac, audio); - if (rc) { - MM_ERR("failed to get %s module, freeing instance 0x%08x\n", - audio->module_name, (int)audio); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_close(&audio->audmgr); - goto err; - } - - rc = rmt_get_resource(audio); - if (rc) { - MM_ERR("ADSP resources are not available for AAC session \ - 0x%08x on decoder: %d\n", (int)audio, audio->dec_id); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_close(&audio->audmgr); - msm_adsp_put(audio->audplay); - goto err; - } - - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->read_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - spin_lock_init(&audio->event_queue_lock); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->write_wait); - init_waitqueue_head(&audio->read_wait); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = audio->out_dma_sz >> 1; - - audio->out[1].data = audio->data + audio->out[0].size; - audio->out[1].addr = audio->phys + audio->out[0].size; - audio->out[1].size = audio->out[0].size; - - audio->pcm_buf_count = PCM_BUF_MAX_COUNT; - for (index = 0; index < PCM_BUF_MAX_COUNT; index++) { - audio->in[index].data = audio->read_data + offset; - audio->in[index].addr = audio->read_phys + offset; - audio->in[index].size = PCM_BUFSZ_MIN; - audio->in[index].used = 0; - offset += PCM_BUFSZ_MIN; - } - - audio->out_sample_rate = 44100; - audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V; - audio->aac_config.format = AUDIO_AAC_FORMAT_ADTS; - audio->aac_config.audio_object = AUDIO_AAC_OBJECT_LC; - audio->aac_config.ep_config = 0; - audio->aac_config.aac_section_data_resilience_flag = - AUDIO_AAC_SEC_DATA_RES_OFF; - audio->aac_config.aac_scalefactor_data_resilience_flag = - AUDIO_AAC_SCA_DATA_RES_OFF; - audio->aac_config.aac_spectral_data_resilience_flag = - AUDIO_AAC_SPEC_DATA_RES_OFF; -#ifdef CONFIG_AUDIO_AAC_PLUS - audio->aac_config.sbr_on_flag = AUDIO_AAC_SBR_ON_FLAG_ON; -#else - audio->aac_config.sbr_on_flag = AUDIO_AAC_SBR_ON_FLAG_OFF; -#endif -#ifdef CONFIG_AUDIO_ENHANCED_AAC_PLUS - audio->aac_config.sbr_ps_on_flag = AUDIO_AAC_SBR_PS_ON_FLAG_ON; -#else - audio->aac_config.sbr_ps_on_flag = AUDIO_AAC_SBR_PS_ON_FLAG_OFF; -#endif - audio->aac_config.dual_mono_mode = AUDIO_AAC_DUAL_MONO_PL_SR; - audio->aac_config.channel_configuration = 2; - audio->vol_pan.volume = 0x2000; - - audio_flush(audio); - - file->private_data = audio; - audio->opened = 1; -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_aac_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, - &audaac_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audaac_resume; - audio->suspend_ctl.node.suspend = audaac_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (index = 0; index < AUDAAC_EVENT_NUM; index++) { - e_node = kmalloc(sizeof(struct audaac_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } - memset(&audio->stream_info, 0, sizeof(struct msm_audio_bitstream_info)); -done: - return rc; -err: - ion_unmap_kernel(client, audio->input_buff_handle); -input_buff_map_error: -input_buff_get_flags_error: -input_buff_get_phys_error: - ion_free(client, audio->input_buff_handle); -input_buff_alloc_error: - ion_unmap_kernel(client, audio->output_buff_handle); -output_buff_map_error: -output_buff_get_phys_error: -output_buff_get_flags_error: - ion_free(client, audio->output_buff_handle); -output_buff_alloc_error: - ion_client_destroy(client); -client_create_error: - audpp_adec_free(audio->dec_id); - kfree(audio); - return rc; -} - -static const struct file_operations audio_aac_fops = { - .owner = THIS_MODULE, - .open = audio_open, - .release = audio_release, - .read = audio_read, - .write = audio_write, - .unlocked_ioctl = audio_ioctl, - .fsync = audaac_fsync -}; - -struct miscdevice audio_aac_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_aac", - .fops = &audio_aac_fops, -}; - -static int __init audio_init(void) -{ - return misc_register(&audio_aac_misc); -} - -static void __exit audio_exit(void) -{ - misc_deregister(&audio_aac_misc); -} - -module_init(audio_init); -module_exit(audio_exit); - -MODULE_DESCRIPTION("MSM AAC driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5/audio_aac_in.c b/arch/arm/mach-msm/qdsp5/audio_aac_in.c deleted file mode 100644 index 1e6ef6005857d5c4200ac4a0856472f41d88139e..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_aac_in.c +++ /dev/null @@ -1,1530 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/audio_aac_in.c - * - * aac audio input device - * - * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. - * - * This code is based in part on arch/arm/mach-msm/qdsp5v2/audio_aac_in.c, - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "audmgr.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define FRAME_HEADER_SIZE 8 /* 8 bytes frame header */ -#define NT_FRAME_HEADER_SIZE 24 /* 24 bytes frame header */ -/* FRAME_NUM must be a power of two */ -#define FRAME_NUM 8 -#define AAC_FRAME_SIZE 1536 /* 36 bytes data */ -/*Tunnel mode : 1536 bytes data + 8 byte header*/ -#define FRAME_SIZE (AAC_FRAME_SIZE + FRAME_HEADER_SIZE) -/* 1536 bytes data + 24 meta field*/ -#define NT_FRAME_SIZE (AAC_FRAME_SIZE + NT_FRAME_HEADER_SIZE) -#define DMASZ (FRAME_SIZE * FRAME_NUM) -#define NT_DMASZ (NT_FRAME_SIZE * FRAME_NUM) -#define OUT_FRAME_NUM 2 -#define OUT_BUFFER_SIZE (32 * 1024 + NT_FRAME_HEADER_SIZE) -#define BUFFER_SIZE (OUT_BUFFER_SIZE * OUT_FRAME_NUM) - -#define AUDPREPROC_AAC_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer*/ -#define AUDPREPROC_AAC_EOS_FLG_MASK 0x01 -#define AUDPREPROC_AAC_EOS_NONE 0x0 /* No EOS detected */ -#define AUDPREPROC_AAC_EOS_SET 0x1 /* EOS set in meta field */ - -struct buffer { - void *data; - uint32_t size; - uint32_t read; - uint32_t addr; - uint32_t used; - uint32_t mfield_sz; -}; - -struct audio_aac_in { - struct buffer in[FRAME_NUM]; - - spinlock_t dsp_lock; - - atomic_t in_bytes; - atomic_t in_samples; - - struct mutex lock; - struct mutex read_lock; - wait_queue_head_t wait; - wait_queue_head_t wait_enable; - /*write section*/ - struct buffer out[OUT_FRAME_NUM]; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - uint32_t out_count; - - struct mutex write_lock; - wait_queue_head_t write_wait; - int32_t out_phys; /* physical address of write buffer */ - char *out_data; - int mfield; /* meta field embedded in data */ - int wflush; /*write flush */ - int rflush; /*read flush*/ - int out_frame_cnt; - - struct msm_adsp_module *audrec; - struct msm_adsp_module *audpre; - - - /* configuration to use on next enable */ - uint32_t samp_rate; - uint32_t channel_mode; - uint32_t buffer_size; /* Frame size (1536 bytes) */ - uint32_t bit_rate; /* bit rate for AAC */ - uint32_t record_quality; /* record quality (bits/sample/channel) */ - uint32_t enc_type; /* 1 for AAC */ - uint32_t mode; /* T or NT Mode*/ - uint32_t dsp_cnt; - uint32_t in_head; /* next buffer dsp will write */ - uint32_t in_tail; /* next buffer read() will read */ - uint32_t in_count; /* number of buffers available to read() */ - - uint32_t eos_ack; - uint32_t flush_ack; - - const char *module_name; - unsigned queue_ids; - uint16_t enc_id; /* Session Id */ - - unsigned short samp_rate_index; - uint32_t audrec_obj_idx ; - - struct audmgr audmgr; - - /* data allocated for various buffers */ - char *data; - dma_addr_t phys; - void *map_v_read; - void *map_v_write; - - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - struct ion_client *client; - struct ion_handle *input_buff_handle; - struct ion_handle *output_buff_handle; -}; - -struct audio_frame { - uint16_t frame_count_lsw; - uint16_t frame_count_msw; - uint16_t frame_length; - uint16_t erased_pcm; - unsigned char raw_bitstream[]; -} __packed; - -struct audio_frame_nt { - uint16_t metadata_len; - uint16_t frame_count_lsw; - uint16_t frame_count_msw; - uint16_t frame_length; - uint16_t erased_pcm; - uint16_t reserved; - uint16_t time_stamp_dword_lsw; - uint16_t time_stamp_dword_msw; - uint16_t time_stamp_lsw; - uint16_t time_stamp_msw; - uint16_t nflag_lsw; - uint16_t nflag_msw; - unsigned char raw_bitstream[]; /* samples */ -} __packed; - -struct aac_encoded_meta_out { - uint16_t metadata_len; - uint16_t time_stamp_dword_lsw; - uint16_t time_stamp_dword_msw; - uint16_t time_stamp_lsw; - uint16_t time_stamp_msw; - uint16_t nflag_lsw; - uint16_t nflag_msw; -}; - -/* Audrec Queue command sent macro's */ -#define audio_send_queue_pre(audio, cmd, len) \ - msm_adsp_write(audio->audpre, QDSP_uPAudPreProcCmdQueue, cmd, len) - -#define audio_send_queue_recbs(audio, cmd, len) \ - msm_adsp_write(audio->audrec, ((audio->queue_ids & 0xFFFF0000) >> 16),\ - cmd, len) -#define audio_send_queue_rec(audio, cmd, len) \ - msm_adsp_write(audio->audrec, (audio->queue_ids & 0x0000FFFF),\ - cmd, len) - -static int audaac_in_dsp_enable(struct audio_aac_in *audio, int enable); -static int audaac_in_encparam_config(struct audio_aac_in *audio); -static int audaac_in_encmem_config(struct audio_aac_in *audio); -static int audaac_in_dsp_read_buffer(struct audio_aac_in *audio, - uint32_t read_cnt); -static void audaac_in_flush(struct audio_aac_in *audio); - -static void audaac_in_get_dsp_frames(struct audio_aac_in *audio); -static int audpcm_config(struct audio_aac_in *audio); -static void audaac_out_flush(struct audio_aac_in *audio); -static int audaac_in_routing_mode_config(struct audio_aac_in *audio); -static void audrec_pcm_send_data(struct audio_aac_in *audio, unsigned needed); -static void audaac_nt_in_get_dsp_frames(struct audio_aac_in *audio); -static void audaac_in_flush(struct audio_aac_in *audio); - -static unsigned convert_dsp_samp_index(unsigned index) -{ - switch (index) { - case 48000: return AUDREC_CMD_SAMP_RATE_INDX_48000; - case 44100: return AUDREC_CMD_SAMP_RATE_INDX_44100; - case 32000: return AUDREC_CMD_SAMP_RATE_INDX_32000; - case 24000: return AUDREC_CMD_SAMP_RATE_INDX_24000; - case 22050: return AUDREC_CMD_SAMP_RATE_INDX_22050; - case 16000: return AUDREC_CMD_SAMP_RATE_INDX_16000; - case 12000: return AUDREC_CMD_SAMP_RATE_INDX_12000; - case 11025: return AUDREC_CMD_SAMP_RATE_INDX_11025; - case 8000: return AUDREC_CMD_SAMP_RATE_INDX_8000; - default: return AUDREC_CMD_SAMP_RATE_INDX_11025; - } -} - -static unsigned convert_samp_rate(unsigned hz) -{ - switch (hz) { - case 48000: return RPC_AUD_DEF_SAMPLE_RATE_48000; - case 44100: return RPC_AUD_DEF_SAMPLE_RATE_44100; - case 32000: return RPC_AUD_DEF_SAMPLE_RATE_32000; - case 24000: return RPC_AUD_DEF_SAMPLE_RATE_24000; - case 22050: return RPC_AUD_DEF_SAMPLE_RATE_22050; - case 16000: return RPC_AUD_DEF_SAMPLE_RATE_16000; - case 12000: return RPC_AUD_DEF_SAMPLE_RATE_12000; - case 11025: return RPC_AUD_DEF_SAMPLE_RATE_11025; - case 8000: return RPC_AUD_DEF_SAMPLE_RATE_8000; - default: return RPC_AUD_DEF_SAMPLE_RATE_11025; - } -} - -static unsigned convert_samp_index(unsigned index) -{ - switch (index) { - case RPC_AUD_DEF_SAMPLE_RATE_48000: return 48000; - case RPC_AUD_DEF_SAMPLE_RATE_44100: return 44100; - case RPC_AUD_DEF_SAMPLE_RATE_32000: return 32000; - case RPC_AUD_DEF_SAMPLE_RATE_24000: return 24000; - case RPC_AUD_DEF_SAMPLE_RATE_22050: return 22050; - case RPC_AUD_DEF_SAMPLE_RATE_16000: return 16000; - case RPC_AUD_DEF_SAMPLE_RATE_12000: return 12000; - case RPC_AUD_DEF_SAMPLE_RATE_11025: return 11025; - case RPC_AUD_DEF_SAMPLE_RATE_8000: return 8000; - default: return 11025; - } -} - -/* Convert Bit Rate to Record Quality field of DSP */ -static unsigned int bitrate_to_record_quality(unsigned int sample_rate, - unsigned int channel, unsigned int bit_rate) { - unsigned int temp; - - temp = sample_rate * channel; - MM_DBG(" sample rate * channel = %d\n", temp); - /* To represent in Q12 fixed format */ - temp = (bit_rate * 4096) / temp; - MM_DBG(" Record Quality = 0x%8x\n", temp); - return temp; -} - -/* must be called with audio->lock held */ -static int audaac_in_enable(struct audio_aac_in *audio) -{ - struct audmgr_config cfg; - int rc; - - if (audio->enabled) - return 0; - - cfg.tx_rate = audio->samp_rate; - cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; - cfg.def_method = RPC_AUD_DEF_METHOD_RECORD; - cfg.codec = RPC_AUD_DEF_CODEC_AAC; - cfg.snd_method = RPC_SND_METHOD_MIDI; - - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - rc = audmgr_enable(&audio->audmgr, &cfg); - if (rc < 0) - return rc; - - if (msm_adsp_enable(audio->audpre)) { - audmgr_disable(&audio->audmgr); - MM_ERR("msm_adsp_enable(audpre) failed\n"); - return -ENODEV; - } - } - if (msm_adsp_enable(audio->audrec)) { - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - audmgr_disable(&audio->audmgr); - msm_adsp_disable(audio->audpre); - } - MM_ERR("msm_adsp_enable(audrec) failed\n"); - return -ENODEV; - } - - audio->enabled = 1; - audaac_in_dsp_enable(audio, 1); - - return 0; -} - -/* must be called with audio->lock held */ -static int audaac_in_disable(struct audio_aac_in *audio) -{ - if (audio->enabled) { - audio->enabled = 0; - - audaac_in_dsp_enable(audio, 0); - - wait_event_interruptible_timeout(audio->wait_enable, - audio->running == 0, 1*HZ); - audio->stopped = 1; - wake_up(&audio->wait); - msm_adsp_disable(audio->audrec); - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - msm_adsp_disable(audio->audpre); - audmgr_disable(&audio->audmgr); - } - } - return 0; -} - -/* ------------------- dsp --------------------- */ -static void audpre_dsp_event(void *data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - uint16_t msg[2]; - getevent(msg, sizeof(msg)); - - switch (id) { - case AUDPREPROC_MSG_CMD_CFG_DONE_MSG: - MM_DBG("type %d, status_flag %d\n", msg[0], msg[1]); - break; - case AUDPREPROC_MSG_ERROR_MSG_ID: - MM_ERR("err_index %d\n", msg[0]); - break; - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audpreproctask)\n"); - break; - default: - MM_ERR("unknown event %d\n", id); - } -} - - -static void audaac_in_get_dsp_frames(struct audio_aac_in *audio) -{ - struct audio_frame *frame; - uint32_t index; - unsigned long flags; - - index = audio->in_head; - - frame = (void *) (((char *)audio->in[index].data) - - sizeof(*frame)); - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->in[index].size = frame->frame_length; - - /* statistics of read */ - atomic_add(audio->in[index].size, &audio->in_bytes); - atomic_add(1, &audio->in_samples); - - audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1); - - /* If overflow, move the tail index foward. */ - if (audio->in_head == audio->in_tail) { - MM_ERR("Error! not able to keep up the read\n"); - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - MM_ERR("in_count = %d\n", audio->in_count); - } else - audio->in_count++; - - audaac_in_dsp_read_buffer(audio, audio->dsp_cnt++); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - - wake_up(&audio->wait); -} - -static void audaac_nt_in_get_dsp_frames(struct audio_aac_in *audio) -{ - struct audio_frame_nt *nt_frame; - uint32_t index; - unsigned long flags; - - index = audio->in_head; - nt_frame = (void *) (((char *)audio->in[index].data) - \ - sizeof(struct audio_frame_nt)); - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->in[index].size = nt_frame->frame_length; - /* statistics of read */ - atomic_add(audio->in[index].size, &audio->in_bytes); - atomic_add(1, &audio->in_samples); - - audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1); - - /* If overflow, move the tail index foward. */ - if (audio->in_head == audio->in_tail) - MM_DBG("Error! not able to keep up the read\n"); - else - audio->in_count++; - - spin_unlock_irqrestore(&audio->dsp_lock, flags); - wake_up(&audio->wait); -} - -static int audrec_pcm_buffer_ptr_refresh(struct audio_aac_in *audio, - unsigned idx, unsigned len) -{ - struct audrec_cmd_pcm_buffer_ptr_refresh_arm_enc cmd; - - if (len == NT_FRAME_HEADER_SIZE) - len = len / 2; - else - len = (len + NT_FRAME_HEADER_SIZE) / 2; - MM_DBG("len = %d\n", len); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_PCM_BUFFER_PTR_REFRESH_ARM_TO_ENC; - cmd.num_buffers = 1; - if (cmd.num_buffers == 1) { - cmd.buf_address_length[0] = (audio->out[idx].addr & - 0xffff0000) >> 16; - cmd.buf_address_length[1] = (audio->out[idx].addr & - 0x0000ffff); - cmd.buf_address_length[2] = (len & 0xffff0000) >> 16; - cmd.buf_address_length[3] = (len & 0x0000ffff); - } - audio->out_frame_cnt++; - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audpcm_config(struct audio_aac_in *audio) -{ - struct audrec_cmd_pcm_cfg_arm_to_enc cmd; - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_PCM_CFG_ARM_TO_ENC; - cmd.config_update_flag = AUDREC_PCM_CONFIG_UPDATE_FLAG_ENABLE; - cmd.enable_flag = AUDREC_ENABLE_FLAG_VALUE; - cmd.sampling_freq = convert_samp_index(audio->samp_rate); - if (!audio->channel_mode) - cmd.channels = 1; - else - cmd.channels = 2; - cmd.frequency_of_intimation = 1; - cmd.max_number_of_buffers = OUT_FRAME_NUM; - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audaac_in_routing_mode_config(struct audio_aac_in *audio) -{ - struct audrec_cmd_routing_mode cmd; - - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_ROUTING_MODE; - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) - cmd.routing_mode = 1; - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static void audrec_dsp_event(void *data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - struct audio_aac_in *audio = NULL; - if (data) - audio = data; - else { - MM_ERR("invalid data for event %x\n", id); - return; - } - - switch (id) { - case AUDREC_MSG_CMD_CFG_DONE_MSG: { - struct audrec_msg_cmd_cfg_done_msg cmd_cfg_done_msg; - getevent(&cmd_cfg_done_msg, AUDREC_MSG_CMD_CFG_DONE_MSG_LEN); - if (cmd_cfg_done_msg.audrec_enc_type & \ - AUDREC_MSG_CFG_DONE_ENC_ENA) { - audio->audrec_obj_idx = cmd_cfg_done_msg.audrec_obj_idx; - MM_DBG("CFG ENABLED\n"); - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) { - MM_DBG("routing command\n"); - audaac_in_routing_mode_config(audio); - } else { - audaac_in_encmem_config(audio); - } - } else { - MM_DBG("CFG SLEEP\n"); - audio->running = 0; - wake_up(&audio->wait_enable); - } - break; - } - case AUDREC_MSG_CMD_ROUTING_MODE_DONE_MSG: { - struct audrec_msg_cmd_routing_mode_done_msg \ - routing_msg; - getevent(&routing_msg, AUDREC_MSG_CMD_ROUTING_MODE_DONE_MSG); - MM_DBG("AUDREC_MSG_CMD_ROUTING_MODE_DONE_MSG"); - if (routing_msg.configuration == 0) { - MM_ERR("routing configuration failed\n"); - audio->running = 0; - wake_up(&audio->wait_enable); - } else - audaac_in_encmem_config(audio); - break; - } - case AUDREC_MSG_CMD_AREC_MEM_CFG_DONE_MSG: { - MM_DBG("AREC_MEM_CFG_DONE_MSG\n"); - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - audaac_in_encparam_config(audio); - else - audpcm_config(audio); - break; - } - case AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG: { - MM_DBG("AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG"); - audaac_in_encparam_config(audio); - break; - } - case AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG: { - MM_DBG("AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG\n"); - audio->running = 1; - wake_up(&audio->wait_enable); - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) - audrec_pcm_send_data(audio, 1); - break; - } - case AUDREC_CMD_PCM_BUFFER_PTR_UPDATE_ARM_TO_ENC_MSG: { - MM_DBG("ptr_update recieved from DSP\n"); - audrec_pcm_send_data(audio, 1); - break; - } - case AUDREC_MSG_NO_EXT_PKT_AVAILABLE_MSG: { - struct audrec_msg_no_ext_pkt_avail_msg err_msg; - getevent(&err_msg, AUDREC_MSG_NO_EXT_PKT_AVAILABLE_MSG_LEN); - MM_DBG("NO_EXT_PKT_AVAILABLE_MSG %x\n",\ - err_msg.audrec_err_id); - break; - } - case AUDREC_MSG_PACKET_READY_MSG: { - struct audrec_msg_packet_ready_msg pkt_ready_msg; - - getevent(&pkt_ready_msg, AUDREC_MSG_PACKET_READY_MSG_LEN); - MM_DBG("UP_PACKET_READY_MSG: write cnt msw %d \ - write cnt lsw %d read cnt msw %d read cnt lsw %d \n",\ - pkt_ready_msg.pkt_counter_msw, \ - pkt_ready_msg.pkt_counter_lsw, \ - pkt_ready_msg.pkt_read_cnt_msw, \ - pkt_ready_msg.pkt_read_cnt_lsw); - - audaac_in_get_dsp_frames(audio); - break; - } - case AUDREC_UP_NT_PACKET_READY_MSG: { - struct audrec_up_nt_packet_ready_msg pkt_ready_msg; - - getevent(&pkt_ready_msg, AUDREC_UP_NT_PACKET_READY_MSG_LEN); - MM_DBG("UP_NT_PACKET_READY_MSG: write cnt lsw %d \ - write cnt msw %d read cnt lsw %d read cnt msw %d \n",\ - pkt_ready_msg.audrec_packetwrite_cnt_lsw, \ - pkt_ready_msg.audrec_packetwrite_cnt_msw, \ - pkt_ready_msg.audrec_upprev_readcount_lsw, \ - pkt_ready_msg.audrec_upprev_readcount_msw); - - audaac_nt_in_get_dsp_frames(audio); - break; - } - case AUDREC_CMD_FLUSH_DONE_MSG: { - audio->wflush = 0; - audio->rflush = 0; - audio->flush_ack = 1; - wake_up(&audio->write_wait); - MM_DBG("flush ack recieved\n"); - break; - } - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module \ - enable/disable(audrectask)\n"); - break; - default: - MM_ERR("unknown event %d\n", id); - } -} - -struct msm_adsp_ops audpre_aac_adsp_ops = { - .event = audpre_dsp_event, -}; - -struct msm_adsp_ops audrec_aac_adsp_ops = { - .event = audrec_dsp_event, -}; - -static int audaac_in_dsp_enable(struct audio_aac_in *audio, int enable) -{ - struct audrec_cmd_enc_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_ENC_CFG; - cmd.audrec_enc_type = (audio->enc_type & 0xFF) | - (enable ? AUDREC_CMD_ENC_ENA : AUDREC_CMD_ENC_DIS); - /* Don't care */ - cmd.audrec_obj_idx = audio->audrec_obj_idx; - - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audaac_in_encmem_config(struct audio_aac_in *audio) -{ - struct audrec_cmd_arecmem_cfg cmd; - uint16_t *data = (void *) audio->data; - int n; - int header_len = 0; - - memset(&cmd, 0, sizeof(cmd)); - - cmd.cmd_id = AUDREC_CMD_ARECMEM_CFG; - cmd.audrec_obj_idx = audio->audrec_obj_idx; - /* Rate at which packet complete message comes */ - cmd.audrec_up_pkt_intm_cnt = 1; - cmd.audrec_extpkt_buffer_msw = audio->phys >> 16; - cmd.audrec_extpkt_buffer_lsw = audio->phys; - /* Max Buffer no available for frames */ - cmd.audrec_extpkt_buffer_num = FRAME_NUM; - - /* prepare buffer pointers: - * T:1536 bytes aac packet + 4 halfword header - * NT:1536 bytes aac packet + 12 halfword header - */ - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - header_len = FRAME_HEADER_SIZE/2; - else - header_len = NT_FRAME_HEADER_SIZE/2; - - for (n = 0; n < FRAME_NUM; n++) { - audio->in[n].data = data + header_len; - data += (AAC_FRAME_SIZE/2) + header_len; - MM_DBG("0x%8x\n", (int)(audio->in[n].data - header_len*2)); - } - - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audaac_in_encparam_config(struct audio_aac_in *audio) -{ - struct audrec_cmd_arecparam_aac_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDREC_CMD_ARECPARAM_CFG; - cmd.common.audrec_obj_idx = audio->audrec_obj_idx; - cmd.samp_rate_idx = audio->samp_rate_index; - cmd.stereo_mode = audio->channel_mode; - cmd.rec_quality = audio->record_quality; - - - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audaac_flush_command(struct audio_aac_in *audio) -{ - struct audrec_cmd_flush cmd; - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_FLUSH; - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audaac_in_dsp_read_buffer(struct audio_aac_in *audio, - uint32_t read_cnt) -{ - audrec_cmd_packet_ext_ptr cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_PACKET_EXT_PTR; - cmd.type = audio->audrec_obj_idx; - cmd.curr_rec_count_msw = read_cnt >> 16; - cmd.curr_rec_count_lsw = read_cnt; - - return audio_send_queue_recbs(audio, &cmd, sizeof(cmd)); -} - -/* ------------------- device --------------------- */ - -static void audaac_ioport_reset(struct audio_aac_in *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->wait); - mutex_lock(&audio->read_lock); - audaac_in_flush(audio); - mutex_unlock(&audio->read_lock); - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audaac_out_flush(audio); - mutex_unlock(&audio->write_lock); -} - -static void audaac_in_flush(struct audio_aac_in *audio) -{ - int i; - unsigned long flags; - - audio->dsp_cnt = 0; - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->in_head = 0; - audio->in_tail = 0; - audio->in_count = 0; - audio->eos_ack = 0; - for (i = FRAME_NUM-1; i >= 0; i--) { - audio->in[i].size = 0; - audio->in[i].read = 0; - } - spin_unlock_irqrestore(&audio->dsp_lock, flags); - MM_DBG("in_bytes %d\n", atomic_read(&audio->in_bytes)); - MM_DBG("in_samples %d\n", atomic_read(&audio->in_samples)); - atomic_set(&audio->in_bytes, 0); - atomic_set(&audio->in_samples, 0); -} - -static void audaac_out_flush(struct audio_aac_in *audio) -{ - int i; - unsigned long flags; - - audio->out_head = 0; - audio->out_count = 0; - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->out_tail = 0; - for (i = OUT_FRAME_NUM-1; i >= 0; i--) { - audio->out[i].size = 0; - audio->out[i].read = 0; - audio->out[i].used = 0; - } - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ -static long audaac_in_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct audio_aac_in *audio = file->private_data; - int rc = 0; - - MM_DBG("\n"); - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = atomic_read(&audio->in_bytes); - stats.sample_count = atomic_read(&audio->in_samples); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return rc; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: { - rc = audaac_in_enable(audio); - if (!rc) { - rc = - wait_event_interruptible_timeout(audio->wait_enable, - audio->running != 0, 1*HZ); - MM_DBG("state %d rc = %d\n", audio->running, rc); - - if (audio->running == 0) - rc = -ENODEV; - else - rc = 0; - } - audio->stopped = 0; - break; - } - case AUDIO_STOP: { - rc = audaac_in_disable(audio); - break; - } - case AUDIO_FLUSH: { - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audaac_ioport_reset(audio); - if (audio->running) { - audaac_flush_command(audio); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config cfg; - memset(&cfg, 0, sizeof(cfg)); - cfg.buffer_size = OUT_BUFFER_SIZE; - cfg.buffer_count = OUT_FRAME_NUM; - cfg.sample_rate = convert_samp_index(audio->samp_rate); - cfg.channel_count = 1; - cfg.type = 0; - cfg.unused[0] = 0; - cfg.unused[1] = 0; - cfg.unused[2] = 0; - if (copy_to_user((void *) arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_GET_STREAM_CONFIG: { - struct msm_audio_stream_config cfg; - memset(&cfg, 0, sizeof(cfg)); - cfg.buffer_size = audio->buffer_size; - cfg.buffer_count = FRAME_NUM; - if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_STREAM_CONFIG: { - struct msm_audio_stream_config cfg; - if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - /* Allow only single frame */ - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - if (cfg.buffer_size != (FRAME_SIZE - 8)) - rc = -EINVAL; - break; - } else { - if (cfg.buffer_size != (AAC_FRAME_SIZE + 14)) - rc = -EINVAL; - break; - } - audio->buffer_size = cfg.buffer_size; - break; - } - case AUDIO_GET_AAC_ENC_CONFIG: { - struct msm_audio_aac_enc_config cfg; - if (audio->channel_mode == AUDREC_CMD_STEREO_MODE_MONO) - cfg.channels = 1; - else - cfg.channels = 2; - cfg.sample_rate = convert_samp_index(audio->samp_rate); - cfg.bit_rate = audio->bit_rate; - cfg.stream_format = AUDIO_AAC_FORMAT_RAW; - if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - break; - } - case AUDIO_SET_AAC_ENC_CONFIG: { - struct msm_audio_aac_enc_config cfg; - unsigned int record_quality; - if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - if (cfg.stream_format != AUDIO_AAC_FORMAT_RAW) { - MM_ERR("unsupported AAC format\n"); - rc = -EINVAL; - break; - } - record_quality = bitrate_to_record_quality(cfg.sample_rate, - cfg.channels, cfg.bit_rate); - /* Range of Record Quality Supported by DSP, Q12 format */ - if ((record_quality < 0x800) || (record_quality > 0x4000)) { - MM_ERR("Unsupported bit rate\n"); - rc = -EINVAL; - break; - } - MM_DBG("channels = %d\n", cfg.channels); - if (cfg.channels == 1) { - cfg.channels = AUDREC_CMD_STEREO_MODE_MONO; - } else if (cfg.channels == 2) { - cfg.channels = AUDREC_CMD_STEREO_MODE_STEREO; - } else { - rc = -EINVAL; - break; - } - - audio->samp_rate = convert_samp_rate(cfg.sample_rate); - audio->samp_rate_index = - convert_dsp_samp_index(cfg.sample_rate); - audio->channel_mode = cfg.channels; - audio->bit_rate = cfg.bit_rate; - audio->record_quality = record_quality; - MM_DBG(" Record Quality = 0x%8x\n", audio->record_quality); - break; - } - - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -static ssize_t audaac_in_read(struct file *file, - char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_aac_in *audio = file->private_data; - unsigned long flags; - const char __user *start = buf; - void *data; - uint32_t index; - uint32_t size; - int rc = 0; - struct aac_encoded_meta_out meta_field; - struct audio_frame_nt *nt_frame; - MM_DBG("count = %d\n", count); - mutex_lock(&audio->read_lock); - while (count > 0) { - rc = wait_event_interruptible( - audio->wait, (audio->in_count > 0) || audio->stopped || - audio->rflush); - if (rc < 0) - break; - - if (audio->rflush) { - rc = -EBUSY; - break; - } - if (audio->stopped && !audio->in_count) { - MM_DBG("Driver in stop state, No more buffer to read"); - rc = 0;/* End of File */ - break; - } - - index = audio->in_tail; - data = (uint8_t *) audio->in[index].data; - size = audio->in[index].size; - - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) { - nt_frame = (struct audio_frame_nt *)(data - - sizeof(struct audio_frame_nt)); - memcpy((char *)&meta_field.time_stamp_dword_lsw, - (char *)&nt_frame->time_stamp_dword_lsw, - (sizeof(struct aac_encoded_meta_out) - \ - sizeof(uint16_t))); - meta_field.metadata_len = - sizeof(struct aac_encoded_meta_out); - if (copy_to_user((char *)start, (char *)&meta_field, - sizeof(struct aac_encoded_meta_out))) { - rc = -EFAULT; - break; - } - if (nt_frame->nflag_lsw & 0x0001) { - MM_DBG("recieved EOS in read call\n"); - audio->eos_ack = 1; - } - buf += sizeof(struct aac_encoded_meta_out); - count -= sizeof(struct aac_encoded_meta_out); - } - if (count >= size) { - /* order the reads on the buffer */ - dma_coherent_post_ops(); - if (copy_to_user(buf, data, size)) { - rc = -EFAULT; - break; - } - spin_lock_irqsave(&audio->dsp_lock, flags); - if (index != audio->in_tail) { - /* overrun -- data is - * invalid and we need to retry */ - spin_unlock_irqrestore(&audio->dsp_lock, flags); - continue; - } - audio->in[index].size = 0; - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - audio->in_count--; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - count -= size; - buf += size; - if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL)) { - if (!audio->eos_ack) { - MM_DBG("sending read ptr command \ - %d %d\n", - audio->dsp_cnt, - audio->in_tail); - audaac_in_dsp_read_buffer(audio, - audio->dsp_cnt++); - } - } - } else { - MM_ERR("short read\n"); - break; - } - break; - } - mutex_unlock(&audio->read_lock); - - if (buf > start) - return buf - start; - - return rc; -} - -static void audrec_pcm_send_data(struct audio_aac_in *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - MM_DBG("\n"); - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - audrec_pcm_buffer_ptr_refresh(audio, - audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } - done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - - -static int audaac_in_fsync(struct file *file, loff_t a, loff_t b, int datasync) - -{ - struct audio_aac_in *audio = file->private_data; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - if (!audio->running || (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - audio->wflush); - MM_DBG("waked on by some event audio->wflush = %d\n", audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; - -} - -int audrec_aac_process_eos(struct audio_aac_in *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - struct buffer *frame; - int rc = 0; - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - MM_DBG("copying meta_out frame->used = %d\n", frame->used); - audrec_pcm_send_data(audio, 0); -done: - return rc; -} -static ssize_t audaac_in_write(struct file *file, - const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_aac_in *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - char *cpy_ptr; - int rc = 0, eos_condition = AUDPREPROC_AAC_EOS_NONE; - unsigned short mfield_size = 0; - int write_count = 0; - MM_DBG("cnt=%d\n", count); - - if (count & 1) - return -EINVAL; - - if (audio->mode != MSM_AUD_ENC_MODE_NONTUNNEL) - return -EINVAL; - - mutex_lock(&audio->write_lock); - frame = audio->out + audio->out_head; - /* if supplied count is more than driver buffer size - * then only copy driver buffer size - */ - if (count > frame->size) - count = frame->size; - - write_count = count; - cpy_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - goto error; - - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto error; - } - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - goto error; - } else if (mfield_size > count) { - rc = -EINVAL; - goto error; - } - MM_DBG("mf offset_val %x\n", mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - goto error; - } - /* Check if EOS flag is set and buffer has - * contains just meta field - */ - if (cpy_ptr[AUDPREPROC_AAC_EOS_FLG_OFFSET] & - AUDPREPROC_AAC_EOS_FLG_MASK) { - eos_condition = AUDPREPROC_AAC_EOS_SET; - MM_DBG("EOS SET\n"); - if (mfield_size == count) { - buf += mfield_size; - eos_condition = 0; - goto exit; - } else - cpy_ptr[AUDPREPROC_AAC_EOS_FLG_OFFSET] &= - ~AUDPREPROC_AAC_EOS_FLG_MASK; - } - cpy_ptr += mfield_size; - count -= mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - MM_DBG("copying the stream count = %d\n", count); - if (copy_from_user(cpy_ptr, buf, count)) { - rc = -EFAULT; - goto error; - } -exit: - frame->used = count; - audio->out_head ^= 1; - if (!audio->flush_ack) - audrec_pcm_send_data(audio, 0); - else { - audrec_pcm_send_data(audio, 1); - audio->flush_ack = 0; - } - if (eos_condition == AUDPREPROC_AAC_EOS_SET) - rc = audrec_aac_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - return write_count; -error: - mutex_unlock(&audio->write_lock); - return rc; -} - -static int audaac_in_release(struct inode *inode, struct file *file) -{ - struct audio_aac_in *audio = file->private_data; - - mutex_lock(&audio->lock); - audaac_in_disable(audio); - audaac_in_flush(audio); - msm_adsp_put(audio->audrec); - - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - msm_adsp_put(audio->audpre); - - audpreproc_aenc_free(audio->enc_id); - audio->audrec = NULL; - audio->audpre = NULL; - audio->opened = 0; - - if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) && \ - (audio->out_data)) { - ion_unmap_kernel(audio->client, audio->input_buff_handle); - ion_free(audio->client, audio->input_buff_handle); - audio->out_data = NULL; - } - - if (audio->data) { - ion_unmap_kernel(audio->client, audio->output_buff_handle); - ion_free(audio->client, audio->output_buff_handle); - audio->data = NULL; - } - ion_client_destroy(audio->client); - mutex_unlock(&audio->lock); - return 0; -} - -struct audio_aac_in the_audio_aac_in; - -static int audaac_in_open(struct inode *inode, struct file *file) -{ - struct audio_aac_in *audio = &the_audio_aac_in; - int rc; - int encid; - int dma_size = 0; - int len = 0; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - struct ion_client *client = NULL; - - mutex_lock(&audio->lock); - if (audio->opened) { - rc = -EBUSY; - goto done; - } - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - audio->mode = MSM_AUD_ENC_MODE_NONTUNNEL; - dma_size = NT_DMASZ; - MM_DBG("Opened for non tunnel mode encoding\n"); - } else if (!(file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - audio->mode = MSM_AUD_ENC_MODE_TUNNEL; - dma_size = DMASZ; - MM_DBG("Opened for tunnel mode encoding\n"); - } else { - MM_ERR("Invalid mode\n"); - rc = -EACCES; - goto done; - } - - /* Settings will be re-config at AUDIO_SET_CONFIG, - * but at least we need to have initial config - */ - audio->samp_rate = RPC_AUD_DEF_SAMPLE_RATE_11025; - audio->samp_rate_index = AUDREC_CMD_SAMP_RATE_INDX_11025; - - /* For AAC, bit rate hard coded, default settings is - * sample rate (11025) x channel count (1) x recording quality (1.75) - * = 19293 bps */ - audio->bit_rate = 19293; - audio->record_quality = 0x1c00; - - audio->channel_mode = AUDREC_CMD_STEREO_MODE_MONO; - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) - audio->buffer_size = (AAC_FRAME_SIZE + 14); - else - audio->buffer_size = (FRAME_SIZE - 8); - audio->enc_type = AUDREC_CMD_TYPE_0_INDEX_AAC | audio->mode; - - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - rc = audmgr_open(&audio->audmgr); - if (rc) - goto done; - } - - encid = audpreproc_aenc_alloc(audio->enc_type, &audio->module_name, - &audio->queue_ids); - if (encid < 0) { - MM_ERR("No free encoder available\n"); - rc = -ENODEV; - goto done; - } - audio->enc_id = encid; - - rc = msm_adsp_get(audio->module_name, &audio->audrec, - &audrec_aac_adsp_ops, audio); - if (rc) { - audpreproc_aenc_free(audio->enc_id); - goto done; - } - - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre, - &audpre_aac_adsp_ops, audio); - if (rc) { - msm_adsp_put(audio->audrec); - audpreproc_aenc_free(audio->enc_id); - goto done; - } - } - - audio->dsp_cnt = 0; - audio->stopped = 0; - audio->wflush = 0; - audio->rflush = 0; - audio->flush_ack = 0; - - audaac_in_flush(audio); - audaac_out_flush(audio); - - - client = msm_ion_client_create(UINT_MAX, "Audio_AAC_in_client"); - if (IS_ERR_OR_NULL(client)) { - MM_ERR("Unable to create ION client\n"); - rc = -ENOMEM; - goto client_create_error; - } - audio->client = client; - - MM_DBG("allocating mem sz = %d\n", dma_size); - handle = ion_alloc(client, dma_size, SZ_4K, - ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to create allocate O/P buffers\n"); - rc = -ENOMEM; - goto output_buff_alloc_error; - } - - audio->output_buff_handle = handle; - - rc = ion_phys(client , handle, &addr, &len); - if (rc) { - MM_ERR("O/P buffers:Invalid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - rc = -ENOMEM; - goto output_buff_get_phys_error; - } else { - MM_INFO("O/P buffers:valid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - } - audio->phys = (int32_t)addr; - - rc = ion_handle_get_flags(client, handle, &ionflag); - if (rc) { - MM_ERR("could not get flags for the handle\n"); - rc = -ENOMEM; - goto output_buff_get_flags_error; - } - - audio->map_v_read = ion_map_kernel(client, handle); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("could not map read buffers,freeing instance 0x%08x\n", - (int)audio); - rc = -ENOMEM; - goto output_buff_map_error; - } - audio->data = audio->map_v_read; - MM_DBG("read buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->phys, (int)audio->data); - - audio->out_data = NULL; - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) { - - MM_DBG("allocating BUFFER_SIZE %d\n", BUFFER_SIZE); - handle = ion_alloc(client, BUFFER_SIZE, - SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to create allocate I/P buffers\n"); - rc = -ENOMEM; - goto input_buff_alloc_error; - } - - audio->input_buff_handle = handle; - - rc = ion_phys(client , handle, &addr, &len); - if (rc) { - MM_ERR("I/P buffers:Invalid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - rc = -ENOMEM; - goto input_buff_get_phys_error; - } else { - MM_INFO("Got valid phy: %x sz: %x\n", - (unsigned int) addr, - (unsigned int) len); - } - audio->out_phys = (int32_t)addr; - - rc = ion_handle_get_flags(client, - handle, &ionflag); - if (rc) { - MM_ERR("could not get flags for the handle\n"); - rc = -ENOMEM; - goto input_buff_get_flags_error; - } - - audio->map_v_write = ion_map_kernel(client, handle); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write buffers\n"); - rc = -ENOMEM; - goto input_buff_map_error; - } - audio->out_data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n", - (unsigned int)addr, - (unsigned int)audio->out_data); - - /* Initialize buffer */ - audio->out[0].data = audio->out_data + 0; - audio->out[0].addr = audio->out_phys + 0; - audio->out[0].size = OUT_BUFFER_SIZE; - - audio->out[1].data = audio->out_data + OUT_BUFFER_SIZE; - audio->out[1].addr = audio->out_phys + OUT_BUFFER_SIZE; - audio->out[1].size = OUT_BUFFER_SIZE; - - MM_DBG("audio->out[0].data = %d audio->out[1].data = %d", - (unsigned int)audio->out[0].data, - (unsigned int)audio->out[1].data); - audio->mfield = NT_FRAME_HEADER_SIZE; - audio->out_frame_cnt++; - } - file->private_data = audio; - audio->opened = 1; - -done: - mutex_unlock(&audio->lock); - return rc; -input_buff_map_error: -input_buff_get_flags_error: -input_buff_get_phys_error: - ion_free(client, audio->input_buff_handle); -input_buff_alloc_error: - ion_unmap_kernel(client, audio->output_buff_handle); -output_buff_map_error: -output_buff_get_phys_error: -output_buff_get_flags_error: - ion_free(client, audio->output_buff_handle); -output_buff_alloc_error: - ion_client_destroy(client); -client_create_error: - msm_adsp_put(audio->audrec); - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - msm_adsp_put(audio->audpre); - - audpreproc_aenc_free(audio->enc_id); - mutex_unlock(&audio->lock); - return rc; -} - -static const struct file_operations audio_aac_in_fops = { - .owner = THIS_MODULE, - .open = audaac_in_open, - .release = audaac_in_release, - .read = audaac_in_read, - .write = audaac_in_write, - .fsync = audaac_in_fsync, - .unlocked_ioctl = audaac_in_ioctl, -}; - -static struct miscdevice audaac_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_aac_in", - .fops = &audio_aac_in_fops, -}; - -static int __init audaac_in_init(void) -{ - mutex_init(&the_audio_aac_in.lock); - mutex_init(&the_audio_aac_in.read_lock); - spin_lock_init(&the_audio_aac_in.dsp_lock); - init_waitqueue_head(&the_audio_aac_in.wait); - init_waitqueue_head(&the_audio_aac_in.wait_enable); - mutex_init(&the_audio_aac_in.write_lock); - init_waitqueue_head(&the_audio_aac_in.write_wait); - return misc_register(&audaac_in_misc); -} -device_initcall(audaac_in_init); diff --git a/arch/arm/mach-msm/qdsp5/audio_ac3.c b/arch/arm/mach-msm/qdsp5/audio_ac3.c deleted file mode 100644 index d93681218a4a94e4d4a280cdbb20301ad1c55d94..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_ac3.c +++ /dev/null @@ -1,1752 +0,0 @@ -/* arch/arm/mach-msm/audio_ac3.c - * - * Copyright (c) 2008-2009, 2011-2012 The Linux Foundation. All rights reserved. - * - * This code also borrows from audio_aac.c, which is - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "audmgr.h" - -#define BUFSZ 4096 -#define DMASZ (BUFSZ * 2) - -#define AUDDEC_DEC_AC3 23 - -#define PCM_BUFSZ 6168 /* maximum frame size is 512 * 6 samples */ -#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most - * but support 2 buffers currently - */ -#define ROUTING_MODE_FTRT 1 -#define ROUTING_MODE_RT 2 - -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDAC3_METAFIELD_MASK 0xFFFF0000 -#define AUDAC3_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */ -#define AUDAC3_EOS_FLG_MASK 0x01 -#define AUDAC3_EOS_NONE 0x0 /* No EOS detected */ -#define AUDAC3_EOS_SET 0x1 /* EOS set in meta field */ - -#define AUDAC3_EVENT_NUM 10 /* Default number of pre-allocated event packets */ - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; - unsigned short mfield_sz; /* only useful for data has meta field */ -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audac3_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct audac3_event { - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audio { - struct buffer out[2]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - /* Host PCM section */ - struct buffer in[PCM_BUF_MAX_COUNT]; - struct mutex read_lock; - wait_queue_head_t read_wait; /* Wait queue for read */ - char *read_data; /* pointer to reader buffer */ - int32_t read_phys; /* physical address of reader buffer */ - uint8_t read_next; /* index to input buffers to be read next */ - uint8_t fill_next; /* index to buffer that DSP should be filling */ - uint8_t pcm_buf_count; /* number of pcm buffer allocated */ - /* ---- End of Host PCM section */ - - struct msm_adsp_module *audplay; - struct audmgr audmgr; - struct msm_audio_ac3_config ac3_config; - - /* data allocated for various buffers */ - char *data; - int32_t phys; /* physical address of write buffer */ - void *map_v_read; - void *map_v_write; - - int mfield; /* meta field embedded in data */ - int rflush; /* Read flush */ - int wflush; /* Write flush */ - uint8_t opened; - uint8_t enabled; - uint8_t running; - uint8_t stopped; /* set when stopped, cleared on flush */ - uint8_t pcm_feedback; - uint8_t buf_refresh; - int teos; /* valid only if tunnel mode & no data left for decoder */ - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - int rmt_resource_released; - - const char *module_name; - unsigned queue_id; - uint16_t dec_id; - uint32_t read_ptr_offset; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audac3_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - - int eq_enable; - int eq_needs_commit; - audpp_cmd_cfg_object_params_eqalizer eq; - audpp_cmd_cfg_object_params_volume vol_pan; - struct ion_client *client; - struct ion_handle *input_buff_handle; - struct ion_handle *output_buff_handle; -}; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audpp_cmd_cfg_adec_params(struct audio *audio); -static void audpp_cmd_cfg_routing_mode(struct audio *audio); -static void audac3_send_data(struct audio *audio, unsigned needed); -static void audac3_dsp_event(void *private, unsigned id, uint16_t *msg); -static void audac3_config_hostpcm(struct audio *audio); -static void audac3_buffer_refresh(struct audio *audio); -static void audac3_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); - -static int rmt_put_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_DISABLE; - cmd.dec_type = AUDDEC_DEC_AC3; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - - return put_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -static int rmt_get_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_ENABLE; - cmd.dec_type = AUDDEC_DEC_AC3; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - return get_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -/* must be called with audio->lock held */ -static int audac3_enable(struct audio *audio) -{ - struct audmgr_config cfg; - int rc; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (audio->enabled) - return 0; - - if (audio->rmt_resource_released == 1) { - audio->rmt_resource_released = 0; - rc = rmt_get_resource(audio); - if (rc) { - MM_ERR("ADSP resources are not available for AC3"\ - " session 0x%08x on decoder: %d\n Ignoring"\ - " error and going ahead with the playback\n", - (int)audio, audio->dec_id); - } - } - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_tail = 0; - audio->out_needed = 0; - - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) { - cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; - cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000; - cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK; - cfg.codec = RPC_AUD_DEF_CODEC_AC3; - cfg.snd_method = RPC_SND_METHOD_MIDI; - - rc = audmgr_enable(&audio->audmgr, &cfg); - if (rc < 0) - return rc; - } - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audac3_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - audio->enabled = 1; - return 0; -} - -/* must be called with audio->lock held */ -static int audac3_disable(struct audio *audio) -{ - int rc = 0; - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - audio->stopped = 1; - wake_up(&audio->write_wait); - wake_up(&audio->read_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - audio->out_needed = 0; - rmt_put_resource(audio); - audio->rmt_resource_released = 1; - } - return rc; -} - -/* ------------------- dsp --------------------- */ - -static void audac3_update_pcm_buf_entry(struct audio *audio, - uint32_t *payload) -{ - uint8_t index; - unsigned long flags; - - if (audio->rflush) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < payload[1]; index++) { - if (audio->in[audio->fill_next].addr - == payload[2 + index * 2]) { - MM_DBG("in[%d] ready\n", audio->fill_next); - audio->in[audio->fill_next].used = - payload[3 + index * 2]; - if ((++audio->fill_next) == audio->pcm_buf_count) - audio->fill_next = 0; - - } else { - MM_ERR("expected=%x ret=%x\n", - audio->in[audio->fill_next].addr, - payload[1 + index * 2]); - break; - } - } - if (audio->in[audio->fill_next].used == 0) { - audac3_buffer_refresh(audio); - } else { - MM_DBG("read cannot keep up\n"); - audio->buf_refresh = 1; - } - wake_up(&audio->read_wait); - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - getevent(msg, sizeof(msg)); - - MM_DBG("msg_id=%x\n", id); - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audac3_send_data(audio, 1); - break; - case AUDPLAY_MSG_BUFFER_UPDATE: - MM_DBG("\n"); /* Macro prints the file name and function */ - audac3_update_pcm_buf_entry(audio, msg); - break; - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audplaytask)\n"); - break; - default: - MM_ERR("unexpected message from decoder\n"); - } -} - -static void audac3_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status:sleep reason =0x%04x\n", - reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init\n"); - if (audio->pcm_feedback) - audpp_cmd_cfg_routing_mode(audio); - else - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg\n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play\n"); - if (audio->pcm_feedback) { - audac3_config_hostpcm(audio); - audac3_buffer_refresh(audio); - } - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - default: - MM_ERR("unknown decoder status\n"); - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - audpp_dsp_set_eq(audio->dec_id, audio->eq_enable, - &audio->eq); - audpp_avsync(audio->dec_id, 22050); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audpp_avsync(audio->dec_id, 0); - audio->running = 0; - } else { - MM_DBG("CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_ROUTING_ACK: - MM_DBG("ROUTING_ACK\n"); - audpp_cmd_cfg_adec_params(audio); - break; - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - audio->rflush = 0; - wake_up(&audio->write_wait); - if (audio->pcm_feedback) - audac3_buffer_refresh(audio); - break; - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - default: - MM_ERR("UNKNOWN (%d)\n", id); - } - -} - -struct msm_adsp_ops audplay_adsp_ops_ac3 = { - .event = audplay_dsp_event, -}; - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id, \ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - u16 cfg_dec_cmd[AUDPP_CMD_CFG_DEC_TYPE_LEN / sizeof(unsigned short)]; - - memset(cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - - cfg_dec_cmd[0] = AUDPP_CMD_CFG_DEC_TYPE; - if (enable) - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_AC3; - else - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} -static int get_frequency_index(unsigned short frequency) -{ - switch (frequency) { - case 48000: return 0; - case 44100: return 1; - case 32000: return 2; - default: return -EINVAL; - } -} -static void audpp_cmd_cfg_adec_params(struct audio *audio) -{ - struct audpp_cmd_cfg_adec_params_ac3 cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - /* dsp needs word size */ - cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_AC3_LEN >> 1; - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = (audio->ac3_config).fsCod; - - cmd.index[0] = (((audio->ac3_config).numChans << 8) & 0xFF00) | - ((audio->ac3_config).wordSize & 0x00FF); - - cmd.index[1] = (((audio->ac3_config).kCapableMode << 12) & 0xF000) | - (((audio->ac3_config).compMode << 8) & 0x0F00) | - (((audio->ac3_config).outLfeOn << 4) & 0x00F0) | - ((audio->ac3_config).outputMode & 0x000F); - - cmd.index[2] = ((((audio->ac3_config).stereoMode << 12) & 0xF000) | - (((audio->ac3_config).dualMonoMode << 8) & 0x0F00) | - ((get_frequency_index((audio->ac3_config).fsCod) << 4) - & 0x00F0)) & 0xFFF0; /* last 4 bytes are reserved */ - - cmd.index[3] = (audio->ac3_config).pcmScaleFac; - cmd.index[4] = (audio->ac3_config).dynRngScaleHi; - cmd.index[5] = (audio->ac3_config).dynRngScaleLow; - - cmd.index[6] = (((audio->ac3_config).user_downmix_flag << 8) & 0xFF00)| - ((audio->ac3_config).user_karaoke_flag & 0x00FF); - - cmd.index[7] = (audio->ac3_config).dm_address_high; - cmd.index[8] = (audio->ac3_config).dm_address_low; - cmd.index[9] = (audio->ac3_config).ko_address_high; - cmd.index[10] = (audio->ac3_config).ko_address_high; - - cmd.index[11] = (((audio->ac3_config).max_rep_count << 1) & 0xFFFE) | - ((audio->ac3_config).error_concealment & 0x0001); - - cmd.index[12] = (((audio->ac3_config).channel_routing_mode[3] << 12) - & 0xF000) | - (((audio->ac3_config).channel_routing_mode[2] << 8) - & 0x0F00) | - (((audio->ac3_config).channel_routing_mode[1] << 4) - & 0x00F0) | - ((audio->ac3_config).channel_routing_mode[0] & 0x000F); - - cmd.index[13] = ((((audio->ac3_config).channel_routing_mode[5] << 12) - & 0xF000) | - (((audio->ac3_config).channel_routing_mode[4] << 8) - & 0x0F00)) & 0xFF00; /* last 8 bytes are reserved */ - - audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static void audpp_cmd_cfg_routing_mode(struct audio *audio) -{ - struct audpp_cmd_routing_mode cmd; - MM_DBG("\n"); /* Macro prints the file name and function */ - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; - cmd.object_number = audio->dec_id; - if (audio->pcm_feedback) - cmd.routing_mode = ROUTING_MODE_FTRT; - else - cmd.routing_mode = ROUTING_MODE_RT; - - audpp_send_queue1(&cmd, sizeof(cmd)); -} - -static int audplay_dsp_send_data_avail(struct audio *audio, - unsigned idx, unsigned len) -{ - struct audplay_cmd_bitstream_data_avail_nt2 cmd; - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2; - if (audio->mfield) - cmd.decoder_id = AUDAC3_METAFIELD_MASK | - (audio->out[idx].mfield_sz >> 1); - else - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = audio->out[idx].addr; - cmd.buf_size = len / 2; - cmd.partition_number = 0; - /* complete writes to the input buffer */ - wmb(); - return audplay_send_queue0(audio, &cmd, sizeof(cmd)); -} - -static void audac3_buffer_refresh(struct audio *audio) -{ - struct audplay_cmd_buffer_refresh refresh_cmd; - - refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; - refresh_cmd.num_buffers = 1; - refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; - refresh_cmd.buf0_length = audio->in[audio->fill_next].size; - - refresh_cmd.buf_read_count = 0; - MM_DBG("buf0_addr=%x buf0_len=%d\n", refresh_cmd.buf0_address, - refresh_cmd.buf0_length); - (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); -} - -static void audac3_config_hostpcm(struct audio *audio) -{ - struct audplay_cmd_hpcm_buf_cfg cfg_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; - cfg_cmd.max_buffers = 1; - cfg_cmd.byte_swap = 0; - cfg_cmd.hostpcm_config = (0x8000) | (0x4000); - cfg_cmd.feedback_frequency = 1; - cfg_cmd.partition_number = 0; - (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); - -} - -static void audac3_send_data(struct audio *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - MM_DBG("frame %d busy\n", audio->out_tail); - audplay_dsp_send_data_avail(audio, audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } -done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ - -static void audac3_flush(struct audio *audio) -{ - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->out_needed = 0; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - atomic_set(&audio->out_bytes, 0); -} - -static void audac3_flush_pcm_buf(struct audio *audio) -{ - uint8_t index; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < PCM_BUF_MAX_COUNT; index++) - audio->in[index].used = 0; - audio->buf_refresh = 0; - audio->read_next = 0; - audio->fill_next = 0; - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} -/*check if func to be added to validate user data*/ - -static void audac3_ioport_reset(struct audio *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audac3_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->read_wait); - mutex_lock(&audio->read_lock); - audac3_flush_pcm_buf(audio); - mutex_unlock(&audio->read_lock); -} - -static int audac3_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audac3_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audac3_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audac3_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audac3_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - - -static long audac3_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audac3_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - audio->event_wait, audac3_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audac3_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - rc = 0; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audac3_event, list); - list_del(&drv_evt->list); - } - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audio_enable_eq(struct audio *audio, int enable) -{ - if (audio->eq_enable == enable && !audio->eq_needs_commit) - return 0; - - audio->eq_enable = enable; - - if (audio->running) { - audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq); - audio->eq_needs_commit = 0; - } - return 0; -} - -static long audac3_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - unsigned long flags = 0; - uint16_t enable_mask; - int enable; - int prev_state; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - int len = 0; - - MM_DBG("cmd = %d\n", cmd); - - switch (cmd) { - case AUDIO_ENABLE_AUDPP: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - spin_lock_irqsave(&audio->dsp_lock, flags); - enable = (enable_mask & EQ_ENABLE) ? 1 : 0; - audio_enable_eq(audio, enable); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - case AUDIO_SET_VOLUME: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.volume = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_PAN: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.pan = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_EQ: - prev_state = audio->eq_enable; - audio->eq_enable = 0; - if (copy_from_user(&audio->eq.num_bands, (void *) arg, - sizeof(audio->eq) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) { - rc = -EFAULT; - break; - } - audio->eq_enable = prev_state; - audio->eq_needs_commit = 1; - rc = 0; - break; - } - - if (-EINVAL != rc) - return rc; - - if (cmd == AUDIO_GET_EVENT) { - MM_DBG("AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audac3_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audac3_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) { - MM_ERR("In audio->dec_state !=\n"); - rc = -ENODEV; - } else - rc = 0; - } - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audac3_disable(audio); - audac3_ioport_reset(audio); - audio->stopped = 0; - break; - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audac3_ioport_reset(audio); - if (audio->running) { - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - case AUDIO_SET_CONFIG:{ - struct msm_audio_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - audio->mfield = config.meta_field; - rc = 0; - MM_DBG("AUDIO_SET_CONFIG applicable only"\ - " for meta field configuration\n"); - break; - } - case AUDIO_GET_CONFIG:{ - struct msm_audio_config config; - config.buffer_size = BUFSZ; - config.buffer_count = 2; - config.sample_rate = (audio->ac3_config).fsCod; - config.channel_count = 2; - config.meta_field = 0; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *)arg, &config, sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_GET_AC3_CONFIG:{ - if (copy_to_user((void *)arg, &audio->ac3_config, - sizeof(audio->ac3_config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_AC3_CONFIG:{ - struct msm_audio_ac3_config usr_config; - - if (copy_from_user - (&usr_config, (void *)arg, - sizeof(usr_config))) { - rc = -EFAULT; - break; - } - - audio->ac3_config = usr_config; - rc = 0; - break; - } - case AUDIO_GET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - config.pcm_feedback = audio->pcm_feedback; - config.buffer_count = PCM_BUF_MAX_COUNT; - config.buffer_size = PCM_BUFSZ; - if (copy_to_user((void *)arg, &config, sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.pcm_feedback != audio->pcm_feedback) { - - MM_ERR("Not sufficient permission to"\ - " change the playback mode\n"); - rc = -EACCES; - break; - - } - if ((config.buffer_count > PCM_BUF_MAX_COUNT) || - (config.buffer_count == 1)) - config.buffer_count = PCM_BUF_MAX_COUNT; - - if (config.buffer_size < PCM_BUFSZ) - config.buffer_size = PCM_BUFSZ; - - /* Check if pcm feedback is required */ - if ((config.pcm_feedback) && (!audio->read_data)) { - MM_DBG("allocate PCM buf %d\n", - config.buffer_count * - config.buffer_size); - handle = ion_alloc(audio->client, - (config.buffer_size * - config.buffer_count), - SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to alloc I/P buffs\n"); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - break; - } - - audio->input_buff_handle = handle; - - rc = ion_phys(audio->client , - handle, &addr, &len); - if (rc) { - MM_ERR("Invalid phy: %x sz: %x\n", - (unsigned int) addr, - (unsigned int) len); - ion_free(audio->client, handle); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - break; - } else { - MM_INFO("Got valid phy: %x sz: %x\n", - (unsigned int) audio->read_phys, - (unsigned int) len); - } - audio->read_phys = (int32_t)addr; - - rc = ion_handle_get_flags(audio->client, - handle, &ionflag); - if (rc) { - MM_ERR("could not get flags\n"); - ion_free(audio->client, handle); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - break; - } - - audio->map_v_read = ion_map_kernel( - audio->client, handle); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("map of read buf failed\n"); - ion_free(audio->client, handle); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - } else { - uint8_t index; - uint32_t offset = 0; - audio->read_data = - audio->map_v_read; - audio->buf_refresh = 0; - audio->pcm_buf_count = - config.buffer_count; - audio->read_next = 0; - audio->fill_next = 0; - - for (index = 0; - index < config.buffer_count; - index++) { - audio->in[index].data = - audio->read_data + offset; - audio->in[index].addr = - audio->read_phys + offset; - audio->in[index].size = - config.buffer_size; - audio->in[index].used = 0; - offset += config.buffer_size; - } - MM_DBG("read buf: phy addr"\ - " 0x%08x kernel addr 0x%08x\n", - audio->read_phys, - (int)audio->read_data); - rc = 0; - } - } else { - rc = 0; - } - break; - } - case AUDIO_PAUSE: - MM_DBG("AUDIO_PAUSE %ld\n", arg); - rc = audpp_pause(audio->dec_id, (int) arg); - break; - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -static int audac3_fsync(struct file *file, loff_t a, loff_t b, int datasync) -{ - struct audio *audio = file->private_data; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - if (!audio->running || audio->pcm_feedback) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush); - - if (audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; -} - -static ssize_t audac3_read(struct file *file, char __user *buf, size_t count, - loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - int rc = 0; - if (!audio->pcm_feedback) { - MM_ERR("returning from read as tunnel mode\n"); - return 0; - /* PCM feedback is not enabled. Nothing to read */ - } - mutex_lock(&audio->read_lock); - MM_DBG("\n"); /* Macro prints the file name and function */ - while (count > 0) { - rc = wait_event_interruptible(audio->read_wait, - (audio->in[audio->read_next].used > 0) || - (audio->stopped) || (audio->rflush)); - - MM_DBG("wait terminated count%d\n", count); - if (rc < 0) - break; - if (audio->stopped || audio->rflush) { - rc = -EBUSY; - break; - } - if (count < audio->in[audio->read_next].used) { - /* Read must happen in frame boundary. Since driver does - * not know frame size, read count must be greater or - * equal to size of PCM samples - */ - MM_DBG("read stop - partial frame\n"); - break; - } else { - MM_DBG("read from in[%d]\n", audio->read_next); - /* order reads from the output buffer */ - rmb(); - if (copy_to_user - (buf, audio->in[audio->read_next].data, - audio->in[audio->read_next].used)) { - MM_ERR("invalid addr %x\n", - (unsigned int)buf); - rc = -EFAULT; - break; - } - count -= audio->in[audio->read_next].used; - buf += audio->in[audio->read_next].used; - audio->in[audio->read_next].used = 0; - if ((++audio->read_next) == audio->pcm_buf_count) - audio->read_next = 0; - break; - /* Force to exit while loop - * to prevent output thread - * sleep too long if data is - * not ready at this moment - */ - - } - } - /* don't feed output buffer to HW decoder during flushing - * buffer refresh command will be sent once flush completes - * send buf refresh command here can confuse HW decoder - */ - if (audio->buf_refresh && !audio->rflush) { - audio->buf_refresh = 0; - MM_DBG("kick start pcm feedback again\n"); - audac3_buffer_refresh(audio); - } - mutex_unlock(&audio->read_lock); - if (buf > start) - rc = buf - start; - MM_DBG("read %d bytes\n", rc); - return rc; -} - -static int audac3_process_eos(struct audio *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - int rc = 0; - struct buffer *frame; - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - audac3_send_data(audio, 0); - -done: - return rc; -} - -static ssize_t audac3_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - char *cpy_ptr; - unsigned short mfield_size = 0; - int rc = 0, eos_condition = AUDAC3_EOS_NONE; - - MM_DBG("cnt=%d\n", count); - - if (count & 1) - return -EINVAL; - - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - cpy_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - break; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - break; - } - - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - break; - } else if (mfield_size > count) { - rc = -EINVAL; - break; - } - MM_DBG("mf offset_val %x\n", mfield_size); - if (copy_from_user(cpy_ptr, buf, - mfield_size)) { - rc = -EFAULT; - break; - } - /* Check if EOS flag is set and buffer has - * contains just meta field - */ - if (cpy_ptr[AUDAC3_EOS_FLG_OFFSET] & - AUDAC3_EOS_FLG_MASK) { - MM_DBG("eos set\n"); - eos_condition = AUDAC3_EOS_SET; - if (mfield_size == count) { - buf += mfield_size; - break; - } else - cpy_ptr[AUDAC3_EOS_FLG_OFFSET] &= - ~AUDAC3_EOS_FLG_MASK; - } - /* Check EOS to see if */ - cpy_ptr += mfield_size; - count -= mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - - xfer = (count > (frame->size - mfield_size)) ? - (frame->size - mfield_size) : count; - if (copy_from_user(cpy_ptr, buf, xfer)) { - rc = -EFAULT; - break; - } - frame->used = xfer + mfield_size; - audio->out_head ^= 1; - count -= xfer; - buf += xfer; - audac3_send_data(audio, 0); - } - if (eos_condition == AUDAC3_EOS_SET) - rc = audac3_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - if (!rc) { - if (buf > start) - return buf - start; - } - return rc; -} - -static int audac3_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_INFO("audio instance 0x%08x freeing\n", (int)audio); - mutex_lock(&audio->lock); - audac3_disable(audio); - if (audio->rmt_resource_released == 0) - rmt_put_resource(audio); - audac3_flush(audio); - audac3_flush_pcm_buf(audio); - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->event_abort = 1; - wake_up(&audio->event_wait); - audac3_reset_event_queue(audio); - ion_unmap_kernel(audio->client, audio->output_buff_handle); - ion_free(audio->client, audio->output_buff_handle); - if (audio->input_buff_handle != NULL) { - ion_unmap_kernel(audio->client, audio->input_buff_handle); - ion_free(audio->client, audio->input_buff_handle); - } - ion_client_destroy(audio->client); - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - kfree(audio); - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audac3_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audac3_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audac3_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audac3_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -static void audac3_suspend(struct early_suspend *h) -{ - struct audac3_suspend_ctl *ctl = - container_of(h, struct audac3_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audac3_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audac3_resume(struct early_suspend *h) -{ - struct audac3_suspend_ctl *ctl = - container_of(h, struct audac3_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audac3_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audac3_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audac3_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 1024; - static char buffer[1024]; - int n = 0, i; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_feedback %d\n", audio->pcm_feedback); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_buf_sz %d\n", audio->out[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_count %d\n", audio->pcm_buf_count); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_sz %d\n", audio->in[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %x\n", audio->vol_pan.volume); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "rflush %d\n", audio->rflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d\n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d\n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d\n", audio->out_needed); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_head %d\n", audio->out_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_tail %d\n", audio->out_tail); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[0].used %d\n", audio->out[0].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[1].used %d\n", audio->out[1].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "buffer_refresh %d\n", audio->buf_refresh); - n += scnprintf(buffer + n, debug_bufmax - n, - "read_next %d\n", audio->read_next); - n += scnprintf(buffer + n, debug_bufmax - n, - "fill_next %d\n", audio->fill_next); - for (i = 0; i < audio->pcm_buf_count; i++) - n += scnprintf(buffer + n, debug_bufmax - n, - "in[%d].size %d\n", i, audio->in[i].used); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audac3_debug_fops = { - .read = audac3_debug_read, - .open = audac3_debug_open, -}; -#endif - -static int audac3_open(struct inode *inode, struct file *file) -{ - struct audio *audio = NULL; - int rc, dec_attrb, decid, i; - struct audac3_event *e_node = NULL; - int len = 0; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - struct ion_client *client = NULL; -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_ac3_" + 5]; -#endif - - /* Allocate audio instance, set to zero */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("no memory to allocate audio instance\n"); - rc = -ENOMEM; - goto done; - } - MM_INFO("audio instance 0x%08x created\n", (int)audio); - - /* Allocate the decoder */ - dec_attrb = AUDDEC_DEC_AC3; - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_NONTUNNEL; - audio->pcm_feedback = NON_TUNNEL_MODE_PLAYBACK; - } else if ((file->f_mode & FMODE_WRITE) && - !(file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_TUNNEL; - audio->pcm_feedback = TUNNEL_MODE_PLAYBACK; - } else { - kfree(audio); - rc = -EACCES; - goto done; - } - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - - if (decid < 0) { - MM_ERR("No free decoder available, freeing instance 0x%08x\n", - (int)audio); - rc = -ENODEV; - kfree(audio); - goto done; - } - - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - client = msm_ion_client_create(UINT_MAX, "Audio_AC3_client"); - if (IS_ERR_OR_NULL(client)) { - MM_ERR("Unable to create ION client\n"); - rc = -ENOMEM; - goto client_create_error; - } - audio->client = client; - - handle = ion_alloc(client, DMASZ, SZ_4K, - ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to create allocate O/P buffers\n"); - rc = -ENOMEM; - goto output_buff_alloc_error; - } - - audio->output_buff_handle = handle; - - rc = ion_phys(client, handle, &addr, &len); - if (rc) { - MM_ERR("O/P buffers:Invalid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - goto output_buff_get_phys_error; - } else { - MM_INFO("O/P buffers:valid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - } - audio->phys = (int32_t)addr; - - rc = ion_handle_get_flags(client, handle, &ionflag); - if (rc) { - MM_ERR("could not get flags for the handle\n"); - goto output_buff_get_flags_error; - } - - audio->map_v_write = ion_map_kernel(client, handle); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write buffers,freeing instance 0x%08x\n", - (int)audio); - rc = -ENOMEM; - goto output_buff_map_error; - } - audio->data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->phys, (int)audio->data); - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audplay_adsp_ops_ac3, audio); - if (rc) { - MM_ERR("failed to get %s module, freeing instance 0x%08x\n", - audio->module_name, (int)audio); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_close(&audio->audmgr); - goto err; - } - - rc = rmt_get_resource(audio); - if (rc) { - MM_ERR("ADSP resources are not available for AC3 session"\ - " 0x%08x on decoder: %d\n", (int)audio, audio->dec_id); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_close(&audio->audmgr); - msm_adsp_put(audio->audplay); - goto err; - } - - /* Initialize all locks of audio instance */ - audio->input_buff_handle = NULL; - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->read_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - init_waitqueue_head(&audio->write_wait); - init_waitqueue_head(&audio->read_wait); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - spin_lock_init(&audio->event_queue_lock); - - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = BUFSZ; - - audio->out[1].data = audio->data + BUFSZ; - audio->out[1].addr = audio->phys + BUFSZ; - audio->out[1].size = BUFSZ; - - audio->vol_pan.volume = 0x3FFF; - - (audio->ac3_config).wordSize = AUDAC3_DEF_WORDSIZE; - (audio->ac3_config).user_downmix_flag = AUDAC3_DEF_USER_DOWNMIX_FLAG; - (audio->ac3_config).user_karaoke_flag = AUDAC3_DEF_USER_KARAOKE_FLAG; - (audio->ac3_config).error_concealment = AUDAC3_DEF_ERROR_CONCEALMENT; - (audio->ac3_config).max_rep_count = AUDAC3_DEF_MAX_REPEAT_COUNT; - - audac3_flush(audio); - - file->private_data = audio; - audio->opened = 1; -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_ac3_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, &audac3_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audac3_resume; - audio->suspend_ctl.node.suspend = audac3_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (i = 0; i < AUDAC3_EVENT_NUM; i++) { - e_node = kmalloc(sizeof(struct audac3_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } -done: - return rc; -err: - ion_unmap_kernel(client, audio->output_buff_handle); -output_buff_map_error: -output_buff_get_flags_error: -output_buff_get_phys_error: - ion_free(client, audio->output_buff_handle); -output_buff_alloc_error: - ion_client_destroy(client); -client_create_error: - audpp_adec_free(audio->dec_id); - kfree(audio); - return rc; -} - -static const struct file_operations audio_ac3_fops = { - .owner = THIS_MODULE, - .open = audac3_open, - .release = audac3_release, - .read = audac3_read, - .write = audac3_write, - .unlocked_ioctl = audac3_ioctl, - .fsync = audac3_fsync, -}; - -struct miscdevice audio_ac3_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_ac3", - .fops = &audio_ac3_fops, -}; - -static int __init audac3_init(void) -{ - return misc_register(&audio_ac3_misc); - -} - -static void __exit audac3_exit(void) -{ - misc_deregister(&audio_ac3_misc); -} - -module_init(audac3_init); -module_exit(audac3_exit); - -MODULE_DESCRIPTION("MSM AC3 driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5/audio_amrnb.c b/arch/arm/mach-msm/qdsp5/audio_amrnb.c deleted file mode 100644 index 622890b6f1eaa73e92d7b515953960f51e73211e..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_amrnb.c +++ /dev/null @@ -1,1701 +0,0 @@ -/* linux/arch/arm/mach-msm/qdsp5/audio_amrnb.c - * - * amrnb audio decoder device - * - * Copyright (c) 2008-2009, 2011-2012 The Linux Foundation. All rights reserved. - * - * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * - * All source code in this file is licensed under the following license except - * where indicated. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "audmgr.h" - -#define BUFSZ 1024 /* Hold minimum 700ms voice data and 14 bytes of meta in*/ -#define DMASZ (BUFSZ * 2) - -#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF -#define AUDDEC_DEC_AMRNB 10 - -#define PCM_BUFSZ_MIN 1624 /* 100ms worth of data and 24 bytes of meta out*/ -#define AMRNB_DECODED_FRSZ 320 /* AMR-NB 20ms 8KHz mono PCM size */ -#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most - but support 2 buffers currently */ -#define ROUTING_MODE_FTRT 1 -#define ROUTING_MODE_RT 2 -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDAMRNB_METAFIELD_MASK 0xFFFF0000 -#define AUDAMRNB_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */ -#define AUDAMRNB_EOS_FLG_MASK 0x01 -#define AUDAMRNB_EOS_NONE 0x0 /* No EOS detected */ -#define AUDAMRNB_EOS_SET 0x1 /* EOS set in meta field */ - -#define AUDAMRNB_EVENT_NUM 10 /* Default number of pre-allocated event pkts */ - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; - unsigned short mfield_sz; /*only useful for data has meta field */ -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audamrnb_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct audamrnb_event{ - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audio { - struct buffer out[2]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - /* Host PCM section */ - struct buffer in[PCM_BUF_MAX_COUNT]; - struct mutex read_lock; - wait_queue_head_t read_wait; /* Wait queue for read */ - char *read_data; /* pointer to reader buffer */ - int32_t read_phys; /* physical address of reader buffer */ - uint8_t read_next; /* index to input buffers to be read next */ - uint8_t fill_next; /* index to buffer that DSP should be filling */ - uint8_t pcm_buf_count; /* number of pcm buffer allocated */ - /* ---- End of Host PCM section */ - - struct msm_adsp_module *audplay; - - struct audmgr audmgr; - - /* data allocated for various buffers */ - char *data; - int32_t phys; /* physical address of write buffer */ - void *map_v_read; - void *map_v_write; - - - int mfield; /* meta field embedded in data */ - int rflush; /* Read flush */ - int wflush; /* Write flush */ - uint8_t opened:1; - uint8_t enabled:1; - uint8_t running:1; - uint8_t stopped:1; /* set when stopped, cleared on flush */ - uint8_t pcm_feedback:1; - uint8_t buf_refresh:1; - int teos; /* valid only if tunnel mode & no data left for decoder */ - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - int rmt_resource_released; - - const char *module_name; - unsigned queue_id; - uint16_t dec_id; - uint32_t read_ptr_offset; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audamrnb_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - - int eq_enable; - int eq_needs_commit; - audpp_cmd_cfg_object_params_eqalizer eq; - audpp_cmd_cfg_object_params_volume vol_pan; - struct ion_client *client; - struct ion_handle *input_buff_handle; - struct ion_handle *output_buff_handle; -}; - -struct audpp_cmd_cfg_adec_params_amrnb { - audpp_cmd_cfg_adec_params_common common; - unsigned short stereo_cfg; -} __attribute__((packed)) ; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audpp_cmd_cfg_adec_params(struct audio *audio); -static void audpp_cmd_cfg_routing_mode(struct audio *audio); -static void audamrnb_send_data(struct audio *audio, unsigned needed); -static void audamrnb_config_hostpcm(struct audio *audio); -static void audamrnb_buffer_refresh(struct audio *audio); -static void audamrnb_dsp_event(void *private, unsigned id, uint16_t *msg); -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audamrnb_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); -#endif - -static int rmt_put_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_DISABLE; - cmd.dec_type = AUDDEC_DEC_AMRNB; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - - return put_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -static int rmt_get_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_ENABLE; - cmd.dec_type = AUDDEC_DEC_AMRNB; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - - return get_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -/* must be called with audio->lock held */ -static int audamrnb_enable(struct audio *audio) -{ - struct audmgr_config cfg; - int rc; - - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) - return 0; - - if (audio->rmt_resource_released == 1) { - audio->rmt_resource_released = 0; - rc = rmt_get_resource(audio); - if (rc) { - MM_ERR("ADSP resources are not available for AMRNB \ - session 0x%08x on decoder: %d\n Ignoring \ - error and going ahead with the playback\n", - (int)audio, audio->dec_id); - } - } - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_tail = 0; - audio->out_needed = 0; - - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) { - cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; - cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000; - cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK; - cfg.codec = RPC_AUD_DEF_CODEC_AMR_NB; - cfg.snd_method = RPC_SND_METHOD_MIDI; - - rc = audmgr_enable(&audio->audmgr, &cfg); - if (rc < 0) - return rc; - } - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audamrnb_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - audio->enabled = 1; - return 0; -} - -/* must be called with audio->lock held */ -static int audamrnb_disable(struct audio *audio) -{ - int rc = 0; - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - audio->stopped = 1; - wake_up(&audio->write_wait); - wake_up(&audio->read_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - audio->out_needed = 0; - rmt_put_resource(audio); - audio->rmt_resource_released = 1; - } - return rc; -} - -/* ------------------- dsp --------------------- */ -static void audamrnb_update_pcm_buf_entry(struct audio *audio, - uint32_t *payload) -{ - uint8_t index; - unsigned long flags; - - if (audio->rflush) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < payload[1]; index++) { - if (audio->in[audio->fill_next].addr == - payload[2 + index * 2]) { - MM_DBG("in[%d] ready\n", audio->fill_next); - audio->in[audio->fill_next].used = - payload[3 + index * 2]; - if ((++audio->fill_next) == audio->pcm_buf_count) - audio->fill_next = 0; - - } else { - MM_ERR("expected=%x ret=%x\n", - audio->in[audio->fill_next].addr, - payload[1 + index * 2]); - break; - } - } - if (audio->in[audio->fill_next].used == 0) { - audamrnb_buffer_refresh(audio); - } else { - MM_DBG("read cannot keep up\n"); - audio->buf_refresh = 1; - } - wake_up(&audio->read_wait); - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - getevent(msg, sizeof(msg)); - - MM_DBG("msg_id=%x\n", id); - - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audamrnb_send_data(audio, 1); - break; - - case AUDPLAY_MSG_BUFFER_UPDATE: - audamrnb_update_pcm_buf_entry(audio, msg); - break; - - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audplaytask)\n"); - break; - - default: - MM_ERR("unexpected message from decoder\n"); - } -} - -static void audamrnb_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status:sleep reason = \ - 0x%04x\n", reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init \n"); - if (audio->pcm_feedback) - audpp_cmd_cfg_routing_mode(audio); - else - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg \n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play \n"); - if (audio->pcm_feedback) { - audamrnb_config_hostpcm(audio); - audamrnb_buffer_refresh(audio); - } - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - default: - MM_ERR("unknown decoder status \n"); - break; - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - audpp_dsp_set_eq(audio->dec_id, audio->eq_enable, - &audio->eq); - audpp_avsync(audio->dec_id, 22050); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audpp_avsync(audio->dec_id, 0); - audio->running = 0; - } else { - MM_DBG("CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_ROUTING_ACK: - MM_DBG("ROUTING_ACK mode=%d\n", msg[1]); - audpp_cmd_cfg_adec_params(audio); - break; - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - audio->rflush = 0; - wake_up(&audio->write_wait); - if (audio->pcm_feedback) - audamrnb_buffer_refresh(audio); - break; - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - default: - MM_ERR("UNKNOWN (%d)\n", id); - } - -} - -struct msm_adsp_ops audplay_adsp_ops_amrnb = { - .event = audplay_dsp_event, -}; - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id, \ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - u16 cfg_dec_cmd[AUDPP_CMD_CFG_DEC_TYPE_LEN / sizeof(unsigned short)]; - - memset(cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - cfg_dec_cmd[0] = AUDPP_CMD_CFG_DEC_TYPE; - if (enable) - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_AMRNB; - else - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} - -static void audpp_cmd_cfg_adec_params(struct audio *audio) -{ - struct audpp_cmd_cfg_adec_params_amrnb cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN; - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = 8000; - cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V; - - audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static void audpp_cmd_cfg_routing_mode(struct audio *audio) -{ - struct audpp_cmd_routing_mode cmd; - MM_DBG("\n"); /* Macro prints the file name and function */ - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; - cmd.object_number = audio->dec_id; - if (audio->pcm_feedback) - cmd.routing_mode = ROUTING_MODE_FTRT; - else - cmd.routing_mode = ROUTING_MODE_RT; - - audpp_send_queue1(&cmd, sizeof(cmd)); -} - -static int audplay_dsp_send_data_avail(struct audio *audio, - unsigned idx, unsigned len) -{ - struct audplay_cmd_bitstream_data_avail_nt2 cmd; - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2; - if (audio->mfield) - cmd.decoder_id = AUDAMRNB_METAFIELD_MASK | - (audio->out[idx].mfield_sz >> 1); - else - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = audio->out[idx].addr; - cmd.buf_size = len / 2; - cmd.partition_number = 0; - /* complete writes to the input buffer */ - wmb(); - return audplay_send_queue0(audio, &cmd, sizeof(cmd)); -} - -static void audamrnb_buffer_refresh(struct audio *audio) -{ - struct audplay_cmd_buffer_refresh refresh_cmd; - - refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; - refresh_cmd.num_buffers = 1; - refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; - refresh_cmd.buf0_length = audio->in[audio->fill_next].size - - (audio->in[audio->fill_next].size % AMRNB_DECODED_FRSZ) + - (audio->mfield ? 24 : 0); - refresh_cmd.buf_read_count = 0; - MM_DBG("buf0_addr=%x buf0_len=%d\n", refresh_cmd.buf0_address, - refresh_cmd.buf0_length); - (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); -} - -static void audamrnb_config_hostpcm(struct audio *audio) -{ - struct audplay_cmd_hpcm_buf_cfg cfg_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; - cfg_cmd.max_buffers = audio->pcm_buf_count; - cfg_cmd.byte_swap = 0; - cfg_cmd.hostpcm_config = (0x8000) | (0x4000); - cfg_cmd.feedback_frequency = 1; - cfg_cmd.partition_number = 0; - (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); - -} - -static void audamrnb_send_data(struct audio *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - MM_DBG("frame %d busy\n", audio->out_tail); - audplay_dsp_send_data_avail(audio, audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } - done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ - -static void audamrnb_flush(struct audio *audio) -{ - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->out_needed = 0; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - atomic_set(&audio->out_bytes, 0); -} - -static void audamrnb_flush_pcm_buf(struct audio *audio) -{ - uint8_t index; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < PCM_BUF_MAX_COUNT; index++) - audio->in[index].used = 0; - - audio->buf_refresh = 0; - audio->read_next = 0; - audio->fill_next = 0; - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audamrnb_ioport_reset(struct audio *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audamrnb_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->read_wait); - mutex_lock(&audio->read_lock); - audamrnb_flush_pcm_buf(audio); - mutex_unlock(&audio->read_lock); -} - -static int audamrnb_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audamrnb_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audamrnb_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audamrnb_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audamrnb_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - -static long audamrnb_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audamrnb_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - audio->event_wait, audamrnb_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audamrnb_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - rc = 0; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audamrnb_event, list); - list_del(&drv_evt->list); - } - - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audio_enable_eq(struct audio *audio, int enable) -{ - if (audio->eq_enable == enable && !audio->eq_needs_commit) - return 0; - - audio->eq_enable = enable; - - if (audio->running) { - audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq); - audio->eq_needs_commit = 0; - } - return 0; -} - -static long audamrnb_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - unsigned long flags = 0; - uint16_t enable_mask; - int enable; - int prev_state; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - int len = 0; - - MM_DBG("cmd = %d\n", cmd); - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = audpp_avsync_byte_count(audio->dec_id); - stats.sample_count = audpp_avsync_sample_count(audio->dec_id); - if (copy_to_user((void *)arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - switch (cmd) { - case AUDIO_ENABLE_AUDPP: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - spin_lock_irqsave(&audio->dsp_lock, flags); - enable = (enable_mask & EQ_ENABLE) ? 1 : 0; - audio_enable_eq(audio, enable); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - case AUDIO_SET_VOLUME: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.volume = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_PAN: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.pan = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_EQ: - prev_state = audio->eq_enable; - audio->eq_enable = 0; - if (copy_from_user(&audio->eq.num_bands, (void *) arg, - sizeof(audio->eq) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) { - rc = -EFAULT; - break; - } - audio->eq_enable = prev_state; - audio->eq_needs_commit = 1; - rc = 0; - break; - } - - if (-EINVAL != rc) - return rc; - - if (cmd == AUDIO_GET_EVENT) { - MM_DBG("AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audamrnb_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audamrnb_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) - rc = -ENODEV; - else - rc = 0; - } - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audamrnb_disable(audio); - audamrnb_ioport_reset(audio); - audio->stopped = 0; - break; - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audamrnb_ioport_reset(audio); - if (audio->running) { - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - case AUDIO_SET_CONFIG:{ - struct msm_audio_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - audio->mfield = config.meta_field; - rc = 0; - break; - } - case AUDIO_GET_CONFIG:{ - struct msm_audio_config config; - config.buffer_size = BUFSZ; - config.buffer_count = 2; - config.sample_rate = 8000; - config.channel_count = 1; - config.meta_field = 0; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - - break; - } - case AUDIO_GET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - config.pcm_feedback = audio->pcm_feedback; - config.buffer_count = PCM_BUF_MAX_COUNT; - config.buffer_size = PCM_BUFSZ_MIN; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.pcm_feedback != audio->pcm_feedback) { - MM_ERR("Not sufficient permission to" - "change the playback mode\n"); - rc = -EACCES; - break; - } - if ((config.buffer_count > PCM_BUF_MAX_COUNT) || - (config.buffer_count == 1)) - config.buffer_count = PCM_BUF_MAX_COUNT; - - if (config.buffer_size < PCM_BUFSZ_MIN) - config.buffer_size = PCM_BUFSZ_MIN; - - /* Check if pcm feedback is required */ - if ((config.pcm_feedback) && (!audio->read_data)) { - MM_DBG("allocate PCM buf %d\n", - config.buffer_count * - config.buffer_size); - handle = ion_alloc(audio->client, - (config.buffer_size * - config.buffer_count), - SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to alloc I/P buffs\n"); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - break; - } - - audio->input_buff_handle = handle; - - rc = ion_phys(audio->client , - handle, &addr, &len); - if (rc) { - MM_ERR("Invalid phy: %x sz: %x\n", - (unsigned int) addr, - (unsigned int) len); - ion_free(audio->client, handle); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - break; - } else { - MM_INFO("Got valid phy: %x sz: %x\n", - (unsigned int) audio->read_phys, - (unsigned int) len); - } - audio->read_phys = (int32_t)addr; - - rc = ion_handle_get_flags(audio->client, - handle, &ionflag); - if (rc) { - MM_ERR("could not get flags\n"); - ion_free(audio->client, handle); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - break; - } - audio->map_v_read = ion_map_kernel( - audio->client, handle); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("failed to map read buf\n"); - ion_free(audio->client, handle); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - } else { - uint8_t index; - uint32_t offset = 0; - audio->read_data = - audio->map_v_read; - audio->buf_refresh = 0; - audio->pcm_buf_count = - config.buffer_count; - audio->read_next = 0; - audio->fill_next = 0; - - for (index = 0; - index < config.buffer_count; index++) { - audio->in[index].data = - audio->read_data + offset; - audio->in[index].addr = - audio->read_phys + offset; - audio->in[index].size = - config.buffer_size; - audio->in[index].used = 0; - offset += config.buffer_size; - } - MM_DBG("read buf: phy addr 0x%08x kernel \ - addr 0x%08x\n", audio->read_phys, - (int)audio->read_data); - rc = 0; - } - } else { - rc = 0; - } - break; - } - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -static int audamrnb_fsync(struct file *file, loff_t a, loff_t b, int datasync) -{ - struct audio *audio = file->private_data; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (!audio->running || audio->pcm_feedback) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush); - - if (audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; -} - -static ssize_t audamrnb_read(struct file *file, char __user *buf, size_t count, - loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - int rc = 0; - - if (!audio->pcm_feedback) - return 0; /* PCM feedback is not enabled. Nothing to read */ - - mutex_lock(&audio->read_lock); - MM_DBG("%d \n", count); - while (count > 0) { - rc = wait_event_interruptible(audio->read_wait, - (audio->in[audio->read_next].used > 0) || - (audio->stopped) || (audio->rflush)); - - if (rc < 0) - break; - - if (audio->stopped || audio->rflush) { - rc = -EBUSY; - break; - } - - if (count < audio->in[audio->read_next].used) { - /* Read must happen in frame boundary. Since driver does - * not know frame size, read count must be greater or - * equal to size of PCM samples - */ - MM_DBG("read stop - partial frame\n"); - break; - } else { - MM_DBG("read from in[%d]\n", audio->read_next); - /* order reads from the output buffer */ - rmb(); - if (copy_to_user - (buf, audio->in[audio->read_next].data, - audio->in[audio->read_next].used)) { - MM_ERR("invalid addr %x \n", (unsigned int)buf); - rc = -EFAULT; - break; - } - count -= audio->in[audio->read_next].used; - buf += audio->in[audio->read_next].used; - audio->in[audio->read_next].used = 0; - if ((++audio->read_next) == audio->pcm_buf_count) - audio->read_next = 0; - break; - } - } - - /* don't feed output buffer to HW decoder during flushing - * buffer refresh command will be sent once flush completes - * send buf refresh command here can confuse HW decoder - */ - if (audio->buf_refresh && !audio->rflush) { - audio->buf_refresh = 0; - MM_DBG("kick start pcm feedback again\n"); - audamrnb_buffer_refresh(audio); - } - - mutex_unlock(&audio->read_lock); - - if (buf > start) - rc = buf - start; - - MM_DBG("read %d bytes\n", rc); - return rc; -} - -static int audamrnb_process_eos(struct audio *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - int rc = 0; - struct buffer *frame; - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - audamrnb_send_data(audio, 0); - -done: - return rc; -} - -static ssize_t audamrnb_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - char *cpy_ptr; - int rc = 0, eos_condition = AUDAMRNB_EOS_NONE; - unsigned short mfield_size = 0; - - MM_DBG("cnt=%d\n", count); - - if (count & 1) - return -EINVAL; - - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - cpy_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - - MM_DBG("buffer available\n"); - if (rc < 0) - break; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - break; - } - - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - break; - } else if (mfield_size > count) { - rc = -EINVAL; - break; - } - MM_DBG("mf offset_val %x\n", mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - break; - } - /* Check if EOS flag is set and buffer - * contains just meta field - */ - if (cpy_ptr[AUDAMRNB_EOS_FLG_OFFSET] & - AUDAMRNB_EOS_FLG_MASK) { - MM_DBG("eos set\n"); - eos_condition = AUDAMRNB_EOS_SET; - if (mfield_size == count) { - buf += mfield_size; - break; - } else - cpy_ptr[AUDAMRNB_EOS_FLG_OFFSET] &= - ~AUDAMRNB_EOS_FLG_MASK; - } - cpy_ptr += mfield_size; - count -= mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - - xfer = (count > (frame->size - mfield_size)) ? - (frame->size - mfield_size) : count; - if (copy_from_user(cpy_ptr, buf, xfer)) { - rc = -EFAULT; - break; - } - - frame->used = (xfer + mfield_size); - audio->out_head ^= 1; - count -= xfer; - buf += xfer; - - audamrnb_send_data(audio, 0); - - } - if (eos_condition == AUDAMRNB_EOS_SET) - rc = audamrnb_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - if (!rc) { - if (buf > start) - return buf - start; - } - return rc; -} - -static int audamrnb_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_INFO("audio instance 0x%08x freeing\n", (int)audio); - mutex_lock(&audio->lock); - audamrnb_disable(audio); - if (audio->rmt_resource_released == 0) - rmt_put_resource(audio); - audamrnb_flush(audio); - audamrnb_flush_pcm_buf(audio); - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->event_abort = 1; - wake_up(&audio->event_wait); - audamrnb_reset_event_queue(audio); - ion_unmap_kernel(audio->client, audio->output_buff_handle); - ion_free(audio->client, audio->output_buff_handle); - if (audio->input_buff_handle != NULL) { - ion_unmap_kernel(audio->client, audio->input_buff_handle); - ion_free(audio->client, audio->input_buff_handle); - } - ion_client_destroy(audio->client); - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - kfree(audio); - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audamrnb_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audamrnb_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audamrnb_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audamrnb_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -static void audamrnb_suspend(struct early_suspend *h) -{ - struct audamrnb_suspend_ctl *ctl = - container_of(h, struct audamrnb_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audamrnb_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audamrnb_resume(struct early_suspend *h) -{ - struct audamrnb_suspend_ctl *ctl = - container_of(h, struct audamrnb_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audamrnb_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audamrnb_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audamrnb_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 1024; - static char buffer[1024]; - int n = 0, i; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_feedback %d\n", audio->pcm_feedback); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_buf_sz %d\n", audio->out[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_count %d \n", audio->pcm_buf_count); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_sz %d \n", audio->in[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %x \n", audio->vol_pan.volume); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "rflush %d\n", audio->rflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d \n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d \n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d \n", audio->out_needed); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_head %d \n", audio->out_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_tail %d \n", audio->out_tail); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[0].used %d \n", audio->out[0].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[1].used %d \n", audio->out[1].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "buffer_refresh %d \n", audio->buf_refresh); - n += scnprintf(buffer + n, debug_bufmax - n, - "read_next %d \n", audio->read_next); - n += scnprintf(buffer + n, debug_bufmax - n, - "fill_next %d \n", audio->fill_next); - for (i = 0; i < audio->pcm_buf_count; i++) - n += scnprintf(buffer + n, debug_bufmax - n, - "in[%d].used %d \n", i, audio->in[i].used); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audamrnb_debug_fops = { - .read = audamrnb_debug_read, - .open = audamrnb_debug_open, -}; -#endif - -static int audamrnb_open(struct inode *inode, struct file *file) -{ - struct audio *audio = NULL; - int rc, dec_attrb, decid, i; - struct audamrnb_event *e_node = NULL; - unsigned mem_sz = DMASZ; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - struct ion_client *client = NULL; - int len = 0; -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_amrnb_" + 5]; -#endif - - /* Allocate Mem for audio instance */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("no memory to allocate audio instance \n"); - rc = -ENOMEM; - goto done; - } - MM_INFO("audio instance 0x%08x created\n", (int)audio); - - /* Allocate the decoder */ - dec_attrb = AUDDEC_DEC_AMRNB; - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_NONTUNNEL; - audio->pcm_feedback = NON_TUNNEL_MODE_PLAYBACK; - } else if ((file->f_mode & FMODE_WRITE) && - !(file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_TUNNEL; - audio->pcm_feedback = TUNNEL_MODE_PLAYBACK; - } else { - kfree(audio); - rc = -EACCES; - goto done; - } - - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - - if (decid < 0) { - MM_ERR("No free decoder available, freeing instance 0x%08x\n", - (int)audio); - rc = -ENODEV; - kfree(audio); - goto done; - } - - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - client = msm_ion_client_create(UINT_MAX, "Audio_AMR_NB_Client"); - if (IS_ERR_OR_NULL(client)) { - pr_err("Unable to create ION client\n"); - rc = -ENOMEM; - goto client_create_error; - } - audio->client = client; - - handle = ion_alloc(client, mem_sz, SZ_4K, - ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to create allocate O/P buffers\n"); - rc = -ENOMEM; - goto output_buff_alloc_error; - } - audio->output_buff_handle = handle; - - rc = ion_phys(client, handle, &addr, &len); - if (rc) { - MM_ERR("O/P buffers:Invalid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - goto output_buff_get_phys_error; - } else { - MM_INFO("O/P buffers:valid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - } - audio->phys = (int32_t)addr; - - - rc = ion_handle_get_flags(client, handle, &ionflag); - if (rc) { - MM_ERR("could not get flags for the handle\n"); - goto output_buff_get_flags_error; - } - - audio->map_v_write = ion_map_kernel(client, handle); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write buffers\n"); - rc = -ENOMEM; - goto output_buff_map_error; - } - audio->data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->phys, (int)audio->data); - - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) { - rc = audmgr_open(&audio->audmgr); - if (rc) { - MM_ERR("audmgr open failed, freeing instance \ - 0x%08x\n", (int)audio); - goto err; - } - } - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audplay_adsp_ops_amrnb, audio); - if (rc) { - MM_ERR("failed to get %s module, freeing instance 0x%08x\n", - audio->module_name, (int)audio); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_close(&audio->audmgr); - goto err; - } - - rc = rmt_get_resource(audio); - if (rc) { - MM_ERR("ADSP resources are not available for AMRNB session \ - 0x%08x on decoder: %d\n", (int)audio, audio->dec_id); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_close(&audio->audmgr); - msm_adsp_put(audio->audplay); - goto err; - } - - audio->input_buff_handle = NULL; - - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->read_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - spin_lock_init(&audio->event_queue_lock); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->write_wait); - init_waitqueue_head(&audio->read_wait); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = BUFSZ; - - audio->out[1].data = audio->data + BUFSZ; - audio->out[1].addr = audio->phys + BUFSZ; - audio->out[1].size = BUFSZ; - - audio->vol_pan.volume = 0x2000; - - audamrnb_flush(audio); - - file->private_data = audio; - audio->opened = 1; -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_amrnb_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, &audamrnb_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audamrnb_resume; - audio->suspend_ctl.node.suspend = audamrnb_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (i = 0; i < AUDAMRNB_EVENT_NUM; i++) { - e_node = kmalloc(sizeof(struct audamrnb_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } -done: - return rc; -err: - ion_unmap_kernel(client, audio->output_buff_handle); -output_buff_map_error: -output_buff_get_phys_error: -output_buff_get_flags_error: - ion_free(client, audio->output_buff_handle); -output_buff_alloc_error: - ion_client_destroy(client); -client_create_error: - audpp_adec_free(audio->dec_id); - kfree(audio); - return rc; -} - -static const struct file_operations audio_amrnb_fops = { - .owner = THIS_MODULE, - .open = audamrnb_open, - .release = audamrnb_release, - .read = audamrnb_read, - .write = audamrnb_write, - .unlocked_ioctl = audamrnb_ioctl, - .fsync = audamrnb_fsync, -}; - -struct miscdevice audio_amrnb_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_amrnb", - .fops = &audio_amrnb_fops, -}; - -static int __init audamrnb_init(void) -{ - return misc_register(&audio_amrnb_misc); -} - -static void __exit audamrnb_exit(void) -{ - misc_deregister(&audio_amrnb_misc); -} - -module_init(audamrnb_init); -module_exit(audamrnb_exit); - -MODULE_DESCRIPTION("MSM AMR-NB driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c b/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c deleted file mode 100644 index 43df851d7dca4b0b95af32480ee742597607590f..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c +++ /dev/null @@ -1,1526 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/audio_amrnb_in.c - * - * amrnb encoder device - * - * Copyright (c) 2009, 2011-2012 The Linux Foundation. All rights reserved. - * - * This code is based in part on arch/arm/mach-msm/qdsp5/audio_in.c, which is - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org. - * - */ - - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "audmgr.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define FRAME_HEADER_SIZE 8 /* 8 bytes frame header */ -#define NT_FRAME_HEADER_SIZE 24 /* 24 bytes frame header */ -/* FRAME_NUM must be a power of two */ -#define FRAME_NUM 8 -#define AMRNB_FRAME_SIZE 36 /* 36 bytes data */ -/*Tunnel mode : 1536 bytes data + 8 byte header*/ -#define FRAME_SIZE (AMRNB_FRAME_SIZE + FRAME_HEADER_SIZE) -/* 1536 bytes data + 24 meta field*/ -#define NT_FRAME_SIZE (AMRNB_FRAME_SIZE + NT_FRAME_HEADER_SIZE) -#define DMASZ (FRAME_SIZE * FRAME_NUM) -#define NT_DMASZ (NT_FRAME_SIZE * FRAME_NUM) -#define OUT_FRAME_NUM 2 -#define OUT_BUFFER_SIZE (4 * 1024 + NT_FRAME_HEADER_SIZE) -#define BUFFER_SIZE (OUT_BUFFER_SIZE * OUT_FRAME_NUM) - -/* Offset from beginning of buffer*/ -#define AUDPREPROC_AMRNB_EOS_FLG_OFFSET 0x0A -#define AUDPREPROC_AMRNB_EOS_FLG_MASK 0x01 -#define AUDPREPROC_AMRNB_EOS_NONE 0x0 /* No EOS detected */ -#define AUDPREPROC_AMRNB_EOS_SET 0x1 /* EOS set in meta field */ - -struct buffer { - void *data; - uint32_t size; - uint32_t read; - uint32_t addr; - uint32_t used; - uint32_t mfield_sz; -}; - -struct audio_amrnb_in { - struct buffer in[FRAME_NUM]; - - spinlock_t dsp_lock; - - atomic_t in_bytes; - atomic_t in_samples; - - struct mutex lock; - struct mutex read_lock; - wait_queue_head_t wait; - wait_queue_head_t wait_enable; - /*write section*/ - struct buffer out[OUT_FRAME_NUM]; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - uint32_t out_count; - - struct mutex write_lock; - wait_queue_head_t write_wait; - int32_t out_phys; /* physical address of write buffer */ - char *out_data; - uint8_t mfield; /* meta field embedded in data */ - uint8_t wflush; /*write flush */ - uint8_t rflush; /*read flush*/ - uint32_t out_frame_cnt; - - struct msm_adsp_module *audrec; - struct msm_adsp_module *audpre; - - - /* configuration to use on next enable */ - uint32_t samp_rate; - uint32_t channel_mode; - uint32_t buffer_size; - uint32_t enc_type; /* 0 for WAV ,1 for AAC,10 for AMRNB */ - uint32_t mode; /* T or NT Mode*/ - struct msm_audio_amrnb_enc_config amrnb_enc_cfg; - - uint32_t dsp_cnt; - uint32_t in_head; /* next buffer dsp will write */ - uint32_t in_tail; /* next buffer read() will read */ - uint32_t in_count; /* number of buffers available to read() */ - - uint32_t eos_ack; - uint32_t flush_ack; - - const char *module_name; - unsigned queue_ids; - uint16_t enc_id; /* Session Id */ - - unsigned short samp_rate_index; - uint32_t audrec_obj_idx ; - - struct audmgr audmgr; - - /* data allocated for various buffers */ - char *data; - dma_addr_t phys; - void *map_v_write; - - uint8_t opened; - uint8_t enabled; - uint8_t running; - uint8_t stopped; /* set when stopped, cleared on flush */ - struct ion_client *client; - struct ion_handle *input_buff_handle; - -}; - -struct audio_frame { - uint16_t frame_count_lsw; - uint16_t frame_count_msw; - uint16_t frame_length; - uint16_t erased_pcm; - unsigned char raw_bitstream[]; -} __packed; - -struct audio_frame_nt { - uint16_t metadata_len; - uint16_t frame_count_lsw; - uint16_t frame_count_msw; - uint16_t frame_length; - uint16_t erased_pcm; - uint16_t reserved; - uint16_t time_stamp_dword_lsw; - uint16_t time_stamp_dword_msw; - uint16_t time_stamp_lsw; - uint16_t time_stamp_msw; - uint16_t nflag_lsw; - uint16_t nflag_msw; - unsigned char raw_bitstream[]; /* samples */ -} __packed; - -struct amrnb_encoded_meta_out { - uint16_t metadata_len; - uint16_t time_stamp_dword_lsw; - uint16_t time_stamp_dword_msw; - uint16_t time_stamp_lsw; - uint16_t time_stamp_msw; - uint16_t nflag_lsw; - uint16_t nflag_msw; -}; - -/* Audrec Queue command sent macro's */ -#define audio_send_queue_pre(audio, cmd, len) \ - msm_adsp_write(audio->audpre, QDSP_uPAudPreProcCmdQueue, cmd, len) - -#define audio_send_queue_recbs(audio, cmd, len) \ - msm_adsp_write(audio->audrec, ((audio->queue_ids & 0xFFFF0000) >> 16),\ - cmd, len) -#define audio_send_queue_rec(audio, cmd, len) \ - msm_adsp_write(audio->audrec, (audio->queue_ids & 0x0000FFFF),\ - cmd, len) - -static int audamrnb_in_dsp_enable(struct audio_amrnb_in *audio, int enable); -static int audamrnb_in_encparam_config(struct audio_amrnb_in *audio); -static int audamrnb_in_encmem_config(struct audio_amrnb_in *audio); -static int audamrnb_in_dsp_read_buffer(struct audio_amrnb_in *audio, - uint32_t read_cnt); -static void audamrnb_in_flush(struct audio_amrnb_in *audio); - -static void audamrnb_in_get_dsp_frames(struct audio_amrnb_in *audio); -static int audpcm_config(struct audio_amrnb_in *audio); -static void audamrnb_out_flush(struct audio_amrnb_in *audio); -static int audamrnb_in_routing_mode_config(struct audio_amrnb_in *audio); -static void audrec_pcm_send_data(struct audio_amrnb_in *audio, unsigned needed); -static void audamrnb_nt_in_get_dsp_frames(struct audio_amrnb_in *audio); -static void audamrnb_in_flush(struct audio_amrnb_in *audio); - -static unsigned convert_samp_index(unsigned index) -{ - switch (index) { - case RPC_AUD_DEF_SAMPLE_RATE_48000: return 48000; - case RPC_AUD_DEF_SAMPLE_RATE_44100: return 44100; - case RPC_AUD_DEF_SAMPLE_RATE_32000: return 32000; - case RPC_AUD_DEF_SAMPLE_RATE_24000: return 24000; - case RPC_AUD_DEF_SAMPLE_RATE_22050: return 22050; - case RPC_AUD_DEF_SAMPLE_RATE_16000: return 16000; - case RPC_AUD_DEF_SAMPLE_RATE_12000: return 12000; - case RPC_AUD_DEF_SAMPLE_RATE_11025: return 11025; - case RPC_AUD_DEF_SAMPLE_RATE_8000: return 8000; - default: return 11025; - } -} - -/* must be called with audio->lock held */ -static int audamrnb_in_enable(struct audio_amrnb_in *audio) -{ - struct audmgr_config cfg; - int32_t rc; - - if (audio->enabled) - return 0; - - cfg.tx_rate = audio->samp_rate; - cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; - cfg.def_method = RPC_AUD_DEF_METHOD_RECORD; - cfg.codec = RPC_AUD_DEF_CODEC_AMR_NB; - cfg.snd_method = RPC_SND_METHOD_MIDI; - - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - rc = audmgr_enable(&audio->audmgr, &cfg); - if (rc < 0) - return rc; - - if (msm_adsp_enable(audio->audpre)) { - audmgr_disable(&audio->audmgr); - MM_ERR("msm_adsp_enable(audpre) failed\n"); - return -ENODEV; - } - } - if (msm_adsp_enable(audio->audrec)) { - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - audmgr_disable(&audio->audmgr); - msm_adsp_disable(audio->audpre); - } - MM_ERR("msm_adsp_enable(audrec) failed\n"); - return -ENODEV; - } - - audio->enabled = 1; - audamrnb_in_dsp_enable(audio, 1); - - return 0; -} - -/* must be called with audio->lock held */ -static int audamrnb_in_disable(struct audio_amrnb_in *audio) -{ - if (audio->enabled) { - audio->enabled = 0; - - audamrnb_in_dsp_enable(audio, 0); - - wake_up(&audio->wait); - wait_event_interruptible_timeout(audio->wait_enable, - audio->running == 0, 1*HZ); - msm_adsp_disable(audio->audrec); - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - msm_adsp_disable(audio->audpre); - audmgr_disable(&audio->audmgr); - } - } - return 0; -} - -/* ------------------- dsp --------------------- */ -static void audpre_dsp_event(void *data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - uint16_t msg[2]; - getevent(msg, sizeof(msg)); - - switch (id) { - case AUDPREPROC_MSG_CMD_CFG_DONE_MSG: - MM_DBG("type %d, status_flag %d\n", msg[0], msg[1]); - break; - case AUDPREPROC_MSG_ERROR_MSG_ID: - MM_ERR("err_index %d\n", msg[0]); - break; - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audpreproctask)\n"); - break; - default: - MM_ERR("unknown event %d\n", id); - } -} - -static void audamrnb_in_get_dsp_frames(struct audio_amrnb_in *audio) -{ - struct audio_frame *frame; - uint32_t index; - unsigned long flags; - index = audio->in_head; - - frame = (void *) (((char *)audio->in[index].data) - - sizeof(*frame)); - spin_lock_irqsave(&audio->dsp_lock, flags); - - /* Send Complete Transcoded Data, not actual frame part */ - audio->in[index].size = FRAME_SIZE - (sizeof(*frame)); - /* statistics of read */ - atomic_add(audio->in[index].size, &audio->in_bytes); - atomic_add(1, &audio->in_samples); - - audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1); - - /* If overflow, move the tail index foward. */ - if (audio->in_head == audio->in_tail) { - MM_ERR("Error! not able to keep up the read\n"); - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - MM_ERR("in_count = %d\n", audio->in_count); - } else - audio->in_count++; - - audamrnb_in_dsp_read_buffer(audio, audio->dsp_cnt++); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - - wake_up(&audio->wait); -} - -static void audamrnb_nt_in_get_dsp_frames(struct audio_amrnb_in *audio) -{ - struct audio_frame_nt *nt_frame; - uint32_t index; - unsigned long flags; - - index = audio->in_head; - nt_frame = (void *) (((char *)audio->in[index].data) - \ - sizeof(struct audio_frame_nt)); - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->in[index].size = nt_frame->frame_length; - /* statistics of read */ - atomic_add(audio->in[index].size, &audio->in_bytes); - atomic_add(1, &audio->in_samples); - - audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1); - - /* If overflow, move the tail index foward. */ - if (audio->in_head == audio->in_tail) - MM_DBG("Error! not able to keep up the read\n"); - else - audio->in_count++; - - spin_unlock_irqrestore(&audio->dsp_lock, flags); - wake_up(&audio->wait); -} - -static int audrec_pcm_buffer_ptr_refresh(struct audio_amrnb_in *audio, - unsigned idx, unsigned len) -{ - struct audrec_cmd_pcm_buffer_ptr_refresh_arm_enc cmd; - - if (len == NT_FRAME_HEADER_SIZE) - len = len / 2; - else - len = (len + NT_FRAME_HEADER_SIZE) / 2; - MM_DBG("len = %d\n", len); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_PCM_BUFFER_PTR_REFRESH_ARM_TO_ENC; - cmd.num_buffers = 1; - if (cmd.num_buffers == 1) { - cmd.buf_address_length[0] = (audio->out[idx].addr & - 0xffff0000) >> 16; - cmd.buf_address_length[1] = (audio->out[idx].addr & - 0x0000ffff); - cmd.buf_address_length[2] = (len & 0xffff0000) >> 16; - cmd.buf_address_length[3] = (len & 0x0000ffff); - } - audio->out_frame_cnt++; - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audpcm_config(struct audio_amrnb_in *audio) -{ - struct audrec_cmd_pcm_cfg_arm_to_enc cmd; - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_PCM_CFG_ARM_TO_ENC; - cmd.config_update_flag = AUDREC_PCM_CONFIG_UPDATE_FLAG_ENABLE; - cmd.enable_flag = AUDREC_ENABLE_FLAG_VALUE; - cmd.sampling_freq = convert_samp_index(audio->samp_rate); - if (!audio->channel_mode) - cmd.channels = 1; - else - cmd.channels = 2; - cmd.frequency_of_intimation = 1; - cmd.max_number_of_buffers = OUT_FRAME_NUM; - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - - -static int audamrnb_in_routing_mode_config(struct audio_amrnb_in *audio) -{ - struct audrec_cmd_routing_mode cmd; - - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_ROUTING_MODE; - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) - cmd.routing_mode = 1; - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static void audrec_dsp_event(void *data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - struct audio_amrnb_in *audio = data; - if (data) - audio = data; - else { - MM_ERR("invalid data for event %x\n", id); - return; - } - - switch (id) { - case AUDREC_MSG_CMD_CFG_DONE_MSG: { - struct audrec_msg_cmd_cfg_done_msg cmd_cfg_done_msg; - getevent(&cmd_cfg_done_msg, AUDREC_MSG_CMD_CFG_DONE_MSG_LEN); - if (cmd_cfg_done_msg.audrec_enc_type & \ - AUDREC_MSG_CFG_DONE_ENC_ENA) { - audio->audrec_obj_idx = cmd_cfg_done_msg.audrec_obj_idx; - MM_DBG("CFG ENABLED\n"); - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) { - MM_DBG("routing command\n"); - audamrnb_in_routing_mode_config(audio); - } else { - audamrnb_in_encmem_config(audio); - } - } else { - MM_DBG("CFG SLEEP\n"); - audio->running = 0; - wake_up(&audio->wait_enable); - } - break; - } - case AUDREC_MSG_CMD_ROUTING_MODE_DONE_MSG: { - struct audrec_msg_cmd_routing_mode_done_msg \ - routing_msg; - getevent(&routing_msg, AUDREC_MSG_CMD_ROUTING_MODE_DONE_MSG); - MM_DBG("AUDREC_MSG_CMD_ROUTING_MODE_DONE_MSG"); - if (routing_msg.configuration == 0) { - MM_ERR("routing configuration failed\n"); - audio->running = 0; - wake_up(&audio->wait_enable); - } else - audamrnb_in_encmem_config(audio); - break; - } - case AUDREC_MSG_CMD_AREC_MEM_CFG_DONE_MSG: { - MM_DBG("AREC_MEM_CFG_DONE_MSG\n"); - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - audamrnb_in_encparam_config(audio); - else - audpcm_config(audio); - break; - } - - case AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG: { - MM_DBG("AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG"); - audamrnb_in_encparam_config(audio); - break; - } - case AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG: { - MM_DBG("AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG\n"); - audio->running = 1; - wake_up(&audio->wait_enable); - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) - audrec_pcm_send_data(audio, 1); - break; - } - case AUDREC_CMD_PCM_BUFFER_PTR_UPDATE_ARM_TO_ENC_MSG: { - MM_DBG("ptr_update recieved from DSP\n"); - audrec_pcm_send_data(audio, 1); - break; - } - case AUDREC_MSG_NO_EXT_PKT_AVAILABLE_MSG: { - struct audrec_msg_no_ext_pkt_avail_msg err_msg; - getevent(&err_msg, AUDREC_MSG_NO_EXT_PKT_AVAILABLE_MSG_LEN); - MM_DBG("NO_EXT_PKT_AVAILABLE_MSG %x\n",\ - err_msg.audrec_err_id); - break; - } - case AUDREC_MSG_PACKET_READY_MSG: { - struct audrec_msg_packet_ready_msg pkt_ready_msg; - - getevent(&pkt_ready_msg, AUDREC_MSG_PACKET_READY_MSG_LEN); - MM_DBG("UP_PACKET_READY_MSG: write cnt msw %d \ - write cnt lsw %d read cnt msw %d read cnt lsw %d \n",\ - pkt_ready_msg.pkt_counter_msw, \ - pkt_ready_msg.pkt_counter_lsw, \ - pkt_ready_msg.pkt_read_cnt_msw, \ - pkt_ready_msg.pkt_read_cnt_lsw); - - audamrnb_in_get_dsp_frames(audio); - break; - } - case AUDREC_UP_NT_PACKET_READY_MSG: { - struct audrec_up_nt_packet_ready_msg pkt_ready_msg; - - getevent(&pkt_ready_msg, AUDREC_UP_NT_PACKET_READY_MSG_LEN); - MM_DBG("UP_NT_PACKET_READY_MSG: write cnt lsw %d \ - write cnt msw %d read cnt lsw %d read cnt msw %d \n",\ - pkt_ready_msg.audrec_packetwrite_cnt_lsw, \ - pkt_ready_msg.audrec_packetwrite_cnt_msw, \ - pkt_ready_msg.audrec_upprev_readcount_lsw, \ - pkt_ready_msg.audrec_upprev_readcount_msw); - - audamrnb_nt_in_get_dsp_frames(audio); - break; - } - case AUDREC_CMD_FLUSH_DONE_MSG: { - audio->wflush = 0; - audio->rflush = 0; - audio->flush_ack = 1; - wake_up(&audio->write_wait); - MM_DBG("flush ack recieved\n"); - break; - } - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module \ - enable/disable(audrectask)\n"); - break; - default: - MM_ERR("unknown event %d\n", id); - } -} - -struct msm_adsp_ops audpre_amrnb_adsp_ops = { - .event = audpre_dsp_event, -}; - -struct msm_adsp_ops audrec_amrnb_adsp_ops = { - .event = audrec_dsp_event, -}; - -static int audamrnb_in_dsp_enable(struct audio_amrnb_in *audio, int enable) -{ - struct audrec_cmd_enc_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_ENC_CFG; - cmd.audrec_enc_type = (audio->enc_type & 0xFF) | - (enable ? AUDREC_CMD_ENC_ENA : AUDREC_CMD_ENC_DIS); - /* Don't care on enable, required on disable */ - cmd.audrec_obj_idx = audio->audrec_obj_idx; - - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audamrnb_in_encmem_config(struct audio_amrnb_in *audio) -{ - struct audrec_cmd_arecmem_cfg cmd; - uint16_t *data = (void *) audio->data; - uint8_t n; - uint16_t header_len = 0; - - memset(&cmd, 0, sizeof(cmd)); - - cmd.cmd_id = AUDREC_CMD_ARECMEM_CFG; - cmd.audrec_obj_idx = audio->audrec_obj_idx; - /* Rate at which packet complete message comes */ - cmd.audrec_up_pkt_intm_cnt = 1; - cmd.audrec_extpkt_buffer_msw = audio->phys >> 16; - cmd.audrec_extpkt_buffer_lsw = audio->phys; - /* Max Buffer no available for frames */ - cmd.audrec_extpkt_buffer_num = FRAME_NUM; - - /* prepare buffer pointers: - * T:36 bytes amrnb packet + 4 halfword header - * NT:36 bytes amrnb packet + 12 halfword header - */ - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - header_len = FRAME_HEADER_SIZE/2; - else - header_len = NT_FRAME_HEADER_SIZE/2; - - for (n = 0; n < FRAME_NUM; n++) { - audio->in[n].data = data + header_len; - data += (AMRNB_FRAME_SIZE/2) + header_len; - MM_DBG("0x%8x\n", (uint32_t)(audio->in[n].data - header_len*2)); - } - - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audamrnb_in_encparam_config(struct audio_amrnb_in *audio) -{ - struct audrec_cmd_arecparam_amrnb_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - - cmd.common.cmd_id = AUDREC_CMD_ARECPARAM_CFG; - cmd.common.audrec_obj_idx = audio->audrec_obj_idx; - cmd.samp_rate_idx = audio->samp_rate_index; /* 8k Sampling rate */ - cmd.voicememoencweight1 = audio->amrnb_enc_cfg.voicememoencweight1; - cmd.voicememoencweight2 = audio->amrnb_enc_cfg.voicememoencweight2; - cmd.voicememoencweight3 = audio->amrnb_enc_cfg.voicememoencweight3; - cmd.voicememoencweight4 = audio->amrnb_enc_cfg.voicememoencweight4; - cmd.update_mode = 0x8000 | 0x0000; - cmd.dtx_mode = audio->amrnb_enc_cfg.dtx_mode_enable; - cmd.test_mode = audio->amrnb_enc_cfg.test_mode_enable; - cmd.used_mode = audio->amrnb_enc_cfg.enc_mode; - - MM_DBG("cmd.common.cmd_id = 0x%4x\n", cmd.common.cmd_id); - MM_DBG("cmd.common.audrec_obj_idx = 0x%4x\n", - cmd.common.audrec_obj_idx); - MM_DBG("cmd.samp_rate_idx = 0x%4x\n", cmd.samp_rate_idx); - MM_DBG("cmd.voicememoencweight1 = 0x%4x\n", - cmd.voicememoencweight1); - MM_DBG("cmd.voicememoencweight2 = 0x%4x\n", - cmd.voicememoencweight2); - MM_DBG("cmd.voicememoencweight3 = 0x%4x\n", - cmd.voicememoencweight3); - MM_DBG("cmd.voicememoencweight4 = 0x%4x\n", - cmd.voicememoencweight4); - MM_DBG("cmd.update_mode = 0x%4x\n", cmd.update_mode); - MM_DBG("cmd.dtx_mode = 0x%4x\n", cmd.dtx_mode); - MM_DBG("cmd.test_mode = 0x%4x\n", cmd.test_mode); - MM_DBG("cmd.used_mode = 0x%4x\n", cmd.used_mode); - - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audamrnb_flush_command(struct audio_amrnb_in *audio) -{ - struct audrec_cmd_flush cmd; - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_FLUSH; - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} -static int audamrnb_in_dsp_read_buffer(struct audio_amrnb_in *audio, - uint32_t read_cnt) -{ - audrec_cmd_packet_ext_ptr cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_PACKET_EXT_PTR; - cmd.type = audio->audrec_obj_idx; - cmd.curr_rec_count_msw = read_cnt >> 16; - cmd.curr_rec_count_lsw = read_cnt; - - return audio_send_queue_recbs(audio, &cmd, sizeof(cmd)); -} - -/* ------------------- device --------------------- */ - -static void audamrnb_ioport_reset(struct audio_amrnb_in *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audamrnb_in_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->wait); - mutex_lock(&audio->read_lock); - audamrnb_out_flush(audio); - mutex_unlock(&audio->read_lock); -} - -static void audamrnb_in_flush(struct audio_amrnb_in *audio) -{ - uint8_t i; - - audio->dsp_cnt = 0; - audio->in_head = 0; - audio->in_tail = 0; - audio->in_count = 0; - audio->eos_ack = 0; - for (i = FRAME_NUM-1; i >= 0; i--) { - audio->in[i].size = 0; - audio->in[i].read = 0; - } - MM_DBG("in_bytes %d\n", atomic_read(&audio->in_bytes)); - MM_DBG("in_samples %d\n", atomic_read(&audio->in_samples)); - atomic_set(&audio->in_bytes, 0); - atomic_set(&audio->in_samples, 0); -} - -static void audamrnb_out_flush(struct audio_amrnb_in *audio) -{ - uint8_t i; - - audio->out_head = 0; - audio->out_tail = 0; - audio->out_count = 0; - for (i = OUT_FRAME_NUM-1; i >= 0; i--) { - audio->out[i].size = 0; - audio->out[i].read = 0; - audio->out[i].used = 0; - } -} - -/* ------------------- device --------------------- */ -static long audamrnb_in_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct audio_amrnb_in *audio = file->private_data; - int32_t rc = 0; - - MM_DBG("\n"); - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = atomic_read(&audio->in_bytes); - stats.sample_count = atomic_read(&audio->in_samples); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return rc; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: { - rc = audamrnb_in_enable(audio); - if (!rc) { - rc = - wait_event_interruptible_timeout(audio->wait_enable, - audio->running != 0, 1*HZ); - MM_INFO("state %d rc = %d\n", audio->running, rc); - - if (audio->running == 0) - rc = -ENODEV; - else - rc = 0; - } - audio->stopped = 0; - break; - } - case AUDIO_STOP: { - rc = audamrnb_in_disable(audio); - audio->stopped = 1; - break; - } - case AUDIO_FLUSH: { - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audamrnb_ioport_reset(audio); - if (audio->running) { - audamrnb_flush_command(audio); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config cfg; - memset(&cfg, 0, sizeof(cfg)); - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) { - cfg.buffer_size = OUT_BUFFER_SIZE; - cfg.buffer_count = OUT_FRAME_NUM; - } else { - cfg.buffer_size = audio->buffer_size; - cfg.buffer_count = FRAME_NUM; - } - cfg.sample_rate = convert_samp_index(audio->samp_rate); - cfg.channel_count = 1; - cfg.type = 0; - cfg.unused[0] = 0; - cfg.unused[1] = 0; - cfg.unused[2] = 0; - if (copy_to_user((void *) arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_GET_STREAM_CONFIG: { - struct msm_audio_stream_config cfg; - memset(&cfg, 0, sizeof(cfg)); - cfg.buffer_size = audio->buffer_size; - cfg.buffer_count = FRAME_NUM; - if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_STREAM_CONFIG: { - struct msm_audio_stream_config cfg; - if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - /* Allow only single frame */ - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - if (cfg.buffer_size != (FRAME_SIZE - 8)) { - rc = -EINVAL; - break; - } - } else { - if (cfg.buffer_size != (AMRNB_FRAME_SIZE + 14)) { - rc = -EINVAL; - break; - } - } - audio->buffer_size = cfg.buffer_size; - break; - } - - case AUDIO_GET_AMRNB_ENC_CONFIG: { - if (copy_to_user((void *)arg, &audio->amrnb_enc_cfg, - sizeof(audio->amrnb_enc_cfg))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_AMRNB_ENC_CONFIG: { - struct msm_audio_amrnb_enc_config cfg; - if (copy_from_user - (&cfg, (void *)arg, sizeof(cfg))) { - rc = -EFAULT; - } else - rc = 0; - audio->amrnb_enc_cfg.voicememoencweight1 = - cfg.voicememoencweight1; - audio->amrnb_enc_cfg.voicememoencweight2 = - cfg.voicememoencweight2; - audio->amrnb_enc_cfg.voicememoencweight3 = - cfg.voicememoencweight3; - audio->amrnb_enc_cfg.voicememoencweight4 = - cfg.voicememoencweight4; - audio->amrnb_enc_cfg.dtx_mode_enable = cfg.dtx_mode_enable; - audio->amrnb_enc_cfg.test_mode_enable = cfg.test_mode_enable; - audio->amrnb_enc_cfg.enc_mode = cfg.enc_mode; - /* Run time change of Param */ - break; - } - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -static ssize_t audamrnb_in_read(struct file *file, - char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_amrnb_in *audio = file->private_data; - unsigned long flags; - const char __user *start = buf; - void *data; - uint32_t index; - uint32_t size; - int32_t rc = 0; - struct amrnb_encoded_meta_out meta_field; - struct audio_frame_nt *nt_frame; - MM_DBG("count = %d\n", count); - mutex_lock(&audio->read_lock); - while (count > 0) { - rc = wait_event_interruptible( - audio->wait, (audio->in_count > 0) || audio->stopped || - audio->rflush); - if (rc < 0) - break; - - if (audio->rflush) { - rc = -EBUSY; - break; - } - if (audio->stopped && !audio->in_count) { - MM_DBG("Driver in stop state, No more buffer to read"); - rc = 0;/* End of File */ - break; - } - - index = audio->in_tail; - data = (uint8_t *) audio->in[index].data; - size = audio->in[index].size; - - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) { - nt_frame = (struct audio_frame_nt *)(data - - sizeof(struct audio_frame_nt)); - memcpy((char *)&meta_field.time_stamp_dword_lsw, - (char *)&nt_frame->time_stamp_dword_lsw, - (sizeof(struct amrnb_encoded_meta_out) - \ - sizeof(uint16_t))); - meta_field.metadata_len = - sizeof(struct amrnb_encoded_meta_out); - if (copy_to_user((char *)start, (char *)&meta_field, - sizeof(struct amrnb_encoded_meta_out))) { - rc = -EFAULT; - break; - } - if (nt_frame->nflag_lsw & 0x0001) { - MM_ERR("recieved EOS in read call\n"); - audio->eos_ack = 1; - } - buf += sizeof(struct amrnb_encoded_meta_out); - count -= sizeof(struct amrnb_encoded_meta_out); - } - if (count >= size) { - /* order the reads on the buffer */ - dma_coherent_post_ops(); - if (copy_to_user(buf, data, size)) { - rc = -EFAULT; - break; - } - spin_lock_irqsave(&audio->dsp_lock, flags); - if (index != audio->in_tail) { - /* overrun -- data is - * invalid and we need to retry */ - spin_unlock_irqrestore(&audio->dsp_lock, flags); - continue; - } - audio->in[index].size = 0; - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - audio->in_count--; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - count -= size; - buf += size; - if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL)) { - if (!audio->eos_ack) { - MM_DBG("sending read ptr command \ - %d %d\n", - audio->dsp_cnt, - audio->in_tail); - audamrnb_in_dsp_read_buffer(audio, - audio->dsp_cnt++); - } - } - } else { - MM_ERR("short read\n"); - break; - } - - } - mutex_unlock(&audio->read_lock); - - if (buf > start) - return buf - start; - - return rc; -} - -static void audrec_pcm_send_data(struct audio_amrnb_in *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - MM_DBG("\n"); - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - audrec_pcm_buffer_ptr_refresh(audio, - audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } - done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static int audamrnb_in_fsync(struct file *file, loff_t a, loff_t b, int datasync) - -{ - struct audio_amrnb_in *audio = file->private_data; - int32_t rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - if (!audio->running || (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - audio->wflush); - MM_DBG("waked on by some event audio->wflush = %d\n", audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; - -} - -int audrec_amrnb_process_eos(struct audio_amrnb_in *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - struct buffer *frame; - int32_t rc = 0; - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - MM_DBG("copying meta_out frame->used = %d\n", frame->used); - audrec_pcm_send_data(audio, 0); -done: - return rc; -} - -static ssize_t audamrnb_in_write(struct file *file, - const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_amrnb_in *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - char *cpy_ptr; - int32_t rc = 0, eos_condition = AUDPREPROC_AMRNB_EOS_NONE; - unsigned short mfield_size = 0; - int32_t write_count = 0; - MM_DBG("cnt=%d\n", count); - - if (count & 1) - return -EINVAL; - - if (audio->mode != MSM_AUD_ENC_MODE_NONTUNNEL) - return -EINVAL; - - mutex_lock(&audio->write_lock); - frame = audio->out + audio->out_head; - /* if supplied count is more than driver buffer size - * then only copy driver buffer size - */ - if (count > frame->size) - count = frame->size; - - write_count = count; - cpy_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - goto error; - - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto error; - } - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - goto error; - } else if (mfield_size > count) { - rc = -EINVAL; - goto error; - } - MM_DBG("mf offset_val %x\n", mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - goto error; - } - /* Check if EOS flag is set and buffer has - * contains just meta field - */ - if (cpy_ptr[AUDPREPROC_AMRNB_EOS_FLG_OFFSET] & - AUDPREPROC_AMRNB_EOS_FLG_MASK) { - eos_condition = AUDPREPROC_AMRNB_EOS_SET; - MM_DBG("EOS SET\n"); - if (mfield_size == count) { - buf += mfield_size; - eos_condition = 0; - goto exit; - } else - cpy_ptr[AUDPREPROC_AMRNB_EOS_FLG_OFFSET] &= - ~AUDPREPROC_AMRNB_EOS_FLG_MASK; - } - cpy_ptr += mfield_size; - count -= mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - MM_DBG("copying the stream count = %d\n", count); - if (copy_from_user(cpy_ptr, buf, count)) { - rc = -EFAULT; - goto error; - } -exit: - frame->used = count; - audio->out_head ^= 1; - if (!audio->flush_ack) - audrec_pcm_send_data(audio, 0); - else { - audrec_pcm_send_data(audio, 1); - audio->flush_ack = 0; - } - if (eos_condition == AUDPREPROC_AMRNB_EOS_SET) - rc = audrec_amrnb_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - return write_count; -error: - mutex_unlock(&audio->write_lock); - return rc; -} - -static int audamrnb_in_release(struct inode *inode, struct file *file) -{ - struct audio_amrnb_in *audio = file->private_data; - int32_t dma_size = 0; - mutex_lock(&audio->lock); - audamrnb_in_disable(audio); - audamrnb_in_flush(audio); - msm_adsp_put(audio->audrec); - - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - msm_adsp_put(audio->audpre); - - audpreproc_aenc_free(audio->enc_id); - audio->audrec = NULL; - audio->audpre = NULL; - audio->opened = 0; - if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) && \ - (audio->out_data)) { - ion_unmap_kernel(audio->client, audio->input_buff_handle); - ion_free(audio->client, audio->input_buff_handle); - audio->out_data = NULL; - } - if (audio->data) { - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - dma_size = DMASZ; - else - dma_size = NT_DMASZ; - - dma_free_coherent(NULL, - dma_size, audio->data, audio->phys); - audio->data = NULL; - } - ion_client_destroy(audio->client); - mutex_unlock(&audio->lock); - return 0; -} - -struct audio_amrnb_in the_audio_amrnb_in; - -static int audamrnb_in_open(struct inode *inode, struct file *file) -{ - struct audio_amrnb_in *audio = &the_audio_amrnb_in; - int32_t rc; - int encid; - int32_t dma_size = 0; - int len = 0; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - struct ion_client *client = NULL; - - mutex_lock(&audio->lock); - if (audio->opened) { - rc = -EBUSY; - goto done; - } - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - audio->mode = MSM_AUD_ENC_MODE_NONTUNNEL; - dma_size = NT_DMASZ; - MM_DBG("Opened for non tunnel mode encoding\n"); - } else if (!(file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - audio->mode = MSM_AUD_ENC_MODE_TUNNEL; - dma_size = DMASZ; - MM_DBG("Opened for tunnel mode encoding\n"); - } else { - MM_ERR("Invalid mode\n"); - rc = -EACCES; - goto done; - } - - /* Settings will be re-config at AUDIO_SET_CONFIG, - * but at least we need to have initial config - */ - audio->samp_rate = RPC_AUD_DEF_SAMPLE_RATE_8000, - audio->samp_rate_index = AUDREC_CMD_SAMP_RATE_INDX_8000; - audio->channel_mode = AUDREC_CMD_STEREO_MODE_MONO; - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) - audio->buffer_size = (AMRNB_FRAME_SIZE + 14); - else - audio->buffer_size = (FRAME_SIZE - 8); - audio->enc_type = AUDREC_CMD_TYPE_0_INDEX_AMRNB | audio->mode; - - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - rc = audmgr_open(&audio->audmgr); - if (rc) - goto done; - } - audio->amrnb_enc_cfg.voicememoencweight1 = 0x0000; - audio->amrnb_enc_cfg.voicememoencweight2 = 0x0000; - audio->amrnb_enc_cfg.voicememoencweight3 = 0x4000; - audio->amrnb_enc_cfg.voicememoencweight4 = 0x0000; - audio->amrnb_enc_cfg.dtx_mode_enable = 0; - audio->amrnb_enc_cfg.test_mode_enable = 0; - audio->amrnb_enc_cfg.enc_mode = 7; - - encid = audpreproc_aenc_alloc(audio->enc_type, &audio->module_name, - &audio->queue_ids); - if (encid < 0) { - MM_ERR("No free encoder available\n"); - rc = -ENODEV; - goto done; - } - audio->enc_id = encid; - rc = msm_adsp_get(audio->module_name, &audio->audrec, - &audrec_amrnb_adsp_ops, audio); - if (rc) { - audpreproc_aenc_free(audio->enc_id); - goto done; - } - - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre, - &audpre_amrnb_adsp_ops, audio); - if (rc) { - msm_adsp_put(audio->audrec); - audpreproc_aenc_free(audio->enc_id); - goto done; - } - } - audio->dsp_cnt = 0; - audio->stopped = 0; - audio->wflush = 0; - audio->rflush = 0; - audio->flush_ack = 0; - - audamrnb_in_flush(audio); - audamrnb_out_flush(audio); - /* used dma_allco_coherent for backward compatibility with 7x27 */ - audio->data = dma_alloc_coherent(NULL, dma_size, - &audio->phys, GFP_KERNEL); - if (!audio->data) { - MM_ERR("Unable to allocate DMA buffer\n"); - goto evt_error; - } - - client = msm_ion_client_create(UINT_MAX, "Audio_AMRNB_in_client"); - if (IS_ERR_OR_NULL(client)) { - MM_ERR("Unable to create ION client\n"); - rc = -ENOMEM; - goto client_create_error; - } - audio->client = client; - - audio->out_data = NULL; - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) { - MM_DBG("allocating BUFFER_SIZE %d\n", BUFFER_SIZE); - handle = ion_alloc(client, BUFFER_SIZE, - SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to create allocate write buffers\n"); - rc = -ENOMEM; - goto input_buff_alloc_error; - } - - audio->input_buff_handle = handle; - - rc = ion_phys(client , handle, &addr, &len); - if (rc) { - MM_ERR("I/P buffers:Invalid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - rc = -ENOMEM; - goto input_buff_get_phys_error; - } else { - MM_INFO("Got valid phy: %x sz: %x\n", - (unsigned int) addr, - (unsigned int) len); - } - audio->out_phys = (int32_t)addr; - - rc = ion_handle_get_flags(client, - handle, &ionflag); - if (rc) { - MM_ERR("could not get flags for the handle\n"); - rc = -ENOMEM; - goto input_buff_get_flags_error; - } - - audio->map_v_write = ion_map_kernel(client, handle); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write buffers\n"); - rc = -ENOMEM; - goto input_buff_map_error; - } - audio->out_data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n", - (unsigned int)addr, - (unsigned int)audio->out_data); - - /* Initialize buffer */ - audio->out[0].data = audio->out_data + 0; - audio->out[0].addr = audio->out_phys + 0; - audio->out[0].size = OUT_BUFFER_SIZE; - - audio->out[1].data = audio->out_data + OUT_BUFFER_SIZE; - audio->out[1].addr = audio->out_phys + OUT_BUFFER_SIZE; - audio->out[1].size = OUT_BUFFER_SIZE; - - MM_DBG("audio->out[0].data = %d audio->out[1].data = %d", - (uint32_t)audio->out[0].data, - (uint32_t)audio->out[1].data); - audio->mfield = NT_FRAME_HEADER_SIZE; - audio->out_frame_cnt++; - } - file->private_data = audio; - audio->opened = 1; - -done: - mutex_unlock(&audio->lock); - return rc; -input_buff_map_error: -input_buff_get_phys_error: -input_buff_get_flags_error: - ion_free(client, audio->input_buff_handle); -input_buff_alloc_error: - ion_client_destroy(client); -client_create_error: - dma_free_coherent(NULL, dma_size, audio->data, audio->phys); -evt_error: - msm_adsp_put(audio->audrec); - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - msm_adsp_put(audio->audpre); - - audpreproc_aenc_free(audio->enc_id); - mutex_unlock(&audio->lock); - return rc; -} - -static const struct file_operations audio_fops = { - .owner = THIS_MODULE, - .open = audamrnb_in_open, - .release = audamrnb_in_release, - .read = audamrnb_in_read, - .write = audamrnb_in_write, - .fsync = audamrnb_in_fsync, - .unlocked_ioctl = audamrnb_in_ioctl, -}; - -struct miscdevice audamrnb_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_amrnb_in", - .fops = &audio_fops, -}; - -#ifdef CONFIG_DEBUG_FS -static ssize_t audamrnb_in_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audamrnb_in_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int32_t debug_bufmax = 1024; - static char buffer[1024]; - int32_t n = 0, i; - struct audio_amrnb_in *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "audrec_obj_idx %d\n", audio->audrec_obj_idx); - n += scnprintf(buffer + n, debug_bufmax - n, - "dsp_cnt %d \n", audio->dsp_cnt); - n += scnprintf(buffer + n, debug_bufmax - n, - "in_count %d \n", audio->in_count); - for (i = 0; i < FRAME_NUM; i++) - n += scnprintf(buffer + n, debug_bufmax - n, - "audio->in[%d].size %d \n", i, audio->in[i].size); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when record halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d \n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "buffer_size %d \n", audio->buffer_size); - n += scnprintf(buffer + n, debug_bufmax - n, - "in_head %d \n", audio->in_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "in_tail %d \n", audio->in_tail); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audamrnb_in_debug_fops = { - .read = audamrnb_in_debug_read, - .open = audamrnb_in_debug_open, -}; -#endif - -static int __init audamrnb_in_init(void) -{ -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - - mutex_init(&the_audio_amrnb_in.lock); - mutex_init(&the_audio_amrnb_in.read_lock); - spin_lock_init(&the_audio_amrnb_in.dsp_lock); - init_waitqueue_head(&the_audio_amrnb_in.wait); - init_waitqueue_head(&the_audio_amrnb_in.wait_enable); - mutex_init(&the_audio_amrnb_in.write_lock); - init_waitqueue_head(&the_audio_amrnb_in.write_wait); - -#ifdef CONFIG_DEBUG_FS - dentry = debugfs_create_file("msm_amrnb_in", S_IFREG | S_IRUGO, NULL, - (void *) &the_audio_amrnb_in, &audamrnb_in_debug_fops); - - if (IS_ERR(dentry)) - MM_ERR("debugfs_create_file failed\n"); -#endif - return misc_register(&audamrnb_in_misc); -} - -static void __exit audamrnb_in_exit(void) -{ - misc_deregister(&audamrnb_in_misc); -} - -module_init(audamrnb_in_init); -module_exit(audamrnb_in_exit); - -MODULE_DESCRIPTION("MSM AMRNB Encoder driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5/audio_amrwb.c b/arch/arm/mach-msm/qdsp5/audio_amrwb.c deleted file mode 100644 index 71100a6735f00d8dc92ebb34a46043a6dbce8ff9..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_amrwb.c +++ /dev/null @@ -1,1768 +0,0 @@ -/* linux/arch/arm/mach-msm/qdsp5/audio_amrwb.c - * - * amrwb audio decoder device - * - * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009, 2011-2012 The Linux Foundation. All rights reserved. - * - * All source code in this file is licensed under the following license except - * where indicated. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "audmgr.h" - -#define BUFSZ 4110 /* Hold minimum 700ms voice data and 14 bytes of meta in*/ -#define DMASZ (BUFSZ * 2) - -#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF -#define AUDDEC_DEC_AMRWB 11 - -#define PCM_BUFSZ_MIN 8216 /* 100ms worth of data and 24 bytes of meta out*/ -#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most - but support 2 buffers currently */ -#define ROUTING_MODE_FTRT 1 -#define ROUTING_MODE_RT 2 -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDAMRWB_METAFIELD_MASK 0xFFFF0000 -#define AUDAMRWB_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */ -#define AUDAMRWB_EOS_FLG_MASK 0x01 -#define AUDAMRWB_EOS_NONE 0x0 /* No EOS detected */ -#define AUDAMRWB_EOS_SET 0x1 /* EOS set in meta field */ - -#define AUDAMRWB_EVENT_NUM 10 /* Default number of pre-allocated event pkts */ - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; - unsigned short mfield_sz; /*only useful for data has meta field */ -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audamrwb_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct audamrwb_event{ - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audio { - struct buffer out[2]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - /* Host PCM section */ - struct buffer in[PCM_BUF_MAX_COUNT]; - struct mutex read_lock; - wait_queue_head_t read_wait; /* Wait queue for read */ - char *read_data; /* pointer to reader buffer */ - int32_t read_phys; /* physical address of reader buffer */ - uint8_t read_next; /* index to input buffers to be read next */ - uint8_t fill_next; /* index to buffer that DSP should be filling */ - uint8_t pcm_buf_count; /* number of pcm buffer allocated */ - /* ---- End of Host PCM section */ - - struct msm_adsp_module *audplay; - struct audmgr audmgr; - - /* configuration to use on next enable */ - uint32_t out_sample_rate; - uint32_t out_channel_mode; - - /* data allocated for various buffers */ - char *data; - int32_t phys; /* physical address of write buffer */ - void *map_v_read; - void *map_v_write; - int mfield; /* meta field embedded in data */ - int rflush; /* Read flush */ - int wflush; /* Write flush */ - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - int pcm_feedback; - int buf_refresh; - int rmt_resource_released; - int teos; /* valid only if tunnel mode & no data left for decoder */ - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - int reserved; /* A byte is being reserved */ - char rsv_byte; /* Handle odd length user data */ - - const char *module_name; - unsigned queue_id; - uint16_t dec_id; - uint32_t read_ptr_offset; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audamrwb_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - - int eq_enable; - int eq_needs_commit; - audpp_cmd_cfg_object_params_eqalizer eq; - audpp_cmd_cfg_object_params_volume vol_pan; - struct ion_client *client; - struct ion_handle *input_buff_handle; - struct ion_handle *output_buff_handle; -}; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audpp_cmd_cfg_adec_params(struct audio *audio); -static void audpp_cmd_cfg_routing_mode(struct audio *audio); -static void audamrwb_send_data(struct audio *audio, unsigned needed); -static void audamrwb_config_hostpcm(struct audio *audio); -static void audamrwb_buffer_refresh(struct audio *audio); -static void audamrwb_dsp_event(void *private, unsigned id, uint16_t *msg); -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audamrwb_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); -#endif - -static int rmt_put_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_DISABLE; - cmd.dec_type = AUDDEC_DEC_AMRWB; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - - return put_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -static int rmt_get_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_ENABLE; - cmd.dec_type = AUDDEC_DEC_AMRWB; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - - return get_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -/* must be called with audio->lock held */ -static int audamrwb_enable(struct audio *audio) -{ - struct audmgr_config cfg; - int rc; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (audio->enabled) - return 0; - - if (audio->rmt_resource_released == 1) { - audio->rmt_resource_released = 0; - rc = rmt_get_resource(audio); - if (rc) { - MM_ERR("ADSP resources are not available for AMRWB \ - session 0x%08x on decoder: %d\n Ignoring \ - error and going ahead with the playback\n", - (int)audio, audio->dec_id); - } - } - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_tail = 0; - audio->out_needed = 0; - - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) { - cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; - cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000; - cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK; - cfg.codec = RPC_AUD_DEF_CODEC_AMR_WB; - cfg.snd_method = RPC_SND_METHOD_MIDI; - - rc = audmgr_enable(&audio->audmgr, &cfg); - if (rc < 0) - return rc; - } - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audamrwb_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - audio->enabled = 1; - return 0; -} - -/* must be called with audio->lock held */ -static int audamrwb_disable(struct audio *audio) -{ - int rc = 0; - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - audio->stopped = 1; - wake_up(&audio->write_wait); - wake_up(&audio->read_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - audio->out_needed = 0; - rmt_put_resource(audio); - audio->rmt_resource_released = 1; - } - return rc; -} - -/* ------------------- dsp --------------------- */ -static void audamrwb_update_pcm_buf_entry(struct audio *audio, - uint32_t *payload) -{ - uint8_t index; - unsigned long flags; - - if (audio->rflush) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < payload[1]; index++) { - if (audio->in[audio->fill_next].addr == - payload[2 + index * 2]) { - MM_DBG("in[%d] ready\n", audio->fill_next); - audio->in[audio->fill_next].used = - payload[3 + index * 2]; - if ((++audio->fill_next) == audio->pcm_buf_count) - audio->fill_next = 0; - - } else { - MM_ERR("expected=%x ret=%x\n", - audio->in[audio->fill_next].addr, - payload[1 + index * 2]); - break; - } - } - if (audio->in[audio->fill_next].used == 0) { - audamrwb_buffer_refresh(audio); - } else { - MM_DBG("read cannot keep up\n"); - audio->buf_refresh = 1; - } - wake_up(&audio->read_wait); - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - getevent(msg, sizeof(msg)); - - MM_DBG("msg_id=%x\n", id); - - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audamrwb_send_data(audio, 1); - break; - - case AUDPLAY_MSG_BUFFER_UPDATE: - audamrwb_update_pcm_buf_entry(audio, msg); - break; - - default: - MM_ERR("unexpected message from decoder\n"); - } -} - -static void audamrwb_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status:sleep reason=0x%04x\n", - reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init\n"); - if (audio->pcm_feedback) - audpp_cmd_cfg_routing_mode(audio); - else - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg\n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play\n"); - if (audio->pcm_feedback) { - audamrwb_config_hostpcm(audio); - audamrwb_buffer_refresh(audio); - } - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - default: - MM_DBG("unknown decoder status\n"); - break; - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - audpp_dsp_set_eq(audio->dec_id, audio->eq_enable, - &audio->eq); - audpp_avsync(audio->dec_id, 22050); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audpp_avsync(audio->dec_id, 0); - audio->running = 0; - } else { - MM_DBG("CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_ROUTING_ACK: - MM_DBG("ROUTING_ACK mode=%d\n", msg[1]); - audpp_cmd_cfg_adec_params(audio); - break; - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - audio->rflush = 0; - wake_up(&audio->write_wait); - if (audio->pcm_feedback) - audamrwb_buffer_refresh(audio); - break; - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - default: - MM_DBG("UNKNOWN (%d)\n", id); - } - -} - -struct msm_adsp_ops audplay_adsp_ops_amrwb = { - .event = audplay_dsp_event, -}; - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id, \ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - u16 cfg_dec_cmd[AUDPP_CMD_CFG_DEC_TYPE_LEN / sizeof(unsigned short)]; - - memset(cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - cfg_dec_cmd[0] = AUDPP_CMD_CFG_DEC_TYPE; - if (enable) - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_AMRWB; - else - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} - -static void audpp_cmd_cfg_adec_params(struct audio *audio) -{ - struct audpp_cmd_cfg_adec_params_amrwb cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_AMRWB_LEN; - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = audio->out_sample_rate; - cmd.stereo_cfg = audio->out_channel_mode; - audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static void audpp_cmd_cfg_routing_mode(struct audio *audio) -{ - struct audpp_cmd_routing_mode cmd; - MM_DBG("\n"); /* Macro prints the file name and function */ - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; - cmd.object_number = audio->dec_id; - if (audio->pcm_feedback) - cmd.routing_mode = ROUTING_MODE_FTRT; - else - cmd.routing_mode = ROUTING_MODE_RT; - - audpp_send_queue1(&cmd, sizeof(cmd)); -} - -static int audplay_dsp_send_data_avail(struct audio *audio, - unsigned idx, unsigned len) -{ - struct audplay_cmd_bitstream_data_avail_nt2 cmd; - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2; - if (audio->mfield) - cmd.decoder_id = AUDAMRWB_METAFIELD_MASK | - (audio->out[idx].mfield_sz >> 1); - else - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = audio->out[idx].addr; - cmd.buf_size = len / 2; - cmd.partition_number = 0; - return audplay_send_queue0(audio, &cmd, sizeof(cmd)); -} - -static void audamrwb_buffer_refresh(struct audio *audio) -{ - struct audplay_cmd_buffer_refresh refresh_cmd; - - refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; - refresh_cmd.num_buffers = 1; - refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; - refresh_cmd.buf0_length = audio->in[audio->fill_next].size; - refresh_cmd.buf_read_count = 0; - MM_DBG("buf0_addr=%x buf0_len=%d\n", refresh_cmd.buf0_address, - refresh_cmd.buf0_length); - (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); -} - -static void audamrwb_config_hostpcm(struct audio *audio) -{ - struct audplay_cmd_hpcm_buf_cfg cfg_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; - cfg_cmd.max_buffers = audio->pcm_buf_count; - cfg_cmd.byte_swap = 0; - cfg_cmd.hostpcm_config = (0x8000) | (0x4000); - cfg_cmd.feedback_frequency = 1; - cfg_cmd.partition_number = 0; - (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); - -} - -static void audamrwb_send_data(struct audio *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - MM_DBG("frame %d busy\n", audio->out_tail); - audplay_dsp_send_data_avail(audio, audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } - done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ - -static void audamrwb_flush(struct audio *audio) -{ - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->reserved = 0; - audio->out_needed = 0; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - atomic_set(&audio->out_bytes, 0); -} - -static void audamrwb_flush_pcm_buf(struct audio *audio) -{ - uint8_t index; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < PCM_BUF_MAX_COUNT; index++) - audio->in[index].used = 0; - - audio->buf_refresh = 0; - audio->read_next = 0; - audio->fill_next = 0; - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audamrwb_ioport_reset(struct audio *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audamrwb_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->read_wait); - mutex_lock(&audio->read_lock); - audamrwb_flush_pcm_buf(audio); - mutex_unlock(&audio->read_lock); -} - -static int audamrwb_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audamrwb_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audamrwb_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audamrwb_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audamrwb_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - -static long audamrwb_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audamrwb_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - audio->event_wait, audamrwb_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audamrwb_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - rc = 0; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audamrwb_event, list); - list_del(&drv_evt->list); - } - - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audio_enable_eq(struct audio *audio, int enable) -{ - if (audio->eq_enable == enable && !audio->eq_needs_commit) - return 0; - - audio->eq_enable = enable; - - if (audio->running) { - audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq); - audio->eq_needs_commit = 0; - } - return 0; -} - -static long audamrwb_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - unsigned long flags = 0; - uint16_t enable_mask; - int enable; - int prev_state; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - int len = 0; - - MM_DBG("cmd = %d\n", cmd); - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = audpp_avsync_byte_count(audio->dec_id); - stats.sample_count = audpp_avsync_sample_count(audio->dec_id); - if (copy_to_user((void *)arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - switch (cmd) { - case AUDIO_ENABLE_AUDPP: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - spin_lock_irqsave(&audio->dsp_lock, flags); - enable = (enable_mask & EQ_ENABLE) ? 1 : 0; - audio_enable_eq(audio, enable); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - case AUDIO_SET_VOLUME: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.volume = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_PAN: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.pan = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_EQ: - prev_state = audio->eq_enable; - audio->eq_enable = 0; - if (copy_from_user(&audio->eq.num_bands, (void *) arg, - sizeof(audio->eq) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) { - rc = -EFAULT; - break; - } - audio->eq_enable = prev_state; - audio->eq_needs_commit = 1; - rc = 0; - break; - } - - if (-EINVAL != rc) - return rc; - - if (cmd == AUDIO_GET_EVENT) { - MM_DBG("AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audamrwb_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audamrwb_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) - rc = -ENODEV; - else - rc = 0; - } - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audamrwb_disable(audio); - audamrwb_ioport_reset(audio); - audio->stopped = 0; - break; - case AUDIO_FLUSH: - MM_DBG(" AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audamrwb_ioport_reset(audio); - if (audio->running) { - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - case AUDIO_SET_CONFIG:{ - struct msm_audio_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.channel_count == 1) - config.channel_count = - AUDPP_CMD_PCM_INTF_MONO_V; - else if (config.channel_count == 2) - config.channel_count = - AUDPP_CMD_PCM_INTF_STEREO_V; - else - rc = -EINVAL; - audio->out_channel_mode = config.channel_count; - audio->out_sample_rate = config.sample_rate; - audio->mfield = config.meta_field; - rc = 0; - break; - } - case AUDIO_GET_CONFIG:{ - struct msm_audio_config config; - config.buffer_size = BUFSZ; - config.buffer_count = 2; - config.sample_rate = audio->out_sample_rate; - if (audio->out_channel_mode == - AUDPP_CMD_PCM_INTF_MONO_V) - config.channel_count = 1; - else - config.channel_count = 2; - config.meta_field = 0; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - - break; - } - case AUDIO_GET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - config.pcm_feedback = 0; - config.buffer_count = PCM_BUF_MAX_COUNT; - config.buffer_size = PCM_BUFSZ_MIN; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if ((config.buffer_count > PCM_BUF_MAX_COUNT) || - (config.buffer_count == 1)) - config.buffer_count = PCM_BUF_MAX_COUNT; - - if (config.buffer_size < PCM_BUFSZ_MIN) - config.buffer_size = PCM_BUFSZ_MIN; - - /* Check if pcm feedback is required */ - if ((config.pcm_feedback) && (!audio->read_data)) { - MM_DBG("allocate PCM buf %d\n", config.buffer_count * - config.buffer_size); - handle = ion_alloc(audio->client, - (config.buffer_size * - config.buffer_count), - SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to alloc I/P buffs\n"); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - break; - } - - audio->input_buff_handle = handle; - - rc = ion_phys(audio->client , - handle, &addr, &len); - if (rc) { - MM_ERR("Invalid phy: %x sz: %x\n", - (unsigned int) addr, - (unsigned int) len); - ion_free(audio->client, handle); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - break; - } else { - MM_INFO("Got valid phy: %x sz: %x\n", - (unsigned int) audio->read_phys, - (unsigned int) len); - } - audio->read_phys = (int32_t)addr; - - rc = ion_handle_get_flags(audio->client, - handle, &ionflag); - if (rc) { - MM_ERR("could not get flags\n"); - ion_free(audio->client, handle); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - break; - } - audio->map_v_read = ion_map_kernel( - audio->client, handle); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("failed to map mem for read buf\n"); - ion_free(audio->client, handle); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - } else { - uint8_t index; - uint32_t offset = 0; - audio->read_data = audio->map_v_read; - audio->pcm_feedback = 1; - audio->buf_refresh = 0; - audio->pcm_buf_count = - config.buffer_count; - audio->read_next = 0; - audio->fill_next = 0; - - for (index = 0; - index < config.buffer_count; index++) { - audio->in[index].data = - audio->read_data + offset; - audio->in[index].addr = - audio->read_phys + offset; - audio->in[index].size = - config.buffer_size; - audio->in[index].used = 0; - offset += config.buffer_size; - } - MM_DBG("read buf: phy addr 0x%08x \ - kernel addr 0x%08x\n", - audio->read_phys, - (int)audio->read_data); - rc = 0; - } - } else { - rc = 0; - } - break; - } - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -static int audamrwb_fsync(struct file *file, loff_t a, loff_t b, - int datasync) -{ - struct audio *audio = file->private_data; - struct buffer *frame; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (!audio->running || audio->pcm_feedback) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (audio->reserved) { - MM_DBG("send reserved byte\n"); - frame = audio->out + audio->out_tail; - ((char *) frame->data)[0] = audio->rsv_byte; - ((char *) frame->data)[1] = 0; - frame->used = 2; - audamrwb_send_data(audio, 0); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - } - - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush); - - if (audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; -} - -static ssize_t audamrwb_read(struct file *file, char __user *buf, size_t count, - loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - int rc = 0; - - if (!audio->pcm_feedback) - return 0; /* PCM feedback is not enabled. Nothing to read */ - - mutex_lock(&audio->read_lock); - MM_DBG("count %d\n", count); - while (count > 0) { - rc = wait_event_interruptible(audio->read_wait, - (audio->in[audio->read_next].used > 0) || - (audio->stopped) || (audio->rflush)); - - if (rc < 0) - break; - - if (audio->stopped || audio->rflush) { - rc = -EBUSY; - break; - } - - if (count < audio->in[audio->read_next].used) { - /* Read must happen in frame boundary. Since driver does - * not know frame size, read count must be greater or - * equal to size of PCM samples - */ - MM_DBG("read stop - partial frame\n"); - break; - } else { - MM_DBG("read from in[%d]\n", - audio->read_next); - - if (copy_to_user - (buf, audio->in[audio->read_next].data, - audio->in[audio->read_next].used)) { - MM_ERR("invalid addr %x \n", (unsigned int)buf); - rc = -EFAULT; - break; - } - count -= audio->in[audio->read_next].used; - buf += audio->in[audio->read_next].used; - audio->in[audio->read_next].used = 0; - if ((++audio->read_next) == audio->pcm_buf_count) - audio->read_next = 0; - break; - } - } - - /* don't feed output buffer to HW decoder during flushing - * buffer refresh command will be sent once flush completes - * send buf refresh command here can confuse HW decoder - */ - if (audio->buf_refresh && !audio->rflush) { - audio->buf_refresh = 0; - MM_ERR("kick start pcm feedback again\n"); - audamrwb_buffer_refresh(audio); - } - - mutex_unlock(&audio->read_lock); - - if (buf > start) - rc = buf - start; - - MM_DBG("read %d bytes\n", rc); - return rc; -} - -static int audamrwb_process_eos(struct audio *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - struct buffer *frame; - char *buf_ptr; - int rc = 0; - - MM_DBG("signal input EOS reserved=%d\n", audio->reserved); - if (audio->reserved) { - MM_DBG("Pass reserve byte\n"); - frame = audio->out + audio->out_head; - buf_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - buf_ptr[0] = audio->rsv_byte; - buf_ptr[1] = 0; - audio->out_head ^= 1; - frame->mfield_sz = 0; - audio->reserved = 0; - frame->used = 2; - audamrwb_send_data(audio, 0); - } - - MM_DBG("Now signal input EOS after reserved bytes %d %d %d\n", - audio->out[0].used, audio->out[1].used, audio->out_needed); - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - audamrwb_send_data(audio, 0); - -done: - return rc; -} - -static ssize_t audamrwb_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - char *cpy_ptr; - int rc = 0, eos_condition = AUDAMRWB_EOS_NONE; - unsigned short mfield_size = 0; - unsigned dsize; - - MM_DBG("cnt=%d\n", count); - - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - cpy_ptr = frame->data; - dsize = 0; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - - MM_DBG("buffer available\n"); - if (rc < 0) - break; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - break; - } - - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - break; - } else if (mfield_size > count) { - rc = -EINVAL; - break; - } - MM_DBG("mf offset_val %x\n", mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - break; - } - /* Check if EOS flag is set and buffer - * contains just meta field - */ - if (cpy_ptr[AUDAMRWB_EOS_FLG_OFFSET] & - AUDAMRWB_EOS_FLG_MASK) { - MM_DBG("eos set\n"); - eos_condition = AUDAMRWB_EOS_SET; - if (mfield_size == count) { - buf += mfield_size; - break; - } else - cpy_ptr[AUDAMRWB_EOS_FLG_OFFSET] &= - ~AUDAMRWB_EOS_FLG_MASK; - } - cpy_ptr += mfield_size; - count -= mfield_size; - dsize += mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - - if (audio->reserved) { - MM_DBG("append reserved byte %x\n", audio->rsv_byte); - *cpy_ptr = audio->rsv_byte; - xfer = (count > ((frame->size - mfield_size) - 1)) ? - ((frame->size - mfield_size) - 1) : count; - cpy_ptr++; - dsize += 1; - audio->reserved = 0; - } else - xfer = (count > (frame->size - mfield_size)) ? - (frame->size - mfield_size) : count; - - if (copy_from_user(cpy_ptr, buf, xfer)) { - rc = -EFAULT; - break; - } - - dsize += xfer; - if (dsize & 1) { - audio->rsv_byte = ((char *) frame->data)[dsize - 1]; - MM_DBG("odd length buf reserve last byte %x\n", - audio->rsv_byte); - audio->reserved = 1; - dsize--; - } - count -= xfer; - buf += xfer; - - if (dsize > 0) { - audio->out_head ^= 1; - frame->used = dsize; - audamrwb_send_data(audio, 0); - } - } - MM_DBG("eos_condition %x buf[0x%x] start[0x%x]\n", eos_condition, - (int) buf, (int) start); - if (eos_condition == AUDAMRWB_EOS_SET) - rc = audamrwb_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - if (!rc) { - if (buf > start) - return buf - start; - } - return rc; -} - -static int audamrwb_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_INFO("audio instance 0x%08x freeing\n", (int)audio); - mutex_lock(&audio->lock); - audamrwb_disable(audio); - if (audio->rmt_resource_released == 0) - rmt_put_resource(audio); - audamrwb_flush(audio); - audamrwb_flush_pcm_buf(audio); - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->event_abort = 1; - wake_up(&audio->event_wait); - audamrwb_reset_event_queue(audio); - ion_unmap_kernel(audio->client, audio->output_buff_handle); - ion_free(audio->client, audio->output_buff_handle); - if (audio->input_buff_handle != NULL) { - ion_unmap_kernel(audio->client, audio->input_buff_handle); - ion_free(audio->client, audio->input_buff_handle); - } - ion_client_destroy(audio->client); - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - kfree(audio); - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audamrwb_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audamrwb_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audamrwb_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audamrwb_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -static void audamrwb_suspend(struct early_suspend *h) -{ - struct audamrwb_suspend_ctl *ctl = - container_of(h, struct audamrwb_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audamrwb_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audamrwb_resume(struct early_suspend *h) -{ - struct audamrwb_suspend_ctl *ctl = - container_of(h, struct audamrwb_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audamrwb_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audamrwb_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audamrwb_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 1024; - static char buffer[1024]; - int n = 0, i; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_feedback %d\n", audio->pcm_feedback); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_buf_sz %d\n", audio->out[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_count %d \n", audio->pcm_buf_count); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_sz %d \n", audio->in[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %x \n", audio->vol_pan.volume); - n += scnprintf(buffer + n, debug_bufmax - n, - "sample rate %d \n", audio->out_sample_rate); - n += scnprintf(buffer + n, debug_bufmax - n, - "channel mode %d \n", audio->out_channel_mode); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "rflush %d\n", audio->rflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d \n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d \n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d \n", audio->out_needed); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_head %d \n", audio->out_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_tail %d \n", audio->out_tail); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[0].used %d \n", audio->out[0].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[1].used %d \n", audio->out[1].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "buffer_refresh %d \n", audio->buf_refresh); - n += scnprintf(buffer + n, debug_bufmax - n, - "read_next %d \n", audio->read_next); - n += scnprintf(buffer + n, debug_bufmax - n, - "fill_next %d \n", audio->fill_next); - for (i = 0; i < audio->pcm_buf_count; i++) - n += scnprintf(buffer + n, debug_bufmax - n, - "in[%d].used %d \n", i, audio->in[i].used); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audamrwb_debug_fops = { - .read = audamrwb_debug_read, - .open = audamrwb_debug_open, -}; -#endif - -static int audamrwb_open(struct inode *inode, struct file *file) -{ - struct audio *audio = NULL; - int rc = 0, dec_attrb, decid, i; - struct audamrwb_event *e_node = NULL; - unsigned mem_sz = DMASZ; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - struct ion_client *client = NULL; - int len = 0; -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_amrwb_" + 5]; -#endif - - /* Allocate Mem for audio instance */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("No memory to allocate audio instance\n"); - rc = -ENOMEM; - goto done; - } - MM_INFO("audio instance 0x%08x created\n", (int)audio); - - /* Allocate the decoder */ - dec_attrb = AUDDEC_DEC_AMRWB; - if (file->f_mode & FMODE_READ) - dec_attrb |= MSM_AUD_MODE_NONTUNNEL; - else - dec_attrb |= MSM_AUD_MODE_TUNNEL; - - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - - if (decid < 0) { - MM_ERR("No free decoder available, freeing instance 0x%08x\n", - (int)audio); - rc = -ENODEV; - kfree(audio); - goto done; - } - - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - client = msm_ion_client_create(UINT_MAX, "Audio_AMR_WB_Client"); - if (IS_ERR_OR_NULL(client)) { - pr_err("Unable to create ION client\n"); - rc = -ENOMEM; - goto client_create_error; - } - audio->client = client; - - handle = ion_alloc(client, mem_sz, SZ_4K, - ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to create allocate O/P buffers\n"); - goto output_buff_alloc_error; - } - audio->output_buff_handle = handle; - - rc = ion_phys(client, handle, &addr, &len); - if (rc) { - MM_ERR("O/P buffers:Invalid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - goto output_buff_get_phys_error; - } else { - MM_INFO("O/P buffers:valid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - } - audio->phys = (int32_t)addr; - - - rc = ion_handle_get_flags(client, handle, &ionflag); - if (rc) { - MM_ERR("could not get flags for the handle\n"); - goto output_buff_get_flags_error; - } - - audio->map_v_write = ion_map_kernel(client, handle); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write buffers\n"); - rc = -ENOMEM; - goto output_buff_map_error; - } - audio->data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->phys, (int)audio->data); - - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) { - rc = audmgr_open(&audio->audmgr); - if (rc) { - MM_ERR("audmgr open failed, freeing instance \ - 0x%08x\n", (int)audio); - goto err; - } - } - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audplay_adsp_ops_amrwb, audio); - if (rc) { - MM_ERR("failed to get %s module, freeing instance 0x%08x\n", - audio->module_name, (int)audio); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_close(&audio->audmgr); - goto err; - } - - rc = rmt_get_resource(audio); - if (rc) { - MM_ERR("ADSP resources are not available for AMRWB session \ - 0x%08x on decoder: %d\n", (int)audio, audio->dec_id); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_close(&audio->audmgr); - msm_adsp_put(audio->audplay); - goto err; - } - - audio->input_buff_handle = NULL; - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->read_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - spin_lock_init(&audio->event_queue_lock); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->write_wait); - init_waitqueue_head(&audio->read_wait); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = BUFSZ; - - audio->out[1].data = audio->data + BUFSZ; - audio->out[1].addr = audio->phys + BUFSZ; - audio->out[1].size = BUFSZ; - - audio->vol_pan.volume = 0x2000; - audio->vol_pan.pan = 0x0; - audio->eq_enable = 0; - audio->out_sample_rate = 44100; - audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V; - - audamrwb_flush(audio); - - file->private_data = audio; - audio->opened = 1; - audio->event_abort = 0; -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_amrwb_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, &audamrwb_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audamrwb_resume; - audio->suspend_ctl.node.suspend = audamrwb_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (i = 0; i < AUDAMRWB_EVENT_NUM; i++) { - e_node = kmalloc(sizeof(struct audamrwb_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } -done: - return rc; -err: - ion_unmap_kernel(client, audio->output_buff_handle); -output_buff_map_error: -output_buff_get_phys_error: -output_buff_get_flags_error: - ion_free(client, audio->output_buff_handle); -output_buff_alloc_error: - ion_client_destroy(client); -client_create_error: - audpp_adec_free(audio->dec_id); - kfree(audio); - return rc; -} - -static const struct file_operations audio_amrwb_fops = { - .owner = THIS_MODULE, - .open = audamrwb_open, - .release = audamrwb_release, - .read = audamrwb_read, - .write = audamrwb_write, - .unlocked_ioctl = audamrwb_ioctl, - .fsync = audamrwb_fsync, -}; - -struct miscdevice audio_amrwb_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_amrwb", - .fops = &audio_amrwb_fops, -}; - -static int __init audamrwb_init(void) -{ - return misc_register(&audio_amrwb_misc); -} - -static void __exit audamrwb_exit(void) -{ - misc_deregister(&audio_amrwb_misc); -} - -module_init(audamrwb_init); -module_exit(audamrwb_exit); - -MODULE_DESCRIPTION("MSM AMR-WB driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5/audio_evrc.c b/arch/arm/mach-msm/qdsp5/audio_evrc.c deleted file mode 100644 index d79da153ed5e9ace62fe338866742b293866664d..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_evrc.c +++ /dev/null @@ -1,1695 +0,0 @@ -/* arch/arm/mach-msm/audio_evrc.c - * - * Copyright (c) 2008-2009, 2011-2012 The Linux Foundation. All rights reserved. - * - * This code also borrows from audio_aac.c, which is - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "audmgr.h" - -/* Hold 30 packets of 24 bytes each and 14 bytes of meta in */ -#define BUFSZ 734 -#define DMASZ (BUFSZ * 2) - -#define AUDDEC_DEC_EVRC 12 - -#define PCM_BUFSZ_MIN 1624 /* 100ms worth of data and - and 24 bytes of meta out */ -#define PCM_BUF_MAX_COUNT 5 -/* DSP only accepts 5 buffers at most - * but support 2 buffers currently - */ -#define EVRC_DECODED_FRSZ 320 /* EVRC 20ms 8KHz mono PCM size */ - -#define ROUTING_MODE_FTRT 1 -#define ROUTING_MODE_RT 2 -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDEVRC_METAFIELD_MASK 0xFFFF0000 -#define AUDEVRC_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */ -#define AUDEVRC_EOS_FLG_MASK 0x01 -#define AUDEVRC_EOS_NONE 0x0 /* No EOS detected */ -#define AUDEVRC_EOS_SET 0x1 /* EOS set in meta field */ - -#define AUDEVRC_EVENT_NUM 10 /* Default number of pre-allocated event packets */ - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; - unsigned short mfield_sz; /*only useful for data has meta field */ -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audevrc_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct audevrc_event{ - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audio { - struct buffer out[2]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - /* Host PCM section */ - struct buffer in[PCM_BUF_MAX_COUNT]; - struct mutex read_lock; - wait_queue_head_t read_wait; /* Wait queue for read */ - char *read_data; /* pointer to reader buffer */ - int32_t read_phys; /* physical address of reader buffer */ - uint8_t read_next; /* index to input buffers to be read next */ - uint8_t fill_next; /* index to buffer that DSP should be filling */ - uint8_t pcm_buf_count; /* number of pcm buffer allocated */ - /* ---- End of Host PCM section */ - - struct msm_adsp_module *audplay; - struct audmgr audmgr; - - /* data allocated for various buffers */ - char *data; - int32_t phys; /* physical address of write buffer */ - void *map_v_read; - void *map_v_write; - - int mfield; /* meta field embedded in data */ - int rflush; /* Read flush */ - int wflush; /* Write flush */ - uint8_t opened:1; - uint8_t enabled:1; - uint8_t running:1; - uint8_t stopped:1; /* set when stopped, cleared on flush */ - uint8_t pcm_feedback:1; - uint8_t buf_refresh:1; - int teos; /* valid only if tunnel mode & no data left for decoder */ - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - int rmt_resource_released; - - const char *module_name; - unsigned queue_id; - uint16_t dec_id; - uint32_t read_ptr_offset; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audevrc_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - - int eq_enable; - int eq_needs_commit; - audpp_cmd_cfg_object_params_eqalizer eq; - audpp_cmd_cfg_object_params_volume vol_pan; - struct ion_client *client; - struct ion_handle *input_buff_handle; - struct ion_handle *output_buff_handle; -}; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audpp_cmd_cfg_adec_params(struct audio *audio); -static void audpp_cmd_cfg_routing_mode(struct audio *audio); -static void audevrc_send_data(struct audio *audio, unsigned needed); -static void audevrc_dsp_event(void *private, unsigned id, uint16_t *msg); -static void audevrc_config_hostpcm(struct audio *audio); -static void audevrc_buffer_refresh(struct audio *audio); -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audevrc_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); -#endif - -static int rmt_put_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_DISABLE; - cmd.dec_type = AUDDEC_DEC_EVRC; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - - return put_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -static int rmt_get_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_ENABLE; - cmd.dec_type = AUDDEC_DEC_EVRC; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - - return get_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -/* must be called with audio->lock held */ -static int audevrc_enable(struct audio *audio) -{ - struct audmgr_config cfg; - int rc; - - if (audio->enabled) - return 0; - - if (audio->rmt_resource_released == 1) { - audio->rmt_resource_released = 0; - rc = rmt_get_resource(audio); - if (rc) { - MM_ERR("ADSP resources are not available for EVRC \ - session 0x%08x on decoder: %d\n Ignoring \ - error and going ahead with the playback\n", - (int)audio, audio->dec_id); - } - } - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_tail = 0; - audio->out_needed = 0; - - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) { - cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; - cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000; - cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK; - cfg.codec = RPC_AUD_DEF_CODEC_EVRC; - cfg.snd_method = RPC_SND_METHOD_MIDI; - - rc = audmgr_enable(&audio->audmgr, &cfg); - if (rc < 0) - return rc; - } - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audevrc_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - audio->enabled = 1; - return 0; -} - -/* must be called with audio->lock held */ -static int audevrc_disable(struct audio *audio) -{ - int rc = 0; - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - audio->stopped = 1; - wake_up(&audio->write_wait); - wake_up(&audio->read_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - audio->out_needed = 0; - rmt_put_resource(audio); - audio->rmt_resource_released = 1; - } - return rc; -} - -/* ------------------- dsp --------------------- */ - -static void audevrc_update_pcm_buf_entry(struct audio *audio, - uint32_t *payload) -{ - uint8_t index; - unsigned long flags; - - if (audio->rflush) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < payload[1]; index++) { - if (audio->in[audio->fill_next].addr - == payload[2 + index * 2]) { - MM_DBG("in[%d] ready\n", audio->fill_next); - audio->in[audio->fill_next].used = - payload[3 + index * 2]; - if ((++audio->fill_next) == audio->pcm_buf_count) - audio->fill_next = 0; - - } else { - MM_ERR("expected=%x ret=%x\n", - audio->in[audio->fill_next].addr, - payload[1 + index * 2]); - break; - } - } - if (audio->in[audio->fill_next].used == 0) { - audevrc_buffer_refresh(audio); - } else { - MM_DBG("read cannot keep up\n"); - audio->buf_refresh = 1; - } - wake_up(&audio->read_wait); - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - getevent(msg, sizeof(msg)); - - MM_DBG("msg_id=%x\n", id); - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audevrc_send_data(audio, 1); - break; - case AUDPLAY_MSG_BUFFER_UPDATE: - MM_DBG("\n"); /* Macro prints the file name and function */ - audevrc_update_pcm_buf_entry(audio, msg); - break; - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audplaytask)\n"); - break; - default: - MM_ERR("unexpected message from decoder \n"); - } -} - -static void audevrc_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status:sleep reason = \ - 0x%04x\n", reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init \n"); - if (audio->pcm_feedback) - audpp_cmd_cfg_routing_mode(audio); - else - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg \n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play \n"); - if (audio->pcm_feedback) { - audevrc_config_hostpcm(audio); - audevrc_buffer_refresh(audio); - } - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - default: - MM_ERR("unknown decoder status \n"); - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - audpp_dsp_set_eq(audio->dec_id, audio->eq_enable, - &audio->eq); - audpp_avsync(audio->dec_id, 22050); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audpp_avsync(audio->dec_id, 0); - audio->running = 0; - } else { - MM_DBG("CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_ROUTING_ACK: - MM_DBG("ROUTING_ACK\n"); - audpp_cmd_cfg_adec_params(audio); - break; - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - audio->rflush = 0; - wake_up(&audio->write_wait); - if (audio->pcm_feedback) - audevrc_buffer_refresh(audio); - break; - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - default: - MM_ERR("UNKNOWN (%d)\n", id); - } - -} - -struct msm_adsp_ops audplay_adsp_ops_evrc = { - .event = audplay_dsp_event, -}; - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id, \ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - u16 cfg_dec_cmd[AUDPP_CMD_CFG_DEC_TYPE_LEN / sizeof(unsigned short)]; - - memset(cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - - cfg_dec_cmd[0] = AUDPP_CMD_CFG_DEC_TYPE; - if (enable) - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_EVRC; - else - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} - -static void audpp_cmd_cfg_adec_params(struct audio *audio) -{ - struct audpp_cmd_cfg_adec_params_evrc cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = sizeof(cmd); - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = 8000; - cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V; - - audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static void audpp_cmd_cfg_routing_mode(struct audio *audio) -{ - struct audpp_cmd_routing_mode cmd; - MM_DBG("\n"); /* Macro prints the file name and function */ - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; - cmd.object_number = audio->dec_id; - if (audio->pcm_feedback) - cmd.routing_mode = ROUTING_MODE_FTRT; - else - cmd.routing_mode = ROUTING_MODE_RT; - - audpp_send_queue1(&cmd, sizeof(cmd)); -} - -static int audplay_dsp_send_data_avail(struct audio *audio, - unsigned idx, unsigned len) -{ - struct audplay_cmd_bitstream_data_avail_nt2 cmd; - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2; - if (audio->mfield) - cmd.decoder_id = AUDEVRC_METAFIELD_MASK | - (audio->out[idx].mfield_sz >> 1); - else - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = audio->out[idx].addr; - cmd.buf_size = len / 2; - cmd.partition_number = 0; - /* complete writes to the input buffer */ - wmb(); - return audplay_send_queue0(audio, &cmd, sizeof(cmd)); -} - -static void audevrc_buffer_refresh(struct audio *audio) -{ - struct audplay_cmd_buffer_refresh refresh_cmd; - - refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; - refresh_cmd.num_buffers = 1; - refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; - refresh_cmd.buf0_length = audio->in[audio->fill_next].size; - - refresh_cmd.buf_read_count = 0; - MM_DBG("buf0_addr=%x buf0_len=%d\n", refresh_cmd.buf0_address, - refresh_cmd.buf0_length); - audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); -} - -static void audevrc_config_hostpcm(struct audio *audio) -{ - struct audplay_cmd_hpcm_buf_cfg cfg_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; - cfg_cmd.max_buffers = 1; - cfg_cmd.byte_swap = 0; - cfg_cmd.hostpcm_config = (0x8000) | (0x4000); - cfg_cmd.feedback_frequency = 1; - cfg_cmd.partition_number = 0; - audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); - -} - -static void audevrc_send_data(struct audio *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - MM_DBG("frame %d busy\n", audio->out_tail); - audplay_dsp_send_data_avail(audio, audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } -done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ - -static void audevrc_flush(struct audio *audio) -{ - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->out_needed = 0; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - atomic_set(&audio->out_bytes, 0); -} - -static void audevrc_flush_pcm_buf(struct audio *audio) -{ - uint8_t index; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < PCM_BUF_MAX_COUNT; index++) - audio->in[index].used = 0; - audio->buf_refresh = 0; - audio->read_next = 0; - audio->fill_next = 0; - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audevrc_ioport_reset(struct audio *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audevrc_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->read_wait); - mutex_lock(&audio->read_lock); - audevrc_flush_pcm_buf(audio); - mutex_unlock(&audio->read_lock); -} - -static int audevrc_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audevrc_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audevrc_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audevrc_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audevrc_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - - -static long audevrc_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audevrc_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - audio->event_wait, audevrc_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audevrc_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - rc = 0; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audevrc_event, list); - list_del(&drv_evt->list); - } - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audio_enable_eq(struct audio *audio, int enable) -{ - if (audio->eq_enable == enable && !audio->eq_needs_commit) - return 0; - - audio->eq_enable = enable; - - if (audio->running) { - audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq); - audio->eq_needs_commit = 0; - } - return 0; -} - -static long audevrc_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - unsigned long flags = 0; - uint16_t enable_mask; - int enable; - int prev_state; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - int len = 0; - - MM_DBG("cmd = %d\n", cmd); - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = audpp_avsync_byte_count(audio->dec_id); - stats.sample_count = audpp_avsync_sample_count(audio->dec_id); - if (copy_to_user((void *)arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - switch (cmd) { - case AUDIO_ENABLE_AUDPP: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - spin_lock_irqsave(&audio->dsp_lock, flags); - enable = (enable_mask & EQ_ENABLE) ? 1 : 0; - audio_enable_eq(audio, enable); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - case AUDIO_SET_VOLUME: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.volume = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_PAN: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.pan = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_EQ: - prev_state = audio->eq_enable; - audio->eq_enable = 0; - if (copy_from_user(&audio->eq.num_bands, (void *) arg, - sizeof(audio->eq) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) { - rc = -EFAULT; - break; - } - audio->eq_enable = prev_state; - audio->eq_needs_commit = 1; - rc = 0; - break; - } - - if (-EINVAL != rc) - return rc; - - if (cmd == AUDIO_GET_EVENT) { - MM_DBG("AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audevrc_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audevrc_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) - rc = -ENODEV; - else - rc = 0; - } - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audevrc_disable(audio); - audevrc_ioport_reset(audio); - audio->stopped = 0; - break; - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audevrc_ioport_reset(audio); - if (audio->running) { - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - case AUDIO_SET_CONFIG:{ - struct msm_audio_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - audio->mfield = config.meta_field; - rc = 0; - MM_DBG("AUDIO_SET_CONFIG applicable only \ - for meta field configuration\n"); - break; - } - case AUDIO_GET_CONFIG:{ - struct msm_audio_config config; - config.buffer_size = BUFSZ; - config.buffer_count = 2; - config.sample_rate = 8000; - config.channel_count = 1; - config.meta_field = 0; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *)arg, &config, sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_GET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - config.pcm_feedback = audio->pcm_feedback; - config.buffer_count = PCM_BUF_MAX_COUNT; - config.buffer_size = PCM_BUFSZ_MIN; - if (copy_to_user((void *)arg, &config, sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.pcm_feedback != audio->pcm_feedback) { - MM_ERR("Not sufficient permission to" - "change the playback mode\n"); - rc = -EACCES; - break; - } - if ((config.buffer_count > PCM_BUF_MAX_COUNT) || - (config.buffer_count == 1)) - config.buffer_count = PCM_BUF_MAX_COUNT; - - if (config.buffer_size < PCM_BUFSZ_MIN) - config.buffer_size = PCM_BUFSZ_MIN; - - /* Check if pcm feedback is required */ - if ((config.pcm_feedback) && (!audio->read_data)) { - MM_DBG("allocate PCM buf %d\n", - config.buffer_count * - config.buffer_size); - handle = ion_alloc(audio->client, - (config.buffer_size * - config.buffer_count), - SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to alloc I/P buffs\n"); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - break; - } - - audio->input_buff_handle = handle; - - rc = ion_phys(audio->client , - handle, &addr, &len); - if (rc) { - MM_ERR("Invalid phy: %x sz: %x\n", - (unsigned int) addr, - (unsigned int) len); - ion_free(audio->client, handle); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - break; - } else { - MM_INFO("Got valid phy: %x sz: %x\n", - (unsigned int) audio->read_phys, - (unsigned int) len); - } - audio->read_phys = (int32_t)addr; - - rc = ion_handle_get_flags(audio->client, - handle, &ionflag); - if (rc) { - MM_ERR("could not get flags\n"); - ion_free(audio->client, handle); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - break; - } - audio->map_v_read = ion_map_kernel( - audio->client, handle); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("failed to map mem" - " for read buf\n"); - ion_free(audio->client, handle); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - } else { - uint8_t index; - uint32_t offset = 0; - audio->read_data = - audio->map_v_read; - audio->buf_refresh = 0; - audio->pcm_buf_count = - config.buffer_count; - audio->read_next = 0; - audio->fill_next = 0; - - for (index = 0; - index < config.buffer_count; - index++) { - audio->in[index].data = - audio->read_data + offset; - audio->in[index].addr = - audio->read_phys + offset; - audio->in[index].size = - config.buffer_size; - audio->in[index].used = 0; - offset += config.buffer_size; - } - MM_DBG("read buf: phy addr \ - 0x%08x kernel addr 0x%08x\n", - audio->read_phys, - (int)audio->read_data); - rc = 0; - } - } else { - rc = 0; - } - break; - } - case AUDIO_PAUSE: - MM_DBG("AUDIO_PAUSE %ld\n", arg); - rc = audpp_pause(audio->dec_id, (int) arg); - break; - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -static int audevrc_fsync(struct file *file, loff_t a, loff_t b, int datasync) -{ - struct audio *audio = file->private_data; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - if (!audio->running || audio->pcm_feedback) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush); - - if (audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; -} - -static ssize_t audevrc_read(struct file *file, char __user *buf, size_t count, - loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - int rc = 0; - if (!audio->pcm_feedback) { - return 0; - /* PCM feedback is not enabled. Nothing to read */ - } - mutex_lock(&audio->read_lock); - MM_DBG("\n"); /* Macro prints the file name and function */ - while (count > 0) { - rc = wait_event_interruptible(audio->read_wait, - (audio->in[audio->read_next].used > 0) || - (audio->stopped) || (audio->rflush)); - - MM_DBG("wait terminated \n"); - if (rc < 0) - break; - if (audio->stopped || audio->rflush) { - rc = -EBUSY; - break; - } - if (count < audio->in[audio->read_next].used) { - /* Read must happen in frame boundary. Since driver does - * not know frame size, read count must be greater or - * equal to size of PCM samples - */ - MM_DBG("read stop - partial frame\n"); - break; - } else { - MM_DBG("read from in[%d]\n", audio->read_next); - /* order reads from the output buffer */ - rmb(); - if (copy_to_user - (buf, audio->in[audio->read_next].data, - audio->in[audio->read_next].used)) { - MM_ERR("invalid addr %x \n", - (unsigned int)buf); - rc = -EFAULT; - break; - } - count -= audio->in[audio->read_next].used; - buf += audio->in[audio->read_next].used; - audio->in[audio->read_next].used = 0; - if ((++audio->read_next) == audio->pcm_buf_count) - audio->read_next = 0; - break; - /* Force to exit while loop - * to prevent output thread - * sleep too long if data is - * not ready at this moment - */ - - } - } - /* don't feed output buffer to HW decoder during flushing - * buffer refresh command will be sent once flush completes - * send buf refresh command here can confuse HW decoder - */ - if (audio->buf_refresh && !audio->rflush) { - audio->buf_refresh = 0; - MM_DBG("kick start pcm feedback again\n"); - audevrc_buffer_refresh(audio); - } - mutex_unlock(&audio->read_lock); - if (buf > start) - rc = buf - start; - MM_DBG("read %d bytes\n", rc); - return rc; -} - -static int audevrc_process_eos(struct audio *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - int rc = 0; - struct buffer *frame; - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - audevrc_send_data(audio, 0); - -done: - return rc; -} - -static ssize_t audevrc_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - char *cpy_ptr; - unsigned short mfield_size = 0; - int rc = 0, eos_condition = AUDEVRC_EOS_NONE; - - MM_DBG("cnt=%d\n", count); - - if (count & 1) - return -EINVAL; - - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - cpy_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - break; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - break; - } - - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - break; - } else if (mfield_size > count) { - rc = -EINVAL; - break; - } - MM_DBG("mf offset_val %x\n", mfield_size); - if (copy_from_user(cpy_ptr, buf, - mfield_size)) { - rc = -EFAULT; - break; - } - /* Check if EOS flag is set and buffer has - * contains just meta field - */ - if (cpy_ptr[AUDEVRC_EOS_FLG_OFFSET] & - AUDEVRC_EOS_FLG_MASK) { - MM_DBG("eos set\n"); - eos_condition = AUDEVRC_EOS_SET; - if (mfield_size == count) { - buf += mfield_size; - break; - } else - cpy_ptr[AUDEVRC_EOS_FLG_OFFSET] &= - ~AUDEVRC_EOS_FLG_MASK; - } - /* Check EOS to see if */ - cpy_ptr += mfield_size; - count -= mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - - xfer = (count > (frame->size - mfield_size)) ? - (frame->size - mfield_size) : count; - if (copy_from_user(cpy_ptr, buf, xfer)) { - rc = -EFAULT; - break; - } - - frame->used = xfer + mfield_size; - audio->out_head ^= 1; - count -= xfer; - buf += xfer; - audevrc_send_data(audio, 0); - } - if (eos_condition == AUDEVRC_EOS_SET) - rc = audevrc_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - if (!rc) { - if (buf > start) - return buf - start; - } - return rc; -} - -static int audevrc_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_INFO("audio instance 0x%08x freeing\n", (int)audio); - mutex_lock(&audio->lock); - audevrc_disable(audio); - if (audio->rmt_resource_released == 0) - rmt_put_resource(audio); - audevrc_flush(audio); - audevrc_flush_pcm_buf(audio); - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->event_abort = 1; - wake_up(&audio->event_wait); - audevrc_reset_event_queue(audio); - ion_unmap_kernel(audio->client, audio->output_buff_handle); - ion_free(audio->client, audio->output_buff_handle); - if (audio->input_buff_handle != NULL) { - ion_unmap_kernel(audio->client, audio->input_buff_handle); - ion_free(audio->client, audio->input_buff_handle); - } - ion_client_destroy(audio->client); - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - kfree(audio); - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audevrc_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audevrc_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audevrc_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audevrc_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -static void audevrc_suspend(struct early_suspend *h) -{ - struct audevrc_suspend_ctl *ctl = - container_of(h, struct audevrc_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audevrc_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audevrc_resume(struct early_suspend *h) -{ - struct audevrc_suspend_ctl *ctl = - container_of(h, struct audevrc_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audevrc_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audevrc_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audevrc_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 1024; - static char buffer[1024]; - int n = 0, i; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_feedback %d\n", audio->pcm_feedback); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_buf_sz %d\n", audio->out[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_count %d \n", audio->pcm_buf_count); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_sz %d \n", audio->in[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %x \n", audio->vol_pan.volume); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "rflush %d\n", audio->rflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d \n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d \n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d \n", audio->out_needed); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_head %d \n", audio->out_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_tail %d \n", audio->out_tail); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[0].used %d \n", audio->out[0].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[1].used %d \n", audio->out[1].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "buffer_refresh %d \n", audio->buf_refresh); - n += scnprintf(buffer + n, debug_bufmax - n, - "read_next %d \n", audio->read_next); - n += scnprintf(buffer + n, debug_bufmax - n, - "fill_next %d \n", audio->fill_next); - for (i = 0; i < audio->pcm_buf_count; i++) - n += scnprintf(buffer + n, debug_bufmax - n, - "in[%d].size %d \n", i, audio->in[i].used); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audevrc_debug_fops = { - .read = audevrc_debug_read, - .open = audevrc_debug_open, -}; -#endif - -static int audevrc_open(struct inode *inode, struct file *file) -{ - struct audio *audio = NULL; - int rc, dec_attrb, decid, i; - struct audevrc_event *e_node = NULL; - unsigned mem_sz = DMASZ; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - struct ion_client *client = NULL; - int len = 0; - -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_evrc_" + 5]; -#endif - - /* Allocate audio instance, set to zero */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("no memory to allocate audio instance\n"); - rc = -ENOMEM; - goto done; - } - MM_INFO("audio instance 0x%08x created\n", (int)audio); - - /* Allocate the decoder */ - dec_attrb = AUDDEC_DEC_EVRC; - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_NONTUNNEL; - audio->pcm_feedback = NON_TUNNEL_MODE_PLAYBACK; - } else if ((file->f_mode & FMODE_WRITE) && - !(file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_TUNNEL; - audio->pcm_feedback = TUNNEL_MODE_PLAYBACK; - } else { - kfree(audio); - rc = -EACCES; - goto done; - } - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - - if (decid < 0) { - MM_ERR("No free decoder available, freeing instance 0x%08x\n", - (int)audio); - rc = -ENODEV; - kfree(audio); - goto done; - } - - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - client = msm_ion_client_create(UINT_MAX, "Audio_EVRC_Client"); - if (IS_ERR_OR_NULL(client)) { - pr_err("Unable to create ION client\n"); - rc = -ENOMEM; - goto client_create_error; - } - audio->client = client; - - handle = ion_alloc(client, mem_sz, SZ_4K, - ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to create allocate O/P buffers\n"); - rc = -ENOMEM; - goto output_buff_alloc_error; - } - audio->output_buff_handle = handle; - - rc = ion_phys(client, handle, &addr, &len); - if (rc) { - MM_ERR("O/P buffers:Invalid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - goto output_buff_get_phys_error; - } else { - MM_INFO("O/P buffers:valid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - } - audio->phys = (int32_t)addr; - - - rc = ion_handle_get_flags(client, handle, &ionflag); - if (rc) { - MM_ERR("could not get flags for the handle\n"); - goto output_buff_get_flags_error; - } - - audio->map_v_write = ion_map_kernel(client, handle); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write buffers\n"); - rc = -ENOMEM; - goto output_buff_map_error; - } - audio->data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->phys, (int)audio->data); - - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) { - rc = audmgr_open(&audio->audmgr); - if (rc) { - MM_ERR("audmgr open failed, freeing instance \ - 0x%08x\n", (int)audio); - goto err; - } - } - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audplay_adsp_ops_evrc, audio); - - if (rc) { - MM_ERR("failed to get %s module, freeing instance 0x%08x\n", - audio->module_name, (int)audio); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_close(&audio->audmgr); - goto err; - } - - rc = rmt_get_resource(audio); - if (rc) { - MM_ERR("ADSP resources are not available for EVRC session \ - 0x%08x on decoder: %d\n", (int)audio, audio->dec_id); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_close(&audio->audmgr); - msm_adsp_put(audio->audplay); - goto err; - } - - audio->input_buff_handle = NULL; - - /* Initialize all locks of audio instance */ - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->read_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - init_waitqueue_head(&audio->write_wait); - init_waitqueue_head(&audio->read_wait); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - spin_lock_init(&audio->event_queue_lock); - - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = BUFSZ; - - audio->out[1].data = audio->data + BUFSZ; - audio->out[1].addr = audio->phys + BUFSZ; - audio->out[1].size = BUFSZ; - - audio->vol_pan.volume = 0x3FFF; - - audevrc_flush(audio); - - file->private_data = audio; - audio->opened = 1; -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_evrc_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, &audevrc_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audevrc_resume; - audio->suspend_ctl.node.suspend = audevrc_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (i = 0; i < AUDEVRC_EVENT_NUM; i++) { - e_node = kmalloc(sizeof(struct audevrc_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } -done: - return rc; -err: - ion_unmap_kernel(client, audio->output_buff_handle); -output_buff_map_error: -output_buff_get_phys_error: -output_buff_get_flags_error: - ion_free(client, audio->output_buff_handle); -output_buff_alloc_error: - ion_client_destroy(client); -client_create_error: - audpp_adec_free(audio->dec_id); - kfree(audio); - return rc; -} - -static const struct file_operations audio_evrc_fops = { - .owner = THIS_MODULE, - .open = audevrc_open, - .release = audevrc_release, - .read = audevrc_read, - .write = audevrc_write, - .unlocked_ioctl = audevrc_ioctl, - .fsync = audevrc_fsync, -}; - -struct miscdevice audio_evrc_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_evrc", - .fops = &audio_evrc_fops, -}; - -static int __init audevrc_init(void) -{ - return misc_register(&audio_evrc_misc); - -} - -static void __exit audevrc_exit(void) -{ - misc_deregister(&audio_evrc_misc); -} - -module_init(audevrc_init); -module_exit(audevrc_exit); - -MODULE_DESCRIPTION("MSM EVRC driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5/audio_evrc_in.c b/arch/arm/mach-msm/qdsp5/audio_evrc_in.c deleted file mode 100644 index fc90fae672220451c4ea735536cf189e4da9cfe5..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_evrc_in.c +++ /dev/null @@ -1,1466 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/audio_evrc_in.c - * - * evrc audio input device - * - * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. - * - * This code is based in part on arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c, - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "audmgr.h" - -#include -#include -#include -#include -#include -#include - -#define FRAME_HEADER_SIZE 8 /* 8 bytes frame header */ -#define NT_FRAME_HEADER_SIZE 24 /* 24 bytes frame header */ -/* FRAME_NUM must be a power of two */ -#define FRAME_NUM 8 -#define EVRC_FRAME_SIZE 36 /* 36 bytes data */ -/*Tunnel mode : 36 bytes data + 8 byte header*/ -#define FRAME_SIZE (EVRC_FRAME_SIZE + FRAME_HEADER_SIZE) - /* 36 bytes data + 24 meta field*/ -#define NT_FRAME_SIZE (EVRC_FRAME_SIZE + NT_FRAME_HEADER_SIZE) -#define DMASZ (FRAME_SIZE * FRAME_NUM) -#define NT_DMASZ (NT_FRAME_SIZE * FRAME_NUM) -#define OUT_FRAME_NUM 2 -#define OUT_BUFFER_SIZE (4 * 1024 + NT_FRAME_HEADER_SIZE) -#define BUFFER_SIZE (OUT_BUFFER_SIZE * OUT_FRAME_NUM) - -#define AUDPREPROC_EVRC_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer*/ -#define AUDPREPROC_EVRC_EOS_FLG_MASK 0x01 -#define AUDPREPROC_EVRC_EOS_NONE 0x0 /* No EOS detected */ -#define AUDPREPROC_EVRC_EOS_SET 0x1 /* EOS set in meta field */ - -struct buffer { - void *data; - uint32_t size; - uint32_t read; - uint32_t addr; - uint32_t used; - uint32_t mfield_sz; -}; - -struct audio_evrc_in { - struct buffer in[FRAME_NUM]; - - spinlock_t dsp_lock; - - atomic_t in_bytes; - atomic_t in_samples; - - struct mutex lock; - struct mutex read_lock; - wait_queue_head_t wait; - wait_queue_head_t wait_enable; - /*write section*/ - struct buffer out[OUT_FRAME_NUM]; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - uint32_t out_count; - - struct mutex write_lock; - wait_queue_head_t write_wait; - int32_t out_phys; /* physical address of write buffer */ - char *out_data; - int mfield; /* meta field embedded in data */ - int wflush; /*write flush */ - int rflush; /*read flush*/ - int out_frame_cnt; - - struct msm_adsp_module *audrec; - struct msm_adsp_module *audpre; - - - /* configuration to use on next enable */ - uint32_t samp_rate; - uint32_t channel_mode; - uint32_t buffer_size; /* Frame size (36 bytes) */ - uint32_t enc_type; /* 11 for EVRC */ - uint32_t mode; /* T or NT Mode*/ - - struct msm_audio_evrc_enc_config cfg; - - uint32_t dsp_cnt; - uint32_t in_head; /* next buffer dsp will write */ - uint32_t in_tail; /* next buffer read() will read */ - uint32_t in_count; /* number of buffers available to read() */ - - uint32_t eos_ack; - uint32_t flush_ack; - - const char *module_name; - unsigned queue_ids; - uint16_t enc_id; /* Session Id */ - - unsigned short samp_rate_index; - uint32_t audrec_obj_idx ; - - struct audmgr audmgr; - - /* data allocated for various buffers */ - char *data; - dma_addr_t phys; - - void *map_v_read; - void *map_v_write; - - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - struct ion_client *client; - struct ion_handle *input_buff_handle; - struct ion_handle *output_buff_handle; -}; - -struct audio_frame { - uint16_t frame_count_lsw; - uint16_t frame_count_msw; - uint16_t frame_length; - uint16_t erased_pcm; - unsigned char raw_bitstream[]; -} __packed; - -struct audio_frame_nt { - uint16_t metadata_len; - uint16_t frame_count_lsw; - uint16_t frame_count_msw; - uint16_t frame_length; - uint16_t erased_pcm; - uint16_t reserved; - uint16_t time_stamp_dword_lsw; - uint16_t time_stamp_dword_msw; - uint16_t time_stamp_lsw; - uint16_t time_stamp_msw; - uint16_t nflag_lsw; - uint16_t nflag_msw; - unsigned char raw_bitstream[]; /* samples */ -} __packed; - -struct evrc_encoded_meta_out { - uint16_t metadata_len; - uint16_t time_stamp_dword_lsw; - uint16_t time_stamp_dword_msw; - uint16_t time_stamp_lsw; - uint16_t time_stamp_msw; - uint16_t nflag_lsw; - uint16_t nflag_msw; -}; - -/* Audrec Queue command sent macro's */ -#define audio_send_queue_pre(audio, cmd, len) \ - msm_adsp_write(audio->audpre, QDSP_uPAudPreProcCmdQueue, cmd, len) - -#define audio_send_queue_recbs(audio, cmd, len) \ - msm_adsp_write(audio->audrec, ((audio->queue_ids & 0xFFFF0000) >> 16),\ - cmd, len) -#define audio_send_queue_rec(audio, cmd, len) \ - msm_adsp_write(audio->audrec, (audio->queue_ids & 0x0000FFFF),\ - cmd, len) - -static int audevrc_in_dsp_enable(struct audio_evrc_in *audio, int enable); -static int audevrc_in_encparam_config(struct audio_evrc_in *audio); -static int audevrc_in_encmem_config(struct audio_evrc_in *audio); -static int audevrc_in_dsp_read_buffer(struct audio_evrc_in *audio, - uint32_t read_cnt); -static void audevrc_in_flush(struct audio_evrc_in *audio); - -static void audevrc_in_get_dsp_frames(struct audio_evrc_in *audio); -static int audpcm_config(struct audio_evrc_in *audio); -static void audevrc_out_flush(struct audio_evrc_in *audio); -static int audevrc_in_routing_mode_config(struct audio_evrc_in *audio); -static void audrec_pcm_send_data(struct audio_evrc_in *audio, unsigned needed); -static void audevrc_nt_in_get_dsp_frames(struct audio_evrc_in *audio); -static void audevrc_in_flush(struct audio_evrc_in *audio); - -static unsigned convert_samp_index(unsigned index) -{ - switch (index) { - case RPC_AUD_DEF_SAMPLE_RATE_48000: return 48000; - case RPC_AUD_DEF_SAMPLE_RATE_44100: return 44100; - case RPC_AUD_DEF_SAMPLE_RATE_32000: return 32000; - case RPC_AUD_DEF_SAMPLE_RATE_24000: return 24000; - case RPC_AUD_DEF_SAMPLE_RATE_22050: return 22050; - case RPC_AUD_DEF_SAMPLE_RATE_16000: return 16000; - case RPC_AUD_DEF_SAMPLE_RATE_12000: return 12000; - case RPC_AUD_DEF_SAMPLE_RATE_11025: return 11025; - case RPC_AUD_DEF_SAMPLE_RATE_8000: return 8000; - default: return 11025; - } -} - -/* must be called with audio->lock held */ -static int audevrc_in_enable(struct audio_evrc_in *audio) -{ - struct audmgr_config cfg; - int rc; - - if (audio->enabled) - return 0; - - cfg.tx_rate = audio->samp_rate; - cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; - cfg.def_method = RPC_AUD_DEF_METHOD_RECORD; - cfg.codec = RPC_AUD_DEF_CODEC_EVRC; - cfg.snd_method = RPC_SND_METHOD_MIDI; - - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - rc = audmgr_enable(&audio->audmgr, &cfg); - if (rc < 0) - return rc; - - if (msm_adsp_enable(audio->audpre)) { - audmgr_disable(&audio->audmgr); - MM_ERR("msm_adsp_enable(audpre) failed\n"); - return -ENODEV; - } - } - if (msm_adsp_enable(audio->audrec)) { - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - audmgr_disable(&audio->audmgr); - msm_adsp_disable(audio->audpre); - } - MM_ERR("msm_adsp_enable(audrec) failed\n"); - return -ENODEV; - } - - audio->enabled = 1; - audevrc_in_dsp_enable(audio, 1); - - return 0; -} - -/* must be called with audio->lock held */ -static int audevrc_in_disable(struct audio_evrc_in *audio) -{ - if (audio->enabled) { - audio->enabled = 0; - - audevrc_in_dsp_enable(audio, 0); - - wake_up(&audio->wait); - wait_event_interruptible_timeout(audio->wait_enable, - audio->running == 0, 1*HZ); - audio->stopped = 1; - wake_up(&audio->wait); - msm_adsp_disable(audio->audrec); - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - msm_adsp_disable(audio->audpre); - audmgr_disable(&audio->audmgr); - } - } - return 0; -} - -/* ------------------- dsp --------------------- */ -static void audpre_dsp_event(void *data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - uint16_t msg[2]; - getevent(msg, sizeof(msg)); - - switch (id) { - case AUDPREPROC_MSG_CMD_CFG_DONE_MSG: - MM_DBG("type %d, status_flag %d\n", msg[0], msg[1]); - break; - case AUDPREPROC_MSG_ERROR_MSG_ID: - MM_ERR("err_index %d\n", msg[0]); - break; - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audpreproctask)\n"); - break; - default: - MM_ERR("unknown event %d\n", id); - } -} - -static void audevrc_in_get_dsp_frames(struct audio_evrc_in *audio) -{ - struct audio_frame *frame; - uint32_t index; - unsigned long flags; - - index = audio->in_head; - - frame = (void *) (((char *)audio->in[index].data) - - sizeof(*frame)); - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->in[index].size = frame->frame_length; - - /* statistics of read */ - atomic_add(audio->in[index].size, &audio->in_bytes); - atomic_add(1, &audio->in_samples); - - audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1); - - /* If overflow, move the tail index foward. */ - if (audio->in_head == audio->in_tail) { - MM_ERR("Error! not able to keep up the read\n"); - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - MM_ERR("in_count = %d\n", audio->in_count); - } else - audio->in_count++; - - audevrc_in_dsp_read_buffer(audio, audio->dsp_cnt++); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - - wake_up(&audio->wait); -} - -static void audevrc_nt_in_get_dsp_frames(struct audio_evrc_in *audio) -{ - struct audio_frame_nt *nt_frame; - uint32_t index; - unsigned long flags; - - index = audio->in_head; - nt_frame = (void *) (((char *)audio->in[index].data) - \ - sizeof(struct audio_frame_nt)); - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->in[index].size = nt_frame->frame_length; - /* statistics of read */ - atomic_add(audio->in[index].size, &audio->in_bytes); - atomic_add(1, &audio->in_samples); - - audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1); - - /* If overflow, move the tail index foward. */ - if (audio->in_head == audio->in_tail) - MM_DBG("Error! not able to keep up the read\n"); - else - audio->in_count++; - - spin_unlock_irqrestore(&audio->dsp_lock, flags); - wake_up(&audio->wait); -} - -static int audrec_pcm_buffer_ptr_refresh(struct audio_evrc_in *audio, - unsigned idx, unsigned len) -{ - struct audrec_cmd_pcm_buffer_ptr_refresh_arm_enc cmd; - - if (len == NT_FRAME_HEADER_SIZE) - len = len / 2; - else - len = (len + NT_FRAME_HEADER_SIZE) / 2; - MM_DBG("len = %d\n", len); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_PCM_BUFFER_PTR_REFRESH_ARM_TO_ENC; - cmd.num_buffers = 1; - if (cmd.num_buffers == 1) { - cmd.buf_address_length[0] = (audio->out[idx].addr & - 0xffff0000) >> 16; - cmd.buf_address_length[1] = (audio->out[idx].addr & - 0x0000ffff); - cmd.buf_address_length[2] = (len & 0xffff0000) >> 16; - cmd.buf_address_length[3] = (len & 0x0000ffff); - } - audio->out_frame_cnt++; - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audpcm_config(struct audio_evrc_in *audio) -{ - struct audrec_cmd_pcm_cfg_arm_to_enc cmd; - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_PCM_CFG_ARM_TO_ENC; - cmd.config_update_flag = AUDREC_PCM_CONFIG_UPDATE_FLAG_ENABLE; - cmd.enable_flag = AUDREC_ENABLE_FLAG_VALUE; - cmd.sampling_freq = convert_samp_index(audio->samp_rate); - if (!audio->channel_mode) - cmd.channels = 1; - else - cmd.channels = 2; - cmd.frequency_of_intimation = 1; - cmd.max_number_of_buffers = OUT_FRAME_NUM; - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - - -static int audevrc_in_routing_mode_config(struct audio_evrc_in *audio) -{ - struct audrec_cmd_routing_mode cmd; - - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_ROUTING_MODE; - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) - cmd.routing_mode = 1; - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static void audrec_dsp_event(void *data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - struct audio_evrc_in *audio = NULL; - - if (data) - audio = data; - else { - MM_ERR("invalid data for event %x\n", id); - return; - } - - switch (id) { - case AUDREC_MSG_CMD_CFG_DONE_MSG: { - struct audrec_msg_cmd_cfg_done_msg cmd_cfg_done_msg; - getevent(&cmd_cfg_done_msg, AUDREC_MSG_CMD_CFG_DONE_MSG_LEN); - if (cmd_cfg_done_msg.audrec_enc_type & \ - AUDREC_MSG_CFG_DONE_ENC_ENA) { - audio->audrec_obj_idx = cmd_cfg_done_msg.audrec_obj_idx; - MM_DBG("CFG ENABLED\n"); - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) { - MM_DBG("routing command\n"); - audevrc_in_routing_mode_config(audio); - } else { - audevrc_in_encmem_config(audio); - } - } else { - MM_DBG("CFG SLEEP\n"); - audio->running = 0; - wake_up(&audio->wait_enable); - } - break; - } - case AUDREC_MSG_CMD_ROUTING_MODE_DONE_MSG: { - struct audrec_msg_cmd_routing_mode_done_msg \ - routing_msg; - getevent(&routing_msg, AUDREC_MSG_CMD_ROUTING_MODE_DONE_MSG); - MM_DBG("AUDREC_MSG_CMD_ROUTING_MODE_DONE_MSG"); - if (routing_msg.configuration == 0) { - MM_ERR("routing configuration failed\n"); - audio->running = 0; - wake_up(&audio->wait_enable); - } else - audevrc_in_encmem_config(audio); - break; - } - case AUDREC_MSG_CMD_AREC_MEM_CFG_DONE_MSG: { - MM_DBG("AREC_MEM_CFG_DONE_MSG\n"); - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - audevrc_in_encparam_config(audio); - else - audpcm_config(audio); - break; - } - case AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG: { - MM_DBG("AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG"); - audevrc_in_encparam_config(audio); - break; - } - case AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG: { - MM_DBG("AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG\n"); - audio->running = 1; - wake_up(&audio->wait_enable); - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) - audrec_pcm_send_data(audio, 1); - break; - } - case AUDREC_CMD_PCM_BUFFER_PTR_UPDATE_ARM_TO_ENC_MSG: { - MM_DBG("ptr_update recieved from DSP\n"); - audrec_pcm_send_data(audio, 1); - break; - } - case AUDREC_MSG_NO_EXT_PKT_AVAILABLE_MSG: { - struct audrec_msg_no_ext_pkt_avail_msg err_msg; - getevent(&err_msg, AUDREC_MSG_NO_EXT_PKT_AVAILABLE_MSG_LEN); - MM_DBG("NO_EXT_PKT_AVAILABLE_MSG %x\n",\ - err_msg.audrec_err_id); - break; - } - case AUDREC_MSG_PACKET_READY_MSG: { - struct audrec_msg_packet_ready_msg pkt_ready_msg; - - getevent(&pkt_ready_msg, AUDREC_MSG_PACKET_READY_MSG_LEN); - MM_DBG("UP_PACKET_READY_MSG: write cnt msw %d \ - write cnt lsw %d read cnt msw %d read cnt lsw %d \n",\ - pkt_ready_msg.pkt_counter_msw, \ - pkt_ready_msg.pkt_counter_lsw, \ - pkt_ready_msg.pkt_read_cnt_msw, \ - pkt_ready_msg.pkt_read_cnt_lsw); - - audevrc_in_get_dsp_frames(audio); - break; - } - case AUDREC_UP_NT_PACKET_READY_MSG: { - struct audrec_up_nt_packet_ready_msg pkt_ready_msg; - - getevent(&pkt_ready_msg, AUDREC_UP_NT_PACKET_READY_MSG_LEN); - MM_DBG("UP_NT_PACKET_READY_MSG: write cnt lsw %d \ - write cnt msw %d read cnt lsw %d read cnt msw %d \n",\ - pkt_ready_msg.audrec_packetwrite_cnt_lsw, \ - pkt_ready_msg.audrec_packetwrite_cnt_msw, \ - pkt_ready_msg.audrec_upprev_readcount_lsw, \ - pkt_ready_msg.audrec_upprev_readcount_msw); - - audevrc_nt_in_get_dsp_frames(audio); - break; - } - case AUDREC_CMD_FLUSH_DONE_MSG: { - audio->wflush = 0; - audio->rflush = 0; - audio->flush_ack = 1; - wake_up(&audio->write_wait); - MM_DBG("flush ack recieved\n"); - break; - } - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module \ - enable/disable(audrectask)\n"); - break; - default: - MM_ERR("unknown event %d\n", id); - } -} - -static struct msm_adsp_ops audpre_evrc_adsp_ops = { - .event = audpre_dsp_event, -}; - -static struct msm_adsp_ops audrec_evrc_adsp_ops = { - .event = audrec_dsp_event, -}; - -static int audevrc_in_dsp_enable(struct audio_evrc_in *audio, int enable) -{ - struct audrec_cmd_enc_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_ENC_CFG; - cmd.audrec_enc_type = (audio->enc_type & 0xFF) | - (enable ? AUDREC_CMD_ENC_ENA : AUDREC_CMD_ENC_DIS); - /* Don't care */ - cmd.audrec_obj_idx = audio->audrec_obj_idx; - - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audevrc_in_encmem_config(struct audio_evrc_in *audio) -{ - struct audrec_cmd_arecmem_cfg cmd; - uint16_t *data = (void *) audio->data; - int n; - int header_len = 0; - - memset(&cmd, 0, sizeof(cmd)); - - cmd.cmd_id = AUDREC_CMD_ARECMEM_CFG; - cmd.audrec_obj_idx = audio->audrec_obj_idx; - /* Rate at which packet complete message comes */ - cmd.audrec_up_pkt_intm_cnt = 1; - cmd.audrec_extpkt_buffer_msw = audio->phys >> 16; - cmd.audrec_extpkt_buffer_lsw = audio->phys; - /* Max Buffer no available for frames */ - cmd.audrec_extpkt_buffer_num = FRAME_NUM; - - /* prepare buffer pointers: - * T:36 bytes evrc packet + 4 halfword header - * NT:36 bytes evrc packet + 12 halfword header - */ - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - header_len = FRAME_HEADER_SIZE/2; - else - header_len = NT_FRAME_HEADER_SIZE/2; - - for (n = 0; n < FRAME_NUM; n++) { - audio->in[n].data = data + header_len; - data += (EVRC_FRAME_SIZE/2) + header_len; - MM_DBG("0x%8x\n", (int)(audio->in[n].data - header_len*2)); - } - - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audevrc_in_encparam_config(struct audio_evrc_in *audio) -{ - struct audrec_cmd_arecparam_evrc_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDREC_CMD_ARECPARAM_CFG; - cmd.common.audrec_obj_idx = audio->audrec_obj_idx; - cmd.enc_min_rate = audio->cfg.min_bit_rate; - cmd.enc_max_rate = audio->cfg.max_bit_rate; - cmd.rate_modulation_cmd = 0; /* Default set to 0 */ - - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audevrc_flush_command(struct audio_evrc_in *audio) -{ - struct audrec_cmd_flush cmd; - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_FLUSH; - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audevrc_in_dsp_read_buffer(struct audio_evrc_in *audio, - uint32_t read_cnt) -{ - audrec_cmd_packet_ext_ptr cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_PACKET_EXT_PTR; - cmd.type = audio->audrec_obj_idx; - cmd.curr_rec_count_msw = read_cnt >> 16; - cmd.curr_rec_count_lsw = read_cnt; - - return audio_send_queue_recbs(audio, &cmd, sizeof(cmd)); -} - -/* ------------------- device --------------------- */ - -static void audevrc_ioport_reset(struct audio_evrc_in *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->wait); - mutex_lock(&audio->read_lock); - audevrc_in_flush(audio); - mutex_unlock(&audio->read_lock); - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audevrc_out_flush(audio); - mutex_unlock(&audio->write_lock); -} - -static void audevrc_in_flush(struct audio_evrc_in *audio) -{ - int i; - unsigned long flags; - - audio->dsp_cnt = 0; - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->in_head = 0; - audio->in_tail = 0; - audio->in_count = 0; - audio->eos_ack = 0; - for (i = FRAME_NUM-1; i >= 0; i--) { - audio->in[i].size = 0; - audio->in[i].read = 0; - } - spin_unlock_irqrestore(&audio->dsp_lock, flags); - MM_DBG("in_bytes %d\n", atomic_read(&audio->in_bytes)); - MM_DBG("in_samples %d\n", atomic_read(&audio->in_samples)); - atomic_set(&audio->in_bytes, 0); - atomic_set(&audio->in_samples, 0); -} - -static void audevrc_out_flush(struct audio_evrc_in *audio) -{ - int i; - unsigned long flags; - - audio->out_head = 0; - audio->out_count = 0; - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->out_tail = 0; - for (i = OUT_FRAME_NUM-1; i >= 0; i--) { - audio->out[i].size = 0; - audio->out[i].read = 0; - audio->out[i].used = 0; - } - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ -static long audevrc_in_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct audio_evrc_in *audio = file->private_data; - int rc = 0; - - MM_DBG("\n"); - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = atomic_read(&audio->in_bytes); - stats.sample_count = atomic_read(&audio->in_samples); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return rc; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: { - rc = audevrc_in_enable(audio); - if (!rc) { - rc = - wait_event_interruptible_timeout(audio->wait_enable, - audio->running != 0, 1*HZ); - MM_DBG("state %d rc = %d\n", audio->running, rc); - - if (audio->running == 0) - rc = -ENODEV; - else - rc = 0; - } - audio->stopped = 0; - break; - } - case AUDIO_STOP: { - rc = audevrc_in_disable(audio); - break; - } - case AUDIO_FLUSH: { - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audevrc_ioport_reset(audio); - if (audio->running) { - audevrc_flush_command(audio); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config cfg; - memset(&cfg, 0, sizeof(cfg)); - cfg.buffer_size = OUT_BUFFER_SIZE; - cfg.buffer_count = OUT_FRAME_NUM; - cfg.sample_rate = convert_samp_index(audio->samp_rate); - cfg.channel_count = 1; - cfg.type = 0; - cfg.unused[0] = 0; - cfg.unused[1] = 0; - cfg.unused[2] = 0; - if (copy_to_user((void *) arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_GET_STREAM_CONFIG: { - struct msm_audio_stream_config cfg; - memset(&cfg, 0, sizeof(cfg)); - cfg.buffer_size = audio->buffer_size; - cfg.buffer_count = FRAME_NUM; - if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_STREAM_CONFIG: { - struct msm_audio_stream_config cfg; - if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - /* Allow only single frame */ - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - if (cfg.buffer_size != (FRAME_SIZE - 8)) { - rc = -EINVAL; - break; - } - } else { - if (cfg.buffer_size != (EVRC_FRAME_SIZE + 14)) { - rc = -EINVAL; - break; - } - } - audio->buffer_size = cfg.buffer_size; - break; - } - case AUDIO_GET_EVRC_ENC_CONFIG: { - if (copy_to_user((void *) arg, &audio->cfg, sizeof(audio->cfg))) - rc = -EFAULT; - break; - } - case AUDIO_SET_EVRC_ENC_CONFIG: { - struct msm_audio_evrc_enc_config cfg; - if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - MM_DBG("0X%8x, 0x%8x, 0x%8x\n", cfg.min_bit_rate, - cfg.max_bit_rate, cfg.cdma_rate); - if (cfg.min_bit_rate > CDMA_RATE_FULL || \ - cfg.min_bit_rate < CDMA_RATE_EIGHTH) { - MM_ERR("invalid min bitrate\n"); - rc = -EFAULT; - break; - } - if (cfg.max_bit_rate > CDMA_RATE_FULL || \ - cfg.max_bit_rate < CDMA_RATE_EIGHTH) { - MM_ERR("invalid max bitrate\n"); - rc = -EFAULT; - break; - } - /* Recording Does not support Erase and Blank */ - if (cfg.cdma_rate > CDMA_RATE_FULL || - cfg.cdma_rate < CDMA_RATE_EIGHTH) { - MM_ERR("invalid qcelp cdma rate\n"); - rc = -EFAULT; - break; - } - memcpy(&audio->cfg, &cfg, sizeof(cfg)); - break; - } - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -static ssize_t audevrc_in_read(struct file *file, - char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_evrc_in *audio = file->private_data; - unsigned long flags; - const char __user *start = buf; - void *data; - uint32_t index; - uint32_t size; - int rc = 0; - struct evrc_encoded_meta_out meta_field; - struct audio_frame_nt *nt_frame; - MM_DBG("count = %d\n", count); - mutex_lock(&audio->read_lock); - while (count > 0) { - rc = wait_event_interruptible( - audio->wait, (audio->in_count > 0) || audio->stopped || - audio->rflush); - if (rc < 0) - break; - - if (audio->rflush) { - rc = -EBUSY; - break; - } - if (audio->stopped && !audio->in_count) { - MM_DBG("Driver in stop state, No more buffer to read"); - rc = 0;/* End of File */ - break; - } - - index = audio->in_tail; - data = (uint8_t *) audio->in[index].data; - size = audio->in[index].size; - - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) { - nt_frame = (struct audio_frame_nt *)(data - - sizeof(struct audio_frame_nt)); - memcpy((char *)&meta_field.time_stamp_dword_lsw, - (char *)&nt_frame->time_stamp_dword_lsw, - (sizeof(struct evrc_encoded_meta_out) - \ - sizeof(uint16_t))); - meta_field.metadata_len = - sizeof(struct evrc_encoded_meta_out); - if (copy_to_user((char *)start, (char *)&meta_field, - sizeof(struct evrc_encoded_meta_out))) { - rc = -EFAULT; - break; - } - if (nt_frame->nflag_lsw & 0x0001) { - MM_ERR("recieved EOS in read call\n"); - audio->eos_ack = 1; - } - buf += sizeof(struct evrc_encoded_meta_out); - count -= sizeof(struct evrc_encoded_meta_out); - } - if (count >= size) { - /* order the reads on the buffer */ - dma_coherent_post_ops(); - if (copy_to_user(buf, data, size)) { - rc = -EFAULT; - break; - } - spin_lock_irqsave(&audio->dsp_lock, flags); - if (index != audio->in_tail) { - /* overrun -- data is - * invalid and we need to retry */ - spin_unlock_irqrestore(&audio->dsp_lock, flags); - continue; - } - audio->in[index].size = 0; - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - audio->in_count--; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - count -= size; - buf += size; - if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL)) { - if (!audio->eos_ack) { - MM_DBG("sending read ptr command \ - %d %d\n", - audio->dsp_cnt, - audio->in_tail); - audevrc_in_dsp_read_buffer(audio, - audio->dsp_cnt++); - } - } - } else { - MM_ERR("short read\n"); - break; - } - break; - } - mutex_unlock(&audio->read_lock); - - if (buf > start) - return buf - start; - - return rc; -} - -static void audrec_pcm_send_data(struct audio_evrc_in *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - MM_DBG("\n"); - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - audrec_pcm_buffer_ptr_refresh(audio, - audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } - done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static int audevrc_in_fsync(struct file *file, loff_t a, loff_t b, - int datasync) - -{ - struct audio_evrc_in *audio = file->private_data; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - if (!audio->running || (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - audio->wflush); - MM_DBG("waked on by some event audio->wflush = %d\n", audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; - -} - -int audrec_evrc_process_eos(struct audio_evrc_in *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - struct buffer *frame; - int rc = 0; - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - MM_DBG("copying meta_out frame->used = %d\n", frame->used); - audrec_pcm_send_data(audio, 0); -done: - return rc; -} - -static ssize_t audevrc_in_write(struct file *file, - const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_evrc_in *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - char *cpy_ptr; - int rc = 0, eos_condition = AUDPREPROC_EVRC_EOS_NONE; - unsigned short mfield_size = 0; - int write_count = 0; - MM_DBG("cnt=%d\n", count); - - if (count & 1) - return -EINVAL; - - if (audio->mode != MSM_AUD_ENC_MODE_NONTUNNEL) - return -EINVAL; - - mutex_lock(&audio->write_lock); - frame = audio->out + audio->out_head; - /* if supplied count is more than driver buffer size - * then only copy driver buffer size - */ - if (count > frame->size) - count = frame->size; - - write_count = count; - cpy_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - goto error; - - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto error; - } - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - goto error; - } else if (mfield_size > count) { - rc = -EINVAL; - goto error; - } - MM_DBG("mf offset_val %x\n", mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - goto error; - } - /* Check if EOS flag is set and buffer has - * contains just meta field - */ - if (cpy_ptr[AUDPREPROC_EVRC_EOS_FLG_OFFSET] & - AUDPREPROC_EVRC_EOS_FLG_MASK) { - eos_condition = AUDPREPROC_EVRC_EOS_SET; - MM_DBG("EOS SET\n"); - if (mfield_size == count) { - buf += mfield_size; - eos_condition = 0; - goto exit; - } else - cpy_ptr[AUDPREPROC_EVRC_EOS_FLG_OFFSET] &= - ~AUDPREPROC_EVRC_EOS_FLG_MASK; - } - cpy_ptr += mfield_size; - count -= mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - MM_DBG("copying the stream count = %d\n", count); - if (copy_from_user(cpy_ptr, buf, count)) { - rc = -EFAULT; - goto error; - } -exit: - frame->used = count; - audio->out_head ^= 1; - if (!audio->flush_ack) - audrec_pcm_send_data(audio, 0); - else { - audrec_pcm_send_data(audio, 1); - audio->flush_ack = 0; - } - if (eos_condition == AUDPREPROC_EVRC_EOS_SET) - rc = audrec_evrc_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - return write_count; -error: - mutex_unlock(&audio->write_lock); - return rc; -} - -static int audevrc_in_release(struct inode *inode, struct file *file) -{ - struct audio_evrc_in *audio = file->private_data; - - mutex_lock(&audio->lock); - audevrc_in_disable(audio); - audevrc_in_flush(audio); - msm_adsp_put(audio->audrec); - - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - msm_adsp_put(audio->audpre); - - audpreproc_aenc_free(audio->enc_id); - audio->audrec = NULL; - audio->audpre = NULL; - audio->opened = 0; - if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) && \ - (audio->out_data)) { - ion_unmap_kernel(audio->client, audio->input_buff_handle); - ion_free(audio->client, audio->input_buff_handle); - audio->out_data = NULL; - } - if (audio->data) { - ion_unmap_kernel(audio->client, audio->output_buff_handle); - ion_free(audio->client, audio->output_buff_handle); - audio->data = NULL; - } - ion_client_destroy(audio->client); - mutex_unlock(&audio->lock); - return 0; -} - -static struct audio_evrc_in the_audio_evrc_in; - -static int audevrc_in_open(struct inode *inode, struct file *file) -{ - struct audio_evrc_in *audio = &the_audio_evrc_in; - int rc; - int encid; - int dma_size = 0; - int len = 0; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - struct ion_client *client = NULL; - - mutex_lock(&audio->lock); - if (audio->opened) { - rc = -EBUSY; - goto done; - } - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - audio->mode = MSM_AUD_ENC_MODE_NONTUNNEL; - dma_size = NT_DMASZ; - MM_DBG("Opened for non tunnel mode encoding\n"); - } else if (!(file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - audio->mode = MSM_AUD_ENC_MODE_TUNNEL; - dma_size = DMASZ; - MM_DBG("Opened for tunnel mode encoding\n"); - } else { - MM_ERR("Invalid mode\n"); - rc = -EACCES; - goto done; - } - - /* Settings will be re-config at AUDIO_SET_CONFIG, - * but at least we need to have initial config - */ - audio->samp_rate = RPC_AUD_DEF_SAMPLE_RATE_8000, - audio->samp_rate_index = AUDREC_CMD_SAMP_RATE_INDX_8000; - audio->channel_mode = AUDREC_CMD_STEREO_MODE_MONO; - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) - audio->buffer_size = (EVRC_FRAME_SIZE + 14); - else - audio->buffer_size = EVRC_FRAME_SIZE; - audio->enc_type = AUDREC_CMD_TYPE_0_INDEX_EVRC | audio->mode; - - audio->cfg.cdma_rate = CDMA_RATE_FULL; - audio->cfg.min_bit_rate = CDMA_RATE_FULL; - audio->cfg.max_bit_rate = CDMA_RATE_FULL; - - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - rc = audmgr_open(&audio->audmgr); - if (rc) - goto done; - } - - encid = audpreproc_aenc_alloc(audio->enc_type, &audio->module_name, - &audio->queue_ids); - if (encid < 0) { - MM_ERR("No free encoder available\n"); - rc = -ENODEV; - goto done; - } - audio->enc_id = encid; - - rc = msm_adsp_get(audio->module_name, &audio->audrec, - &audrec_evrc_adsp_ops, audio); - if (rc) { - audpreproc_aenc_free(audio->enc_id); - goto done; - } - - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre, - &audpre_evrc_adsp_ops, audio); - if (rc) { - msm_adsp_put(audio->audrec); - audpreproc_aenc_free(audio->enc_id); - goto done; - } - } - - audio->dsp_cnt = 0; - audio->stopped = 0; - audio->wflush = 0; - audio->rflush = 0; - audio->flush_ack = 0; - - audevrc_in_flush(audio); - audevrc_out_flush(audio); - - client = msm_ion_client_create(UINT_MAX, "Audio_EVRC_in_client"); - if (IS_ERR_OR_NULL(client)) { - MM_ERR("Unable to create ION client\n"); - rc = -ENOMEM; - goto client_create_error; - } - audio->client = client; - - MM_DBG("allocating mem sz = %d\n", dma_size); - handle = ion_alloc(client, dma_size, SZ_4K, - ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to create allocate O/P buffers\n"); - rc = -ENOMEM; - goto output_buff_alloc_error; - } - - audio->output_buff_handle = handle; - - rc = ion_phys(client , handle, &addr, &len); - if (rc) { - MM_ERR("O/P buffers:Invalid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - rc = -ENOMEM; - goto output_buff_get_phys_error; - } else { - MM_INFO("O/P buffers:valid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - } - audio->phys = (int32_t)addr; - - rc = ion_handle_get_flags(client, handle, &ionflag); - if (rc) { - MM_ERR("could not get flags for the handle\n"); - rc = -ENOMEM; - goto output_buff_get_flags_error; - } - - audio->map_v_read = ion_map_kernel(client, handle); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("could not map read buffers,freeing instance 0x%08x\n", - (int)audio); - rc = -ENOMEM; - goto output_buff_map_error; - } - audio->data = audio->map_v_read; - MM_DBG("read buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->phys, (int)audio->data); - - audio->out_data = NULL; - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) { - MM_DBG("allocating BUFFER_SIZE %d\n", BUFFER_SIZE); - handle = ion_alloc(client, BUFFER_SIZE, - SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to create allocate I/P buffers\n"); - rc = -ENOMEM; - goto input_buff_alloc_error; - } - - audio->input_buff_handle = handle; - - rc = ion_phys(client , handle, &addr, &len); - if (rc) { - MM_ERR("I/P buffers:Invalid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - rc = -ENOMEM; - goto input_buff_alloc_error; - } else { - MM_INFO("Got valid phy: %x sz: %x\n", - (unsigned int) addr, - (unsigned int) len); - } - audio->out_phys = (int32_t)addr; - - rc = ion_handle_get_flags(client, - handle, &ionflag); - if (rc) { - MM_ERR("could not get flags for the handle\n"); - rc = -ENOMEM; - goto input_buff_alloc_error; - } - - audio->map_v_write = ion_map_kernel(client, handle); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write buffers\n"); - rc = -ENOMEM; - goto input_buff_map_error; - } - audio->out_data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n", - (unsigned int)addr, - (unsigned int)audio->out_data); - - /* Initialize buffer */ - audio->out[0].data = audio->out_data + 0; - audio->out[0].addr = audio->out_phys + 0; - audio->out[0].size = OUT_BUFFER_SIZE; - - audio->out[1].data = audio->out_data + OUT_BUFFER_SIZE; - audio->out[1].addr = audio->out_phys + OUT_BUFFER_SIZE; - audio->out[1].size = OUT_BUFFER_SIZE; - - MM_DBG("audio->out[0].data = %d audio->out[1].data = %d", - (unsigned int)audio->out[0].data, - (unsigned int)audio->out[1].data); - audio->mfield = NT_FRAME_HEADER_SIZE; - audio->out_frame_cnt++; - } - file->private_data = audio; - audio->opened = 1; - -done: - mutex_unlock(&audio->lock); - return rc; -input_buff_map_error: - ion_free(client, audio->input_buff_handle); -input_buff_alloc_error: - ion_unmap_kernel(client, audio->output_buff_handle); -output_buff_map_error: -output_buff_get_phys_error: -output_buff_get_flags_error: - ion_free(client, audio->output_buff_handle); -output_buff_alloc_error: - ion_client_destroy(client); -client_create_error: - msm_adsp_put(audio->audrec); - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - msm_adsp_put(audio->audpre); - - audpreproc_aenc_free(audio->enc_id); - mutex_unlock(&audio->lock); - return rc; -} - -static const struct file_operations audio_evrc_in_fops = { - .owner = THIS_MODULE, - .open = audevrc_in_open, - .release = audevrc_in_release, - .read = audevrc_in_read, - .write = audevrc_in_write, - .fsync = audevrc_in_fsync, - .unlocked_ioctl = audevrc_in_ioctl, -}; - -static struct miscdevice audevrc_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_evrc_in", - .fops = &audio_evrc_in_fops, -}; - -static int __init audevrc_in_init(void) -{ - mutex_init(&the_audio_evrc_in.lock); - mutex_init(&the_audio_evrc_in.read_lock); - spin_lock_init(&the_audio_evrc_in.dsp_lock); - init_waitqueue_head(&the_audio_evrc_in.wait); - init_waitqueue_head(&the_audio_evrc_in.wait_enable); - mutex_init(&the_audio_evrc_in.write_lock); - init_waitqueue_head(&the_audio_evrc_in.write_wait); - return misc_register(&audevrc_in_misc); -} -device_initcall(audevrc_in_init); diff --git a/arch/arm/mach-msm/qdsp5/audio_fm.c b/arch/arm/mach-msm/qdsp5/audio_fm.c deleted file mode 100644 index 957a407462b84efbfb14498ee9c77ef20e49659a..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_fm.c +++ /dev/null @@ -1,169 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/audio_fm.c - * - * pcm audio output device - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2011, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include - -#include "audmgr.h" - -struct audio { - struct mutex lock; - int opened; - int enabled; - int running; - struct audmgr audmgr; - uint16_t volume; -}; - -static struct audio fm_audio; - -/* must be called with audio->lock held */ -static int audio_enable(struct audio *audio) -{ - struct audmgr_config cfg; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (audio->enabled) - return 0; - - cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000; - cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000; - cfg.def_method = RPC_AUD_DEF_METHOD_HOST_PCM; - cfg.codec = RPC_AUD_DEF_CODEC_PCM; - cfg.snd_method = RPC_SND_METHOD_VOICE; - - rc = audmgr_enable(&audio->audmgr, &cfg); - if (rc < 0) - return rc; - - audio->enabled = 1; - return rc; -} - -/* must be called with audio->lock held */ -static int audio_disable(struct audio *audio) -{ - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audmgr_disable(&audio->audmgr); - } - return 0; -} - -static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - - MM_DBG("cmd %d", cmd); - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audio_enable(audio); - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audio_disable(audio); - audio->running = 0; - audio->enabled = 0; - break; - - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -static int audio_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_DBG("audio instance 0x%08x freeing\n", (int)audio); - mutex_lock(&audio->lock); - audio_disable(audio); - audio->running = 0; - audio->enabled = 0; - audio->opened = 0; - mutex_unlock(&audio->lock); - return 0; -} - -static int audio_open(struct inode *inode, struct file *file) -{ - struct audio *audio = &fm_audio; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - mutex_lock(&audio->lock); - - if (audio->opened) { - MM_ERR("busy\n"); - rc = -EBUSY; - goto done; - } - - rc = audmgr_open(&audio->audmgr); - - if (rc) { - MM_ERR("%s: failed to register listnet\n", __func__); - goto done; - } - - file->private_data = audio; - audio->opened = 1; - -done: - mutex_unlock(&audio->lock); - return rc; -} - -static const struct file_operations audio_fm_fops = { - .owner = THIS_MODULE, - .open = audio_open, - .release = audio_release, - .unlocked_ioctl = audio_ioctl, -}; - -struct miscdevice audio_fm_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_fm", - .fops = &audio_fm_fops, -}; - -static int __init audio_init(void) -{ - struct audio *audio = &fm_audio; - - mutex_init(&audio->lock); - return misc_register(&audio_fm_misc); -} - -device_initcall(audio_init); - -MODULE_DESCRIPTION("MSM FM driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5/audio_in.c b/arch/arm/mach-msm/qdsp5/audio_in.c deleted file mode 100644 index 6fc2ac03be46853973dba630dfd0c1679166c7da..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_in.c +++ /dev/null @@ -1,996 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/audio_in.c - * - * pcm audio input device - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include - -#include "audmgr.h" - -#include -#include -#include -#include -#include - -/* FRAME_NUM must be a power of two */ -#define FRAME_NUM (8) -#define FRAME_SIZE (2052 * 2) -#define MONO_DATA_SIZE (2048) -#define STEREO_DATA_SIZE (MONO_DATA_SIZE * 2) -#define DMASZ (FRAME_SIZE * FRAME_NUM) - -struct buffer { - void *data; - uint32_t size; - uint32_t read; - uint32_t addr; -}; - -struct audio_in { - struct buffer in[FRAME_NUM]; - - spinlock_t dsp_lock; - - atomic_t in_bytes; - - struct mutex lock; - struct mutex read_lock; - wait_queue_head_t wait; - - struct msm_adsp_module *audpre; - struct msm_adsp_module *audrec; - - /* configuration to use on next enable */ - uint32_t samp_rate; - uint32_t channel_mode; - uint32_t buffer_size; /* 2048 for mono, 4096 for stereo */ - uint32_t type; /* 0 for PCM ,1 for AAC */ - uint32_t bit_rate; /* bit rate for AAC */ - uint32_t record_quality; /* record quality (bits/sample/channel) - for AAC*/ - uint32_t buffer_cfg_ioctl; /* to allow any one of buffer set ioctl */ - uint32_t dsp_cnt; - uint32_t in_head; /* next buffer dsp will write */ - uint32_t in_tail; /* next buffer read() will read */ - uint32_t in_count; /* number of buffers available to read() */ - - unsigned short samp_rate_index; - - struct audmgr audmgr; - - /* data allocated for various buffers */ - char *data; - dma_addr_t phys; - - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - - /* audpre settings */ - int tx_agc_enable; - audpreproc_cmd_cfg_agc_params tx_agc_cfg; - int ns_enable; - audpreproc_cmd_cfg_ns_params ns_cfg; - /* For different sample rate, the coeff might be different. * - * All the coeff should be passed from user space */ - int iir_enable; - audpreproc_cmd_cfg_iir_tuning_filter_params iir_cfg; -}; - -static int audio_in_dsp_enable(struct audio_in *audio, int enable); -static int audio_in_encoder_config(struct audio_in *audio); -static int audio_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt); -static void audio_flush(struct audio_in *audio); -static int audio_dsp_set_tx_agc(struct audio_in *audio); -static int audio_dsp_set_ns(struct audio_in *audio); -static int audio_dsp_set_iir(struct audio_in *audio); - -static unsigned convert_dsp_samp_index(unsigned index) -{ - switch (index) { - case 48000: return AUDREC_CMD_SAMP_RATE_INDX_48000; - case 44100: return AUDREC_CMD_SAMP_RATE_INDX_44100; - case 32000: return AUDREC_CMD_SAMP_RATE_INDX_32000; - case 24000: return AUDREC_CMD_SAMP_RATE_INDX_24000; - case 22050: return AUDREC_CMD_SAMP_RATE_INDX_22050; - case 16000: return AUDREC_CMD_SAMP_RATE_INDX_16000; - case 12000: return AUDREC_CMD_SAMP_RATE_INDX_12000; - case 11025: return AUDREC_CMD_SAMP_RATE_INDX_11025; - case 8000: return AUDREC_CMD_SAMP_RATE_INDX_8000; - default: return AUDREC_CMD_SAMP_RATE_INDX_11025; - } -} - -static unsigned convert_samp_rate(unsigned hz) -{ - switch (hz) { - case 48000: return RPC_AUD_DEF_SAMPLE_RATE_48000; - case 44100: return RPC_AUD_DEF_SAMPLE_RATE_44100; - case 32000: return RPC_AUD_DEF_SAMPLE_RATE_32000; - case 24000: return RPC_AUD_DEF_SAMPLE_RATE_24000; - case 22050: return RPC_AUD_DEF_SAMPLE_RATE_22050; - case 16000: return RPC_AUD_DEF_SAMPLE_RATE_16000; - case 12000: return RPC_AUD_DEF_SAMPLE_RATE_12000; - case 11025: return RPC_AUD_DEF_SAMPLE_RATE_11025; - case 8000: return RPC_AUD_DEF_SAMPLE_RATE_8000; - default: return RPC_AUD_DEF_SAMPLE_RATE_11025; - } -} - -static unsigned convert_samp_index(unsigned index) -{ - switch (index) { - case RPC_AUD_DEF_SAMPLE_RATE_48000: return 48000; - case RPC_AUD_DEF_SAMPLE_RATE_44100: return 44100; - case RPC_AUD_DEF_SAMPLE_RATE_32000: return 32000; - case RPC_AUD_DEF_SAMPLE_RATE_24000: return 24000; - case RPC_AUD_DEF_SAMPLE_RATE_22050: return 22050; - case RPC_AUD_DEF_SAMPLE_RATE_16000: return 16000; - case RPC_AUD_DEF_SAMPLE_RATE_12000: return 12000; - case RPC_AUD_DEF_SAMPLE_RATE_11025: return 11025; - case RPC_AUD_DEF_SAMPLE_RATE_8000: return 8000; - default: return 11025; - } -} - -/* must be called with audio->lock held */ -static int audio_in_enable(struct audio_in *audio) -{ - struct audmgr_config cfg; - int rc; - - if (audio->enabled) - return 0; - - cfg.tx_rate = audio->samp_rate; - cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; - cfg.def_method = RPC_AUD_DEF_METHOD_RECORD; - if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV) - cfg.codec = RPC_AUD_DEF_CODEC_PCM; - else - cfg.codec = RPC_AUD_DEF_CODEC_AAC; - cfg.snd_method = RPC_SND_METHOD_MIDI; - - rc = audmgr_enable(&audio->audmgr, &cfg); - if (rc < 0) - return rc; - - if (msm_adsp_enable(audio->audpre)) { - MM_ERR("msm_adsp_enable(audpre) failed\n"); - return -ENODEV; - } - if (msm_adsp_enable(audio->audrec)) { - MM_ERR("msm_adsp_enable(audrec) failed\n"); - return -ENODEV; - } - - audio->enabled = 1; - audio_in_dsp_enable(audio, 1); - - return 0; -} - -/* must be called with audio->lock held */ -static int audio_in_disable(struct audio_in *audio) -{ - if (audio->enabled) { - audio->enabled = 0; - - audio_in_dsp_enable(audio, 0); - - wake_up(&audio->wait); - - msm_adsp_disable(audio->audrec); - msm_adsp_disable(audio->audpre); - audmgr_disable(&audio->audmgr); - } - return 0; -} - -/* ------------------- dsp --------------------- */ -static void audpre_dsp_event(void *data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - uint16_t msg[2]; - getevent(msg, sizeof(msg)); - - switch (id) { - case AUDPREPROC_MSG_CMD_CFG_DONE_MSG: - MM_INFO("type %d, status_flag %d\n", msg[0], msg[1]); - break; - case AUDPREPROC_MSG_ERROR_MSG_ID: - MM_INFO("err_index %d\n", msg[0]); - break; - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audpreproctask)\n"); - break; - default: - MM_ERR("unknown event %d\n", id); - } -} - -struct audio_frame { - uint16_t count_low; - uint16_t count_high; - uint16_t bytes; - uint16_t unknown; - unsigned char samples[]; -} __attribute__((packed)); - -static void audio_in_get_dsp_frames(struct audio_in *audio) -{ - struct audio_frame *frame; - uint32_t index; - unsigned long flags; - - index = audio->in_head; - - /* XXX check for bogus frame size? */ - - frame = (void *) (((char *)audio->in[index].data) - - sizeof(*frame)); - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->in[index].size = frame->bytes; - - audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1); - - /* If overflow, move the tail index foward. */ - if (audio->in_head == audio->in_tail) - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - else - audio->in_count++; - - audio_dsp_read_buffer(audio, audio->dsp_cnt++); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - - wake_up(&audio->wait); -} - -static void audrec_dsp_event(void *data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - struct audio_in *audio = data; - uint16_t msg[3]; - getevent(msg, sizeof(msg)); - - switch (id) { - case AUDREC_MSG_CMD_CFG_DONE_MSG: - if (msg[0] & AUDREC_MSG_CFG_DONE_TYPE_0_UPDATE) { - if (msg[0] & AUDREC_MSG_CFG_DONE_TYPE_0_ENA) { - MM_INFO("CFG ENABLED\n"); - audio_in_encoder_config(audio); - } else { - MM_INFO("CFG SLEEP\n"); - audio->running = 0; - audio->tx_agc_enable = 0; - audio->ns_enable = 0; - audio->iir_enable = 0; - } - } else { - MM_INFO("CMD_CFG_DONE %x\n", msg[0]); - } - break; - case AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG: { - MM_INFO("PARAM CFG DONE\n"); - audio->running = 1; - audio_dsp_set_tx_agc(audio); - audio_dsp_set_ns(audio); - audio_dsp_set_iir(audio); - break; - } - case AUDREC_MSG_FATAL_ERR_MSG: - MM_ERR("ERROR %x\n", msg[0]); - break; - case AUDREC_MSG_PACKET_READY_MSG: -/* REC_DBG("type %x, count %d", msg[0], (msg[1] | (msg[2] << 16))); */ - audio_in_get_dsp_frames(audio); - break; - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module \ - enable/disable(audrectask)\n"); - break; - default: - MM_ERR("unknown event %d\n", id); - } -} - -struct msm_adsp_ops audpre_adsp_ops = { - .event = audpre_dsp_event, -}; - -struct msm_adsp_ops audrec_adsp_ops = { - .event = audrec_dsp_event, -}; - - -#define audio_send_queue_pre(audio, cmd, len) \ - msm_adsp_write(audio->audpre, QDSP_uPAudPreProcCmdQueue, cmd, len) -#define audio_send_queue_recbs(audio, cmd, len) \ - msm_adsp_write(audio->audrec, QDSP_uPAudRecBitStreamQueue, cmd, len) -#define audio_send_queue_rec(audio, cmd, len) \ - msm_adsp_write(audio->audrec, \ - QDSP_uPAudRecCmdQueue, cmd, len) - -/* Convert Bit Rate to Record Quality field of DSP */ -static unsigned int bitrate_to_record_quality(unsigned int sample_rate, - unsigned int channel, unsigned int bit_rate) { - unsigned int temp; - - temp = sample_rate * channel; - MM_DBG(" sample rate * channel = %d \n", temp); - /* To represent in Q12 fixed format */ - temp = (bit_rate * 4096) / temp; - MM_DBG(" Record Quality = 0x%8x \n", temp); - return temp; -} - -static int audio_dsp_set_tx_agc(struct audio_in *audio) -{ - audpreproc_cmd_cfg_agc_params cmd; - - memset(&cmd, 0, sizeof(cmd)); - - audio->tx_agc_cfg.cmd_id = AUDPREPROC_CMD_CFG_AGC_PARAMS; - if (audio->tx_agc_enable) { - /* cmd.tx_agc_param_mask = 0xFE00 from sample code */ - audio->tx_agc_cfg.tx_agc_param_mask = - (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_SLOPE) | - (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_TH) | - (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_SLOPE) | - (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_TH) | - (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_AIG_FLAG) | - (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_STATIC_GAIN) | - (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG); - audio->tx_agc_cfg.tx_agc_enable_flag = - AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA; - /* cmd.param_mask = 0xFFF0 from sample code */ - audio->tx_agc_cfg.param_mask = - (1 << AUDPREPROC_CMD_PARAM_MASK_RMS_TAY) | - (1 << AUDPREPROC_CMD_PARAM_MASK_RELEASEK) | - (1 << AUDPREPROC_CMD_PARAM_MASK_DELAY) | - (1 << AUDPREPROC_CMD_PARAM_MASK_ATTACKK) | - (1 << AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_SLOW) | - (1 << AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_FAST) | - (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_RELEASEK) | - (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_MIN) | - (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_MAX) | - (1 << AUDPREPROC_CMD_PARAM_MASK_LEAK_UP) | - (1 << AUDPREPROC_CMD_PARAM_MASK_LEAK_DOWN) | - (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_ATTACKK); - } else { - audio->tx_agc_cfg.tx_agc_param_mask = - (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG); - audio->tx_agc_cfg.tx_agc_enable_flag = - AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS; - } - cmd = audio->tx_agc_cfg; - - return audio_send_queue_pre(audio, &cmd, sizeof(cmd)); -} - -static int audio_enable_tx_agc(struct audio_in *audio, int enable) -{ - if (audio->tx_agc_enable != enable) { - audio->tx_agc_enable = enable; - if (audio->running) - audio_dsp_set_tx_agc(audio); - } - return 0; -} - -static int audio_dsp_set_ns(struct audio_in *audio) -{ - audpreproc_cmd_cfg_ns_params cmd; - - memset(&cmd, 0, sizeof(cmd)); - - audio->ns_cfg.cmd_id = AUDPREPROC_CMD_CFG_NS_PARAMS; - - if (audio->ns_enable) { - /* cmd.ec_mode_new is fixed as 0x0064 when enable - * from sample code */ - audio->ns_cfg.ec_mode_new = - AUDPREPROC_CMD_EC_MODE_NEW_NS_ENA | - AUDPREPROC_CMD_EC_MODE_NEW_HB_ENA | - AUDPREPROC_CMD_EC_MODE_NEW_VA_ENA; - } else { - audio->ns_cfg.ec_mode_new = - AUDPREPROC_CMD_EC_MODE_NEW_NLMS_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_DES_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_NS_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_CNI_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_NLES_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_HB_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_VA_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_PCD_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_FEHI_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_NEHI_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_NLPP_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_FNE_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_DIS; - } - cmd = audio->ns_cfg; - - return audio_send_queue_pre(audio, &cmd, sizeof(cmd)); -} - -static int audio_enable_ns(struct audio_in *audio, int enable) -{ - if (audio->ns_enable != enable) { - audio->ns_enable = enable; - if (audio->running) - audio_dsp_set_ns(audio); - } - return 0; -} - -static int audio_dsp_set_iir(struct audio_in *audio) -{ - audpreproc_cmd_cfg_iir_tuning_filter_params cmd; - - memset(&cmd, 0, sizeof(cmd)); - - audio->iir_cfg.cmd_id = AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS; - - if (audio->iir_enable) - /* cmd.active_flag is 0xFFFF from sample code but 0x0001 here */ - audio->iir_cfg.active_flag = AUDPREPROC_CMD_IIR_ACTIVE_FLAG_ENA; - else - audio->iir_cfg.active_flag = AUDPREPROC_CMD_IIR_ACTIVE_FLAG_DIS; - - cmd = audio->iir_cfg; - - return audio_send_queue_pre(audio, &cmd, sizeof(cmd)); -} - -static int audio_enable_iir(struct audio_in *audio, int enable) -{ - if (audio->iir_enable != enable) { - audio->iir_enable = enable; - if (audio->running) - audio_dsp_set_iir(audio); - } - return 0; -} - -static int audio_in_dsp_enable(struct audio_in *audio, int enable) -{ - audrec_cmd_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_CFG; - cmd.type_0 = enable ? AUDREC_CMD_TYPE_0_ENA : AUDREC_CMD_TYPE_0_DIS; - cmd.type_0 |= (AUDREC_CMD_TYPE_0_UPDATE | audio->type); - cmd.type_1 = 0; - - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audio_in_encoder_config(struct audio_in *audio) -{ - audrec_cmd_arec0param_cfg cmd; - uint16_t *data = (void *) audio->data; - unsigned n; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_AREC0PARAM_CFG; - cmd.ptr_to_extpkt_buffer_msw = audio->phys >> 16; - cmd.ptr_to_extpkt_buffer_lsw = audio->phys; - cmd.buf_len = FRAME_NUM; /* Both WAV and AAC use 8 frames */ - cmd.samp_rate_index = audio->samp_rate_index; - cmd.stereo_mode = audio->channel_mode; /* 0 for mono, 1 for stereo */ - - /* cmd.rec_quality is based on user set bit rate / sample rate / - * channel - */ - cmd.rec_quality = audio->record_quality; - - /* prepare buffer pointers: - * Mono: 1024 samples + 4 halfword header - * Stereo: 2048 samples + 4 halfword header - * AAC - * Mono/Stere: 768 + 4 halfword header - */ - for (n = 0; n < FRAME_NUM; n++) { - audio->in[n].data = data + 4; - if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV) - data += (4 + (audio->channel_mode ? 2048 : 1024)); - else if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC) - data += (4 + 768); - } - - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audio_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt) -{ - audrec_cmd_packet_ext_ptr cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_PACKET_EXT_PTR; - /* Both WAV and AAC use AUDREC_CMD_TYPE_0 */ - cmd.type = AUDREC_CMD_TYPE_0; - cmd.curr_rec_count_msw = read_cnt >> 16; - cmd.curr_rec_count_lsw = read_cnt; - - return audio_send_queue_recbs(audio, &cmd, sizeof(cmd)); -} - -/* ------------------- device --------------------- */ - -static void audio_flush(struct audio_in *audio) -{ - int i; - - audio->dsp_cnt = 0; - audio->in_head = 0; - audio->in_tail = 0; - audio->in_count = 0; - for (i = 0; i < FRAME_NUM; i++) { - audio->in[i].size = 0; - audio->in[i].read = 0; - } -} - -static long audio_in_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct audio_in *audio = file->private_data; - int rc; - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = atomic_read(&audio->in_bytes); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - rc = audio_in_enable(audio); - break; - case AUDIO_STOP: - rc = audio_in_disable(audio); - audio->stopped = 1; - break; - case AUDIO_FLUSH: - if (audio->stopped) { - /* Make sure we're stopped and we wake any threads - * that might be blocked holding the read_lock. - * While audio->stopped read threads will always - * exit immediately. - */ - wake_up(&audio->wait); - mutex_lock(&audio->read_lock); - audio_flush(audio); - mutex_unlock(&audio->read_lock); - } - case AUDIO_SET_CONFIG: { - struct msm_audio_config cfg; - /* The below code is to make mutual exclusive between - * AUDIO_SET_CONFIG and AUDIO_SET_STREAM_CONFIG. - * Allow any one IOCTL. - */ - if (audio->buffer_cfg_ioctl == AUDIO_SET_STREAM_CONFIG) { - rc = -EINVAL; - break; - } - if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - if (cfg.channel_count == 1) { - cfg.channel_count = AUDREC_CMD_STEREO_MODE_MONO; - } else if (cfg.channel_count == 2) { - cfg.channel_count = AUDREC_CMD_STEREO_MODE_STEREO; - } else { - rc = -EINVAL; - break; - } - - if (cfg.type == 0) { - cfg.type = AUDREC_CMD_TYPE_0_INDEX_WAV; - } else if (cfg.type == 1) { - cfg.type = AUDREC_CMD_TYPE_0_INDEX_AAC; - } else { - rc = -EINVAL; - break; - } - audio->samp_rate = convert_samp_rate(cfg.sample_rate); - audio->samp_rate_index = - convert_dsp_samp_index(cfg.sample_rate); - audio->channel_mode = cfg.channel_count; - audio->buffer_size = - audio->channel_mode ? STEREO_DATA_SIZE - : MONO_DATA_SIZE; - audio->type = cfg.type; - audio->buffer_cfg_ioctl = AUDIO_SET_CONFIG; - rc = 0; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config cfg; - cfg.buffer_size = audio->buffer_size; - cfg.buffer_count = FRAME_NUM; - cfg.sample_rate = convert_samp_index(audio->samp_rate); - if (audio->channel_mode == AUDREC_CMD_STEREO_MODE_MONO) - cfg.channel_count = 1; - else - cfg.channel_count = 2; - if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV) - cfg.type = 0; - else - cfg.type = 1; - cfg.unused[0] = 0; - cfg.unused[1] = 0; - cfg.unused[2] = 0; - if (copy_to_user((void *) arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_GET_STREAM_CONFIG: { - struct msm_audio_stream_config cfg; - cfg.buffer_size = audio->buffer_size; - cfg.buffer_count = FRAME_NUM; - if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_STREAM_CONFIG: { - struct msm_audio_stream_config cfg; - /* The below code is to make mutual exclusive between - * AUDIO_SET_CONFIG and AUDIO_SET_STREAM_CONFIG. - * Allow any one IOCTL. - */ - if (audio->buffer_cfg_ioctl == AUDIO_SET_CONFIG) { - rc = -EINVAL; - break; - } - if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } else - rc = 0; - audio->buffer_size = cfg.buffer_size; - /* The IOCTL is only of AAC, set the encoder as AAC */ - audio->type = 1; - audio->buffer_cfg_ioctl = AUDIO_SET_STREAM_CONFIG; - break; - } - case AUDIO_GET_AAC_ENC_CONFIG: { - struct msm_audio_aac_enc_config cfg; - if (audio->channel_mode == AUDREC_CMD_STEREO_MODE_MONO) - cfg.channels = 1; - else - cfg.channels = 2; - cfg.sample_rate = convert_samp_index(audio->samp_rate); - cfg.bit_rate = audio->bit_rate; - cfg.stream_format = AUDIO_AAC_FORMAT_RAW; - if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_AAC_ENC_CONFIG: { - struct msm_audio_aac_enc_config cfg; - unsigned int record_quality; - if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - if (cfg.stream_format != AUDIO_AAC_FORMAT_RAW) { - MM_ERR("unsupported AAC format\n"); - rc = -EINVAL; - break; - } - record_quality = bitrate_to_record_quality(cfg.sample_rate, - cfg.channels, cfg.bit_rate); - /* Range of Record Quality Supported by DSP, Q12 format */ - if ((record_quality < 0x800) || (record_quality > 0x4000)) { - MM_ERR("Unsupported bit rate \n"); - rc = -EINVAL; - break; - } - if (cfg.channels == 1) { - cfg.channels = AUDREC_CMD_STEREO_MODE_MONO; - } else if (cfg.channels == 2) { - cfg.channels = AUDREC_CMD_STEREO_MODE_STEREO; - } else { - rc = -EINVAL; - break; - } - audio->samp_rate = convert_samp_rate(cfg.sample_rate); - audio->samp_rate_index = - convert_dsp_samp_index(cfg.sample_rate); - audio->channel_mode = cfg.channels; - audio->bit_rate = cfg.bit_rate; - audio->record_quality = record_quality; - MM_DBG(" Record Quality = 0x%8x \n", audio->record_quality); - rc = 0; - break; - } - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -static ssize_t audio_in_read(struct file *file, - char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_in *audio = file->private_data; - unsigned long flags; - const char __user *start = buf; - void *data; - uint32_t index; - uint32_t size; - int rc = 0; - - mutex_lock(&audio->read_lock); - while (count > 0) { - rc = wait_event_interruptible( - audio->wait, (audio->in_count > 0) || audio->stopped); - if (rc < 0) - break; - - if (audio->stopped && !audio->in_count) { - rc = 0;/* End of File */ - break; - } - - index = audio->in_tail; - data = (uint8_t *) audio->in[index].data; - size = audio->in[index].size; - if (count >= size) { - /* order the reads on the buffer */ - dma_coherent_post_ops(); - if (copy_to_user(buf, data, size)) { - rc = -EFAULT; - break; - } - spin_lock_irqsave(&audio->dsp_lock, flags); - if (index != audio->in_tail) { - /* overrun -- data is invalid and we need to retry */ - spin_unlock_irqrestore(&audio->dsp_lock, flags); - continue; - } - audio->in[index].size = 0; - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - audio->in_count--; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - count -= size; - buf += size; - } else { - MM_ERR("short read\n"); - break; - } - if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC) - break; /* AAC only read one frame */ - } - mutex_unlock(&audio->read_lock); - - if (buf > start) - return buf - start; - - return rc; -} - -static ssize_t audio_in_write(struct file *file, - const char __user *buf, - size_t count, loff_t *pos) -{ - return -EINVAL; -} - -static int audio_in_release(struct inode *inode, struct file *file) -{ - struct audio_in *audio = file->private_data; - - mutex_lock(&audio->lock); - audio_in_disable(audio); - audio_flush(audio); - msm_adsp_put(audio->audrec); - msm_adsp_put(audio->audpre); - audio->audrec = NULL; - audio->audpre = NULL; - audio->opened = 0; - mutex_unlock(&audio->lock); - return 0; -} - -struct audio_in the_audio_in; - -static int audio_in_open(struct inode *inode, struct file *file) -{ - struct audio_in *audio = &the_audio_in; - int rc; - - mutex_lock(&audio->lock); - if (audio->opened) { - rc = -EBUSY; - goto done; - } - - /* Settings will be re-config at AUDIO_SET_CONFIG, - * but at least we need to have initial config - */ - audio->samp_rate = RPC_AUD_DEF_SAMPLE_RATE_11025; - audio->samp_rate_index = AUDREC_CMD_SAMP_RATE_INDX_11025; - audio->channel_mode = AUDREC_CMD_STEREO_MODE_MONO; - audio->buffer_size = MONO_DATA_SIZE; - audio->type = AUDREC_CMD_TYPE_0_INDEX_WAV; - - /* For AAC, bit rate hard coded, default settings is - * sample rate (11025) x channel count (1) x recording quality (1.75) - * = 19293 bps */ - audio->bit_rate = 19293; - audio->record_quality = 0x1c00; - - rc = audmgr_open(&audio->audmgr); - if (rc) - goto done; - rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre, - &audpre_adsp_ops, audio); - if (rc) - goto done; - rc = msm_adsp_get("AUDRECTASK", &audio->audrec, - &audrec_adsp_ops, audio); - if (rc) - goto done; - - audio->dsp_cnt = 0; - audio->stopped = 0; - audio->buffer_cfg_ioctl = 0; /* No valid ioctl set */ - - audio_flush(audio); - - file->private_data = audio; - audio->opened = 1; - rc = 0; -done: - mutex_unlock(&audio->lock); - return rc; -} - -static long audpre_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct audio_in *audio = file->private_data; - int rc = 0, enable; - uint16_t enable_mask; - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_ENABLE_AUDPRE: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - enable = (enable_mask & AGC_ENABLE) ? 1 : 0; - audio_enable_tx_agc(audio, enable); - enable = (enable_mask & NS_ENABLE) ? 1 : 0; - audio_enable_ns(audio, enable); - enable = (enable_mask & TX_IIR_ENABLE) ? 1 : 0; - audio_enable_iir(audio, enable); - break; - - case AUDIO_SET_AGC: - if (copy_from_user(&audio->tx_agc_cfg, (void *) arg, - sizeof(audio->tx_agc_cfg))) - rc = -EFAULT; - break; - - case AUDIO_SET_NS: - if (copy_from_user(&audio->ns_cfg, (void *) arg, - sizeof(audio->ns_cfg))) - rc = -EFAULT; - break; - - case AUDIO_SET_TX_IIR: - if (copy_from_user(&audio->iir_cfg, (void *) arg, - sizeof(audio->iir_cfg))) - rc = -EFAULT; - break; - - default: - rc = -EINVAL; - } - - mutex_unlock(&audio->lock); - return rc; -} - -static int audpre_open(struct inode *inode, struct file *file) -{ - struct audio_in *audio = &the_audio_in; - - file->private_data = audio; - - return 0; -} - -static struct file_operations audio_fops = { - .owner = THIS_MODULE, - .open = audio_in_open, - .release = audio_in_release, - .read = audio_in_read, - .write = audio_in_write, - .unlocked_ioctl = audio_in_ioctl, -}; - -struct miscdevice audio_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_pcm_in", - .fops = &audio_fops, -}; - -static const struct file_operations audpre_fops = { - .owner = THIS_MODULE, - .open = audpre_open, - .unlocked_ioctl = audpre_ioctl, -}; - -struct miscdevice audpre_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_preproc_ctl", - .fops = &audpre_fops, -}; - -static int __init audio_in_init(void) -{ - the_audio_in.data = dma_alloc_coherent(NULL, DMASZ, - &the_audio_in.phys, GFP_KERNEL); - if (!the_audio_in.data) { - MM_ERR("Unable to allocate DMA buffer\n"); - return -ENOMEM; - } - - mutex_init(&the_audio_in.lock); - mutex_init(&the_audio_in.read_lock); - spin_lock_init(&the_audio_in.dsp_lock); - init_waitqueue_head(&the_audio_in.wait); - return misc_register(&audio_in_misc) || misc_register(&audpre_misc); -} - -device_initcall(audio_in_init); diff --git a/arch/arm/mach-msm/qdsp5/audio_lpa.c b/arch/arm/mach-msm/qdsp5/audio_lpa.c deleted file mode 100644 index d2244d5c58013547e4bed8e1da5a9df00117d2fb..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_lpa.c +++ /dev/null @@ -1,1516 +0,0 @@ - -/* audio_lpa.c - low power audio driver - * - * Copyright (c) 2012, The Linux Foundation. All rights reserved. - * - * Based on the PCM decoder driver in arch/arm/mach-msm/qdsp5/audio_pcm.c - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * - * All source code in this file is licensed under the following license except - * where indicated. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "audmgr.h" - -/* for queue ids - should be relative to module number*/ -#include "adsp.h" - -#define ADRV_STATUS_AIO_INTF 0x00000001 -#define ADRV_STATUS_OBUF_GIVEN 0x00000002 -#define ADRV_STATUS_IBUF_GIVEN 0x00000004 -#define ADRV_STATUS_FSYNC 0x00000008 - -#define MSM_MAX_VOLUME 0x2000 -/* 17 added to avoid more deviation */ -#define MSM_VOLUME_STEP (MSM_MAX_VOLUME+17) -#define MSM_VOLUME_FACTOR (10000) - -/* Size must be power of 2 */ -#define MAX_BUF 2 -#define BUFSZ (524288) - -#define AUDDEC_DEC_PCM 0 - -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDPCM_EVENT_NUM 10 /* Default number of pre-allocated event packets */ - -#define __CONTAINS(r, v, l) ({ \ - typeof(r) __r = r; \ - typeof(v) __v = v; \ - typeof(v) __e = __v + l; \ - int res = ((__v >= __r->vaddr) && \ - (__e <= __r->vaddr + __r->len)); \ - res; \ -}) - -#define CONTAINS(r1, r2) ({ \ - typeof(r2) __r2 = r2; \ - __CONTAINS(r1, __r2->vaddr, __r2->len); \ -}) - -#define IN_RANGE(r, v) ({ \ - typeof(r) __r = r; \ - typeof(v) __vv = v; \ - int res = ((__vv >= __r->vaddr) && \ - (__vv < (__r->vaddr + __r->len))); \ - res; \ -}) - -#define OVERLAPS(r1, r2) ({ \ - typeof(r1) __r1 = r1; \ - typeof(r2) __r2 = r2; \ - typeof(__r2->vaddr) __v = __r2->vaddr; \ - typeof(__v) __e = __v + __r2->len - 1; \ - int res = (IN_RANGE(__r1, __v) || IN_RANGE(__r1, __e)); \ - res; \ -}) - -struct audio; - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audpcm_suspend_ctl { -struct early_suspend node; -struct audio *audio; -}; -#endif - -struct audpcm_event { - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audlpa_ion_region { - struct list_head list; - struct ion_handle *handle; - int fd; - void *vaddr; - unsigned long paddr; - unsigned long kvaddr; - unsigned long len; - unsigned ref_cnt; -}; - -struct audpcm_buffer_node { - struct list_head list; - struct msm_audio_aio_buf buf; - unsigned long paddr; -}; - -struct audio { - struct buffer out[2]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - struct list_head out_queue; /* queue to retain output buffers */ - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - struct msm_adsp_module *audplay; - - /* configuration to use on next enable */ - uint32_t out_sample_rate; - uint32_t out_channel_mode; - uint32_t out_bits; /* bits per sample */ - - struct audmgr audmgr; - - /* data allocated for various buffers */ - char *data; - int32_t phys; - struct msm_mapped_buffer *map_v_write; - - uint32_t drv_status; - int wflush; /* Write flush */ - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - int teos; /* valid only if tunnel mode & no data left for decoder */ - int rmt_resource_released; - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - int reserved; /* A byte is being reserved */ - char rsv_byte; /* Handle odd length user data */ - - const char *module_name; - unsigned queue_id; - - unsigned long volume; - - uint16_t dec_id; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audpcm_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - - struct list_head ion_region_queue; - int buffer_count; - int buffer_size; - struct ion_client *client; -}; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audpp_cmd_cfg_adec_params(struct audio *audio); -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg); -static void audpcm_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); -static unsigned long audlpa_ion_fixup(struct audio *audio, void *addr, - unsigned long len, int ref_up); -static void audpcm_async_send_data(struct audio *audio, - unsigned needed); - - -static int rmt_put_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_DISABLE; - cmd.dec_type = AUDDEC_DEC_PCM; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - - return put_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -static int rmt_get_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_ENABLE; - cmd.dec_type = AUDDEC_DEC_PCM; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - - return get_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -/* must be called with audio->lock held */ -static int audio_enable(struct audio *audio) -{ - struct audmgr_config cfg; - int rc; - - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) - return 0; - - if (audio->rmt_resource_released == 1) { - audio->rmt_resource_released = 0; - rc = rmt_get_resource(audio); - if (rc) - MM_ERR("ADSP resources are not available"); - } - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_tail = 0; - audio->out_needed = 0; - - cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; - cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000; - cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK; - cfg.codec = RPC_AUD_DEF_CODEC_PCM; - cfg.snd_method = RPC_SND_METHOD_MIDI; - - rc = audmgr_enable(&audio->audmgr, &cfg); - if (rc < 0) - return rc; - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - - audio->enabled = 1; - return 0; -} - -/* must be called with audio->lock held */ -static int audio_disable(struct audio *audio) -{ - int rc = 0; - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - audio->stopped = 1; - wake_up(&audio->write_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - audmgr_disable(&audio->audmgr); - audio->out_needed = 0; - rmt_put_resource(audio); - audio->rmt_resource_released = 1; - } - return rc; -} - -/* ------------------- dsp --------------------- */ -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - getevent(msg, sizeof(msg)); - - MM_DBG("msg_id=%x\n", id); - - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audpcm_async_send_data(audio, 1); - break; - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audplaytask)\n"); - break; - default: - MM_ERR("unexpected message from decoder\n"); - break; - } -} - -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status: sleep reason =0x%04x\n", - reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init\n"); - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg\n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play\n"); - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - default: - MM_ERR("unknown decoder status\n"); - break; - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - audpp_set_volume_and_pan(audio->dec_id, audio->volume, - 0); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audio->running = 0; - } else { - MM_ERR("CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - wake_up(&audio->write_wait); - break; - - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - - default: - MM_ERR("UNKNOWN (%d)\n", id); - } - -} - - -struct msm_adsp_ops audlpadec_adsp_ops = { - .event = audplay_dsp_event, -}; - - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id, \ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - u16 cfg_dec_cmd[AUDPP_CMD_CFG_DEC_TYPE_LEN / sizeof(unsigned short)]; - - memset(cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - - cfg_dec_cmd[0] = AUDPP_CMD_CFG_DEC_TYPE; - if (enable) - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_PCM | - AUDPP_CMD_LPA_MODE; - else - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} - -static void audpp_cmd_cfg_adec_params(struct audio *audio) -{ - audpp_cmd_cfg_adec_params_wav cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_WAV_LEN; - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = audio->out_sample_rate; - cmd.stereo_cfg = audio->out_channel_mode; - cmd.pcm_width = audio->out_bits; - cmd.sign = 0; - audpp_send_queue2(&cmd, sizeof(cmd)); -} -static void audpcm_async_send_data(struct audio *audio, unsigned needed) -{ - unsigned long flags; - - if (!audio->running) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - - if (needed && !audio->wflush) { - audio->out_needed = 1; - if (audio->drv_status & ADRV_STATUS_OBUF_GIVEN) { - /* pop one node out of queue */ - union msm_audio_event_payload payload; - struct audpcm_buffer_node *used_buf; - - MM_DBG("consumed\n"); - - BUG_ON(list_empty(&audio->out_queue)); - used_buf = list_first_entry(&audio->out_queue, - struct audpcm_buffer_node, list); - list_del(&used_buf->list); - payload.aio_buf = used_buf->buf; - audpcm_post_event(audio, AUDIO_EVENT_WRITE_DONE, - payload); - kfree(used_buf); - audio->drv_status &= ~ADRV_STATUS_OBUF_GIVEN; - } - } - if (audio->out_needed) { - struct audpcm_buffer_node *next_buf; - audplay_cmd_bitstream_data_avail cmd; - if (!list_empty(&audio->out_queue)) { - next_buf = list_first_entry(&audio->out_queue, - struct audpcm_buffer_node, list); - MM_DBG("next_buf %p\n", next_buf); - if (next_buf) { - MM_DBG("next buf phy %lx len %d\n", - next_buf->paddr, next_buf->buf.data_len); - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL; - if (next_buf->buf.data_len) - cmd.decoder_id = audio->dec_id; - else { - cmd.decoder_id = -1; - MM_DBG("input EOS signaled\n"); - } - cmd.buf_ptr = (unsigned) next_buf->paddr; - cmd.buf_size = next_buf->buf.data_len >> 1; - cmd.partition_number = 0; - /* complete writes to the input buffer */ - wmb(); - audplay_send_queue0(audio, &cmd, sizeof(cmd)); - audio->out_needed = 0; - audio->drv_status |= ADRV_STATUS_OBUF_GIVEN; - } - } - } - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ -static void audpcm_async_flush(struct audio *audio) -{ - struct audpcm_buffer_node *buf_node; - struct list_head *ptr, *next; - union msm_audio_event_payload payload; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - MM_DBG("\n"); /* Macro prints the file name and function */ - list_for_each_safe(ptr, next, &audio->out_queue) { - buf_node = list_entry(ptr, struct audpcm_buffer_node, list); - list_del(&buf_node->list); - payload.aio_buf = buf_node->buf; - audpcm_post_event(audio, AUDIO_EVENT_WRITE_DONE, - payload); - kfree(buf_node); - } - audio->drv_status &= ~ADRV_STATUS_OBUF_GIVEN; - audio->out_needed = 0; - atomic_set(&audio->out_bytes, 0); - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} -static void audio_ioport_reset(struct audio *audio) -{ - if (audio->drv_status & ADRV_STATUS_AIO_INTF) { - /* If fsync is in progress, make sure - * return value of fsync indicates - * abort due to flush - */ - if (audio->drv_status & ADRV_STATUS_FSYNC) { - MM_DBG("fsync in progress\n"); - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audpcm_async_flush(audio); - mutex_unlock(&audio->write_lock); - } else - audpcm_async_flush(audio); - } else { - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audpcm_async_flush(audio); - mutex_unlock(&audio->write_lock); - } -} - -static int audpcm_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audpcm_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audpcm_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audpcm_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audpcm_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - -static long audpcm_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audpcm_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - audio->event_wait, audpcm_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audpcm_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audpcm_event, list); - list_del(&drv_evt->list); - } - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - if (drv_evt && drv_evt->event_type == AUDIO_EVENT_WRITE_DONE) { - mutex_lock(&audio->lock); - audlpa_ion_fixup(audio, drv_evt->payload.aio_buf.buf_addr, - drv_evt->payload.aio_buf.buf_len, 0); - mutex_unlock(&audio->lock); - } - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audlpa_ion_check(struct audio *audio, - void *vaddr, unsigned long len) -{ - struct audlpa_ion_region *region_elt; - struct audlpa_ion_region t = {.vaddr = vaddr, .len = len }; - - list_for_each_entry(region_elt, &audio->ion_region_queue, list) { - if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) || - OVERLAPS(region_elt, &t)) { - MM_ERR("[%p]:region (vaddr %p len %ld)" - " clashes with registered region" - " (vaddr %p paddr %p len %ld)\n", - audio, vaddr, len, - region_elt->vaddr, - (void *)region_elt->paddr, region_elt->len); - return -EINVAL; - } - } - - return 0; -} -static int audlpa_ion_add(struct audio *audio, - struct msm_audio_ion_info *info) -{ - ion_phys_addr_t paddr; - size_t len; - unsigned long kvaddr; - struct audlpa_ion_region *region; - int rc = -EINVAL; - struct ion_handle *handle; - unsigned long ionflag; - - MM_ERR("\n"); /* Macro prints the file name and function */ - region = kmalloc(sizeof(*region), GFP_KERNEL); - - if (!region) { - rc = -ENOMEM; - goto end; - } - handle = ion_import_dma_buf(audio->client, info->fd); - if (IS_ERR_OR_NULL(handle)) { - pr_err("%s: could not get handle of the given fd\n", __func__); - goto import_error; - } - rc = ion_handle_get_flags(audio->client, handle, &ionflag); - if (rc) { - pr_err("%s: could not get flags for the handle\n", __func__); - goto flag_error; - } - kvaddr = (unsigned long)ion_map_kernel(audio->client, handle); - if (IS_ERR_OR_NULL((void *)kvaddr)) { - pr_err("%s: could not get virtual address\n", __func__); - goto map_error; - } - rc = ion_phys(audio->client, handle, &paddr, &len); - if (rc) { - pr_err("%s: could not get physical address\n", __func__); - goto ion_error; - } - rc = audlpa_ion_check(audio, info->vaddr, len); - if (rc < 0) { - MM_ERR("audpcm_ion_check failed\n"); - goto ion_error; - } - region->handle = handle; - region->vaddr = info->vaddr; - region->fd = info->fd; - region->paddr = paddr; - region->kvaddr = kvaddr; - region->len = len; - region->ref_cnt = 0; - MM_DBG("[%p]:add region paddr %lx vaddr %p, len %lu kvaddr %lx\n", - audio, region->paddr, region->vaddr, - region->len, region->kvaddr); - list_add_tail(®ion->list, &audio->ion_region_queue); - - return rc; - -ion_error: - ion_unmap_kernel(audio->client, handle); -map_error: -flag_error: - ion_free(audio->client, handle); -import_error: - kfree(region); -end: - return rc; -} - -static int audlpa_ion_remove(struct audio *audio, - struct msm_audio_ion_info *info) -{ - struct audlpa_ion_region *region; - struct list_head *ptr, *next; - int rc = -EINVAL; - - list_for_each_safe(ptr, next, &audio->ion_region_queue) { - region = list_entry(ptr, struct audlpa_ion_region, list); - - if (region != NULL && (region->fd == info->fd) && - (region->vaddr == info->vaddr)) { - if (region->ref_cnt) { - MM_DBG("%s[%p]:region %p in use ref_cnt %d\n", - __func__, audio, region, - region->ref_cnt); - break; - } - MM_DBG("remove region fd %d vaddr %p\n", - info->fd, info->vaddr); - list_del(®ion->list); - ion_unmap_kernel(audio->client, region->handle); - ion_free(audio->client, region->handle); - kfree(region); - rc = 0; - break; - } - } - - return rc; -} - -static int audlpa_ion_lookup_vaddr(struct audio *audio, void *addr, - unsigned long len, struct audlpa_ion_region **region) -{ - struct audlpa_ion_region *region_elt; - int match_count = 0; - *region = NULL; - - /* returns physical address or zero */ - list_for_each_entry(region_elt, &audio->ion_region_queue, list) { - if (addr >= region_elt->vaddr && - addr < region_elt->vaddr + region_elt->len && - addr + len <= region_elt->vaddr + region_elt->len) { - /* offset since we could pass vaddr inside a registerd - * ion buffer - */ - - match_count++; - if (!*region) - *region = region_elt; - } - } - - if (match_count > 1) { - MM_ERR("%s[%p]:multiple hits for vaddr %p, len %ld\n", - __func__, audio, addr, len); - list_for_each_entry(region_elt, &audio->ion_region_queue, - list) { - if (addr >= region_elt->vaddr && - addr < region_elt->vaddr + region_elt->len && - addr + len <= region_elt->vaddr + region_elt->len) - MM_ERR("\t%s[%p]:%p, %ld --> %p\n", - __func__, audio, - region_elt->vaddr, - region_elt->len, - (void *)region_elt->paddr); - } - } - return *region ? 0 : -1; -} -static unsigned long audlpa_ion_fixup(struct audio *audio, void *addr, - unsigned long len, int ref_up) -{ - struct audlpa_ion_region *region; - unsigned long paddr; - int ret; - - ret = audlpa_ion_lookup_vaddr(audio, addr, len, ®ion); - if (ret) { - MM_ERR("%s[%p]:lookup (%p, %ld) failed\n", - __func__, audio, addr, len); - return 0; - } - if (ref_up) - region->ref_cnt++; - else - region->ref_cnt--; - MM_DBG("found region %p ref_cnt %d\n", region, region->ref_cnt); - paddr = region->paddr + (addr - region->vaddr); - return paddr; -} - -/* audio -> lock must be held at this point */ -static int audlpa_aio_buf_add(struct audio *audio, unsigned dir, - void __user *arg) -{ - unsigned long flags; - struct audpcm_buffer_node *buf_node; - - buf_node = kmalloc(sizeof(*buf_node), GFP_KERNEL); - - if (!buf_node) - return -ENOMEM; - - if (copy_from_user(&buf_node->buf, arg, sizeof(buf_node->buf))) { - kfree(buf_node); - return -EFAULT; - } - - MM_DBG("node %p dir %x buf_addr %p buf_len %d data_len" - "%d\n", buf_node, dir, - buf_node->buf.buf_addr, buf_node->buf.buf_len, - buf_node->buf.data_len); - - buf_node->paddr = audlpa_ion_fixup( - audio, buf_node->buf.buf_addr, - buf_node->buf.buf_len, 1); - if (dir) { - /* write */ - if (!buf_node->paddr || - (buf_node->paddr & 0x1) || - (buf_node->buf.data_len & 0x1)) { - kfree(buf_node); - return -EINVAL; - } - spin_lock_irqsave(&audio->dsp_lock, flags); - list_add_tail(&buf_node->list, &audio->out_queue); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - audpcm_async_send_data(audio, 0); - } - MM_DBG("Add buf_node %p paddr %lx\n", buf_node, buf_node->paddr); - - return 0; -} - -static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = 0; - - MM_DBG("cmd = %d\n", cmd); - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = audpp_avsync_byte_count(audio->dec_id); - stats.sample_count = audpp_avsync_sample_count(audio->dec_id); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - if (cmd == AUDIO_SET_VOLUME) { - unsigned long flags; - spin_lock_irqsave(&audio->dsp_lock, flags); - - audio->volume = MSM_VOLUME_STEP * arg; - audio->volume /= MSM_VOLUME_FACTOR; - - if (audio->volume > MSM_MAX_VOLUME) - audio->volume = MSM_MAX_VOLUME; - - if (audio->running) - audpp_set_volume_and_pan(audio->dec_id, - audio->volume, 0); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - return 0; - } - if (cmd == AUDIO_GET_EVENT) { - MM_DBG("AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audpcm_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audio_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) - rc = -ENODEV; - else - rc = 0; - } - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audio_disable(audio); - audio_ioport_reset(audio); - audio->stopped = 0; - break; - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH\n"); - audio->wflush = 1; - audio_ioport_reset(audio); - if (audio->running) { - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->wflush = 0; - } - break; - - case AUDIO_SET_CONFIG: { - struct msm_audio_config config; - if (copy_from_user(&config, (void *) arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.channel_count == 1) { - config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V; - } else if (config.channel_count == 2) { - config.channel_count = AUDPP_CMD_PCM_INTF_STEREO_V; - } else { - rc = -EINVAL; - break; - } - if (config.bits == 8) - config.bits = AUDPP_CMD_WAV_PCM_WIDTH_8; - else if (config.bits == 16) - config.bits = AUDPP_CMD_WAV_PCM_WIDTH_16; - else { - rc = -EINVAL; - break; - } - audio->out_sample_rate = config.sample_rate; - audio->out_channel_mode = config.channel_count; - audio->out_bits = config.bits; - audio->buffer_count = config.buffer_count; - audio->buffer_size = config.buffer_size; - MM_DBG("AUDIO_SET_CONFIG\n"); - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config config; - config.buffer_count = audio->buffer_count; - config.buffer_size = audio->buffer_size; - config.sample_rate = audio->out_sample_rate; - if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) - config.channel_count = 1; - else - config.channel_count = 2; - if (audio->out_bits == AUDPP_CMD_WAV_PCM_WIDTH_8) - config.bits = 8; - else if (audio->out_bits == AUDPP_CMD_WAV_PCM_WIDTH_16) - config.bits = 16; - else - config.bits = 16; - config.unused[0] = 0; - config.unused[1] = 0; - - if (copy_to_user((void *) arg, &config, sizeof(config))) - rc = -EFAULT; - else - rc = 0; - MM_DBG("AUDIO_GET_CONFIG\n"); - break; - } - - - case AUDIO_PAUSE: - MM_DBG("AUDIO_PAUSE %ld\n", arg); - rc = audpp_pause(audio->dec_id, (int) arg); - break; - - case AUDIO_REGISTER_ION: { - struct msm_audio_ion_info info; - MM_ERR("AUDIO_REGISTER_ION\n"); - if (copy_from_user(&info, (void *) arg, sizeof(info))) - rc = -EFAULT; - else - rc = audlpa_ion_add(audio, &info); - break; - } - - case AUDIO_DEREGISTER_ION: { - struct msm_audio_ion_info info; - MM_ERR("AUDIO_DEREGISTER_ION\n"); - if (copy_from_user(&info, (void *) arg, sizeof(info))) - rc = -EFAULT; - else - rc = audlpa_ion_remove(audio, &info); - break; - } - - case AUDIO_ASYNC_WRITE: - if (audio->drv_status & ADRV_STATUS_FSYNC) - rc = -EBUSY; - else - rc = audlpa_aio_buf_add(audio, 1, (void __user *) arg); - break; - - case AUDIO_ASYNC_READ: - MM_ERR("AUDIO_ASYNC_READ not supported\n"); - rc = -EPERM; - break; - - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -int audlpa_async_fsync(struct audio *audio) -{ - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - /* Blocking client sends more data */ - mutex_lock(&audio->lock); - audio->drv_status |= ADRV_STATUS_FSYNC; - mutex_unlock(&audio->lock); - - mutex_lock(&audio->write_lock); - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - (audio->teos && audio->out_needed && - list_empty(&audio->out_queue)) - || audio->wflush || audio->stopped); - - if (audio->stopped || audio->wflush) - rc = -EBUSY; - - mutex_unlock(&audio->write_lock); - mutex_lock(&audio->lock); - audio->drv_status &= ~ADRV_STATUS_FSYNC; - mutex_unlock(&audio->lock); - - return rc; -} - -int audlpa_sync_fsync(struct audio *audio) -{ - struct buffer *frame; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (audio->reserved) { - MM_DBG("send reserved byte\n"); - frame = audio->out + audio->out_tail; - ((char *) frame->data)[0] = audio->rsv_byte; - ((char *) frame->data)[1] = 0; - frame->used = 2; - audpcm_async_send_data(audio, 0); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - } - - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush); - - if (audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); - return rc; -} - -int audlpa_fsync(struct file *file, loff_t a, loff_t b, - int datasync) -{ - struct audio *audio = file->private_data; - - if (!audio->running) - return -EINVAL; - - return audlpa_async_fsync(audio); -} - -static void audpcm_reset_ion_region(struct audio *audio) -{ - struct audlpa_ion_region *region; - struct list_head *ptr, *next; - - list_for_each_safe(ptr, next, &audio->ion_region_queue) { - region = list_entry(ptr, struct audlpa_ion_region, list); - list_del(®ion->list); - ion_unmap_kernel(audio->client, region->handle); - ion_free(audio->client, region->handle); - kfree(region); - } - - return; -} -static int audio_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_DBG("audio instance 0x%08x freeing\n", (int)audio); - mutex_lock(&audio->lock); - audio_disable(audio); - if (audio->rmt_resource_released == 0) - rmt_put_resource(audio); - audpcm_async_flush(audio); - audpcm_reset_ion_region(audio); - - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->opened = 0; - audio->event_abort = 1; - wake_up(&audio->event_wait); - audpcm_reset_event_queue(audio); - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - ion_client_destroy(audio->client); - kfree(audio); - return 0; -} - -static void audpcm_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audpcm_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audpcm_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audpcm_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audpcm_suspend(struct early_suspend *h) -{ - struct audpcm_suspend_ctl *ctl = - container_of(h, struct audpcm_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audpcm_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audpcm_resume(struct early_suspend *h) -{ - struct audpcm_suspend_ctl *ctl = - container_of(h, struct audpcm_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audpcm_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audpcm_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audpcm_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 4096; - static char buffer[4096]; - int n = 0; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_buf_sz %d\n", audio->out[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %lx\n", audio->volume); - n += scnprintf(buffer + n, debug_bufmax - n, - "sample rate %d\n", audio->out_sample_rate); - n += scnprintf(buffer + n, debug_bufmax - n, - "channel mode %d\n", audio->out_channel_mode); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d\n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d\n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d\n", audio->out_needed); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_head %d\n", audio->out_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_tail %d\n", audio->out_tail); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[0].used %d\n", audio->out[0].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[1].used %d\n", audio->out[1].used); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audpcm_debug_fops = { - .read = audpcm_debug_read, - .open = audpcm_debug_open, -}; -#endif - -static int audio_open(struct inode *inode, struct file *file) -{ - struct audio *audio = NULL; - int rc, i, dec_attrb, decid; - struct audpcm_event *e_node = NULL; - -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_lpa_" + 5]; -#endif - - /* Allocate audio instance, set to zero */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("no memory to allocate audio instance\n"); - rc = -ENOMEM; - goto done; - } - MM_DBG("audio instance 0x%08x created\n", (int)audio); - - /* Allocate the decoder */ - dec_attrb = AUDDEC_DEC_PCM; - if (file->f_mode & FMODE_READ) { - MM_ERR("Non-Tunneled mode not supported\n"); - rc = -EPERM; - kfree(audio); - goto done; - } else - dec_attrb |= MSM_AUD_MODE_TUNNEL; - - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - if (decid < 0) { - MM_ERR("No free decoder available\n"); - rc = -ENODEV; - MM_DBG("audio instance 0x%08x freeing\n", (int)audio); - kfree(audio); - goto done; - } - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - audio->buffer_size = BUFSZ; - audio->buffer_count = MAX_BUF; - rc = audmgr_open(&audio->audmgr); - if (rc) - goto err; - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audlpadec_adsp_ops, audio); - if (rc) { - MM_ERR("failed to get %s module\n", audio->module_name); - audmgr_close(&audio->audmgr); - goto err; - } - - rc = rmt_get_resource(audio); - if (rc) { - MM_ERR("ADSP resources are not available for PCM session"); - audmgr_close(&audio->audmgr); - msm_adsp_put(audio->audplay); - goto err; - } - - /* Initialize all locks of audio instance */ - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - init_waitqueue_head(&audio->write_wait); - INIT_LIST_HEAD(&audio->out_queue); - INIT_LIST_HEAD(&audio->ion_region_queue); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - spin_lock_init(&audio->event_queue_lock); - - audio->out_sample_rate = 44100; - audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V; - audio->out_bits = AUDPP_CMD_WAV_PCM_WIDTH_16; - audio->volume = 0x2000; - audpcm_async_flush(audio); - - file->private_data = audio; - audio->opened = 1; - -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_pcm_lp_dec_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, &audpcm_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audpcm_resume; - audio->suspend_ctl.node.suspend = audpcm_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (i = 0; i < AUDPCM_EVENT_NUM; i++) { - e_node = kmalloc(sizeof(struct audpcm_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } - - audio->client = msm_ion_client_create(UINT_MAX, "Audio_LPA_Client"); - if (IS_ERR_OR_NULL(audio->client)) { - pr_err("Unable to create ION client\n"); - goto err; - } - MM_DBG("Ion client created\n"); - -done: - return rc; -err: - audpp_adec_free(audio->dec_id); - MM_DBG("audio instance 0x%08x freeing\n", (int)audio); - kfree(audio); - return rc; -} - -static const struct file_operations audio_pcm_lp_fops = { - .owner = THIS_MODULE, - .open = audio_open, - .release = audio_release, - .unlocked_ioctl = audio_ioctl, - .fsync = audlpa_fsync, -}; - -struct miscdevice audio_lpa_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_pcm_lp_dec", - .fops = &audio_pcm_lp_fops, -}; - -static int __init audio_init(void) -{ - return misc_register(&audio_lpa_misc); -} - -device_initcall(audio_init); diff --git a/arch/arm/mach-msm/qdsp5/audio_mp3.c b/arch/arm/mach-msm/qdsp5/audio_mp3.c deleted file mode 100644 index 62524ff06ba736fb1c1e2dd142c39cc853a8aae9..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_mp3.c +++ /dev/null @@ -1,2456 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/audio_mp3.c - * - * mp3 audio output device - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "audmgr.h" - -#define ADRV_STATUS_AIO_INTF 0x00000001 -#define ADRV_STATUS_OBUF_GIVEN 0x00000002 -#define ADRV_STATUS_IBUF_GIVEN 0x00000004 -#define ADRV_STATUS_FSYNC 0x00000008 - -/* Size must be power of 2 */ -#define BUFSZ_MAX 32768 -#define BUFSZ_MIN 4096 -#define DMASZ_MAX (BUFSZ_MAX * 2) -#define DMASZ_MIN (BUFSZ_MIN * 2) - -#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF -#define AUDDEC_DEC_MP3 2 - -#define PCM_BUFSZ_MIN 4800 /* Hold one stereo MP3 frame */ -#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most - but support 2 buffers currently */ -#define ROUTING_MODE_FTRT 1 -#define ROUTING_MODE_RT 2 -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDMP3_METAFIELD_MASK 0xFFFF0000 -#define AUDMP3_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */ -#define AUDMP3_EOS_FLG_MASK 0x01 -#define AUDMP3_EOS_NONE 0x0 /* No EOS detected */ -#define AUDMP3_EOS_SET 0x1 /* EOS set in meta field */ - -#define AUDMP3_EVENT_NUM 10 /* Default number of pre-allocated event packets */ - -#define __CONTAINS(r, v, l) ({ \ - typeof(r) __r = r; \ - typeof(v) __v = v; \ - typeof(v) __e = __v + l; \ - int res = ((__v >= __r->vaddr) && \ - (__e <= __r->vaddr + __r->len)); \ - res; \ -}) - -#define CONTAINS(r1, r2) ({ \ - typeof(r2) __r2 = r2; \ - __CONTAINS(r1, __r2->vaddr, __r2->len); \ -}) - -#define IN_RANGE(r, v) ({ \ - typeof(r) __r = r; \ - typeof(v) __vv = v; \ - int res = ((__vv >= __r->vaddr) && \ - (__vv < (__r->vaddr + __r->len))); \ - res; \ -}) - -#define OVERLAPS(r1, r2) ({ \ - typeof(r1) __r1 = r1; \ - typeof(r2) __r2 = r2; \ - typeof(__r2->vaddr) __v = __r2->vaddr; \ - typeof(__v) __e = __v + __r2->len - 1; \ - int res = (IN_RANGE(__r1, __v) || IN_RANGE(__r1, __e)); \ - res; \ -}) - -struct audio; - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; - unsigned short mfield_sz; /*only useful for data has meta field */ -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audmp3_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct audmp3_event { - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audmp3_ion_region { - struct list_head list; - struct ion_handle *handle; - int fd; - void *vaddr; - unsigned long paddr; - unsigned long kvaddr; - unsigned long len; - unsigned ref_cnt; -}; - -struct audmp3_buffer_node { - struct list_head list; - struct msm_audio_aio_buf buf; - unsigned long paddr; -}; - -struct audmp3_drv_operations { - void (*pcm_buf_update)(struct audio *, uint32_t *); - void (*buffer_refresh)(struct audio *); - void (*send_data)(struct audio *, unsigned); - void (*out_flush)(struct audio *); - void (*in_flush)(struct audio *); - int (*fsync)(struct audio *); -}; - -struct audio { - struct buffer out[2]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - unsigned out_dma_sz; - struct list_head out_queue; /* queue to retain output buffers */ - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - /* Host PCM section */ - struct buffer in[PCM_BUF_MAX_COUNT]; - struct mutex read_lock; - wait_queue_head_t read_wait; /* Wait queue for read */ - char *read_data; /* pointer to reader buffer */ - int32_t read_phys; /* physical address of reader buffer */ - uint8_t read_next; /* index to input buffers to be read next */ - uint8_t fill_next; /* index to buffer that DSP should be filling */ - uint8_t pcm_buf_count; /* number of pcm buffer allocated */ - struct list_head in_queue; /* queue to retain input buffers */ - /* ---- End of Host PCM section */ - - struct msm_adsp_module *audplay; - - /* configuration to use on next enable */ - uint32_t out_sample_rate; - uint32_t out_channel_mode; - - struct audmgr audmgr; - - /* data allocated for various buffers */ - char *data; - int32_t phys; /* physical address of write buffer */ - void *map_v_read; - void *map_v_write; - - uint32_t drv_status; - int mfield; /* meta field embedded in data */ - int rflush; /* Read flush */ - int wflush; /* Write flush */ - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - int pcm_feedback; - int buf_refresh; - int rmt_resource_released; - int teos; /* valid only if tunnel mode & no data left for decoder */ - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - int reserved; /* A byte is being reserved */ - char rsv_byte; /* Handle odd length user data */ - - const char *module_name; - unsigned queue_id; - uint16_t dec_id; - uint32_t read_ptr_offset; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audmp3_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - - struct list_head ion_region_queue; /* protected by lock */ - struct audmp3_drv_operations drv_ops; - - int eq_enable; - int eq_needs_commit; - audpp_cmd_cfg_object_params_eqalizer eq; - audpp_cmd_cfg_object_params_volume vol_pan; - struct ion_client *client; - struct ion_handle *input_buff_handle; - struct ion_handle *output_buff_handle; -}; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audpp_cmd_cfg_adec_params(struct audio *audio); -static void audpp_cmd_cfg_routing_mode(struct audio *audio); -static void audplay_send_data(struct audio *audio, unsigned needed); -static void audplay_config_hostpcm(struct audio *audio); -static void audplay_buffer_refresh(struct audio *audio); -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg); -static void audmp3_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); -static unsigned long audmp3_ion_fixup(struct audio *audio, void *addr, - unsigned long len, int ref_up); - -static int rmt_put_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_DISABLE; - cmd.dec_type = AUDDEC_DEC_MP3; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - - return put_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -static int rmt_get_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_ENABLE; - cmd.dec_type = AUDDEC_DEC_MP3; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - - return get_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -/* must be called with audio->lock held */ -static int audio_enable(struct audio *audio) -{ - struct audmgr_config cfg; - int rc; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (audio->enabled) - return 0; - - if (audio->rmt_resource_released == 1) { - audio->rmt_resource_released = 0; - rc = rmt_get_resource(audio); - if (rc) { - MM_ERR("ADSP resources are not available for MP3 \ - session 0x%08x on decoder: %d\n Ignoring \ - error and going ahead with the playback\n", - (int)audio, audio->dec_id); - } - } - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_tail = 0; - audio->out_needed = 0; - - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) { - cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; - cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000; - cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK; - cfg.codec = RPC_AUD_DEF_CODEC_MP3; - cfg.snd_method = RPC_SND_METHOD_MIDI; - - rc = audmgr_enable(&audio->audmgr, &cfg); - if (rc < 0) - return rc; - } - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - - audio->enabled = 1; - return 0; -} - -/* must be called with audio->lock held */ -static int audio_disable(struct audio *audio) -{ - int rc = 0; - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - audio->stopped = 1; - wake_up(&audio->write_wait); - wake_up(&audio->read_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - audio->out_needed = 0; - rmt_put_resource(audio); - audio->rmt_resource_released = 1; - } - return rc; -} - -/* ------------------- dsp --------------------- */ -static void audmp3_async_pcm_buf_update(struct audio *audio, uint32_t *payload) -{ - unsigned long flags; - union msm_audio_event_payload event_payload; - struct audmp3_buffer_node *filled_buf; - uint8_t index; - - if (audio->rflush) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < payload[1]; index++) { - BUG_ON(list_empty(&audio->in_queue)); - filled_buf = list_first_entry(&audio->in_queue, - struct audmp3_buffer_node, list); - if (filled_buf->paddr == payload[2 + index * 2]) { - list_del(&filled_buf->list); - event_payload.aio_buf = filled_buf->buf; - event_payload.aio_buf.data_len = - payload[3 + index * 2]; - MM_DBG("pcm buf %p data_len %d\n", filled_buf, - event_payload.aio_buf.data_len); - audmp3_post_event(audio, AUDIO_EVENT_READ_DONE, - event_payload); - kfree(filled_buf); - } else { - MM_ERR("expected=%lx ret=%x\n", filled_buf->paddr, - payload[2 + index * 2]); - break; - } - } - - audio->drv_status &= ~ADRV_STATUS_IBUF_GIVEN; - audio->drv_ops.buffer_refresh(audio); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - -} - -static void audio_update_pcm_buf_entry(struct audio *audio, uint32_t *payload) -{ - uint8_t index; - unsigned long flags; - - if (audio->rflush) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < payload[1]; index++) { - if (audio->in[audio->fill_next].addr == - payload[2 + index * 2]) { - MM_DBG("in[%d] ready\n", audio->fill_next); - audio->in[audio->fill_next].used = - payload[3 + index * 2]; - if ((++audio->fill_next) == audio->pcm_buf_count) - audio->fill_next = 0; - - } else { - MM_ERR("expected=%x ret=%x\n", - audio->in[audio->fill_next].addr, - payload[2 + index * 2]); - break; - } - } - if (audio->in[audio->fill_next].used == 0) { - audio->drv_ops.buffer_refresh(audio); - } else { - MM_DBG("read cannot keep up\n"); - audio->buf_refresh = 1; - } - wake_up(&audio->read_wait); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - -} - -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - getevent(msg, sizeof(msg)); - - MM_DBG("msg_id=%x\n", id); - - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audio->drv_ops.send_data(audio, 1); - break; - - case AUDPLAY_MSG_BUFFER_UPDATE: - audio->drv_ops.pcm_buf_update(audio, msg); - break; - - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audplaytask)\n"); - break; - - default: - MM_ERR("unexpected message from decoder \n"); - break; - } -} - -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status: sleep reason=0x%04x\n", - reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init \n"); - if (audio->pcm_feedback) - audpp_cmd_cfg_routing_mode(audio); - else - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg \n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play \n"); - if (audio->pcm_feedback) { - audplay_config_hostpcm(audio); - audio->drv_ops.buffer_refresh(audio); - } - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - default: - MM_ERR("unknown decoder status \n"); - break; - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - audpp_dsp_set_eq(audio->dec_id, audio->eq_enable, - &audio->eq); - audpp_avsync(audio->dec_id, 22050); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audpp_avsync(audio->dec_id, 0); - audio->running = 0; - } else { - MM_DBG("CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_ROUTING_ACK: - MM_DBG("ROUTING_ACK mode=%d\n", msg[1]); - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - audio->rflush = 0; - wake_up(&audio->write_wait); - if (audio->pcm_feedback) - audio->drv_ops.buffer_refresh(audio); - break; - - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - - default: - MM_ERR("UNKNOWN (%d)\n", id); - } - -} - - -struct msm_adsp_ops audplay_adsp_ops = { - .event = audplay_dsp_event, -}; - - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id, \ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - u16 cfg_dec_cmd[AUDPP_CMD_CFG_DEC_TYPE_LEN / sizeof(unsigned short)]; - - memset(cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - - cfg_dec_cmd[0] = AUDPP_CMD_CFG_DEC_TYPE; - if (enable) - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_MP3; - else - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} - -static void audpp_cmd_cfg_adec_params(struct audio *audio) -{ - audpp_cmd_cfg_adec_params_mp3 cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_MP3_LEN; - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = audio->out_sample_rate; - - audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static void audpp_cmd_cfg_routing_mode(struct audio *audio) -{ - struct audpp_cmd_routing_mode cmd; - MM_DBG("\n"); /* Macro prints the file name and function */ - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; - cmd.object_number = audio->dec_id; - if (audio->pcm_feedback) - cmd.routing_mode = ROUTING_MODE_FTRT; - else - cmd.routing_mode = ROUTING_MODE_RT; - - audpp_send_queue1(&cmd, sizeof(cmd)); -} - -static int audplay_dsp_send_data_avail(struct audio *audio, - unsigned idx, unsigned len) -{ - struct audplay_cmd_bitstream_data_avail_nt2 cmd; - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2; - if (audio->mfield) - cmd.decoder_id = AUDMP3_METAFIELD_MASK | - (audio->out[idx].mfield_sz >> 1); - else - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = audio->out[idx].addr; - cmd.buf_size = len/2; - cmd.partition_number = 0; - /* complete all the writes to the input buffer */ - wmb(); - return audplay_send_queue0(audio, &cmd, sizeof(cmd)); -} - -/* Caller holds irq_lock */ -static void audmp3_async_buffer_refresh(struct audio *audio) -{ - struct audplay_cmd_buffer_refresh refresh_cmd; - struct audmp3_buffer_node *next_buf; - - if (!audio->running || - audio->drv_status & ADRV_STATUS_IBUF_GIVEN) - return; - - if (!list_empty(&audio->in_queue)) { - next_buf = list_first_entry(&audio->in_queue, - struct audmp3_buffer_node, list); - if (!next_buf) - return; - MM_DBG("next buf %p phy %lx len %d\n", next_buf, - next_buf->paddr, next_buf->buf.buf_len); - refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; - refresh_cmd.num_buffers = 1; - refresh_cmd.buf0_address = next_buf->paddr; - refresh_cmd.buf0_length = next_buf->buf.buf_len - - (next_buf->buf.buf_len % 576) + - (audio->mfield ? 24 : 0); /* Mp3 frame size */ - refresh_cmd.buf_read_count = 0; - audio->drv_status |= ADRV_STATUS_IBUF_GIVEN; - (void) audplay_send_queue0(audio, &refresh_cmd, - sizeof(refresh_cmd)); - } - -} - -static void audplay_buffer_refresh(struct audio *audio) -{ - struct audplay_cmd_buffer_refresh refresh_cmd; - - refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; - refresh_cmd.num_buffers = 1; - refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; - refresh_cmd.buf0_length = audio->in[audio->fill_next].size - - (audio->in[audio->fill_next].size % 576) + - (audio->mfield ? 24 : 0); /* Mp3 frame size */ - refresh_cmd.buf_read_count = 0; - MM_DBG("buf0_addr=%x buf0_len=%d\n", refresh_cmd.buf0_address, - refresh_cmd.buf0_length); - (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); -} - -static void audplay_config_hostpcm(struct audio *audio) -{ - struct audplay_cmd_hpcm_buf_cfg cfg_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; - cfg_cmd.max_buffers = 1; - cfg_cmd.byte_swap = 0; - cfg_cmd.hostpcm_config = (0x8000) | (0x4000); - cfg_cmd.feedback_frequency = 1; - cfg_cmd.partition_number = 0; - (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); - -} - -static void audmp3_async_send_data(struct audio *audio, unsigned needed) -{ - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - audio->out_needed = 1; - if (audio->drv_status & ADRV_STATUS_OBUF_GIVEN) { - /* pop one node out of queue */ - union msm_audio_event_payload payload; - struct audmp3_buffer_node *used_buf; - - MM_DBG("consumed\n"); - BUG_ON(list_empty(&audio->out_queue)); - used_buf = list_first_entry(&audio->out_queue, - struct audmp3_buffer_node, list); - list_del(&used_buf->list); - payload.aio_buf = used_buf->buf; - audmp3_post_event(audio, AUDIO_EVENT_WRITE_DONE, - payload); - kfree(used_buf); - audio->drv_status &= ~ADRV_STATUS_OBUF_GIVEN; - } - - } - - if (audio->out_needed) { - struct audmp3_buffer_node *next_buf; - struct audplay_cmd_bitstream_data_avail_nt2 cmd; - if (!list_empty(&audio->out_queue)) { - next_buf = list_first_entry(&audio->out_queue, - struct audmp3_buffer_node, list); - MM_DBG("next_buf %p\n", next_buf); - if (next_buf) { - MM_DBG("next buf phy %lx len %d\n", - next_buf->paddr, - next_buf->buf.data_len); - - cmd.cmd_id = - AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2; - if (audio->mfield) - cmd.decoder_id = AUDMP3_METAFIELD_MASK | - (next_buf->buf.mfield_sz >> 1); - else - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = (unsigned) next_buf->paddr; - cmd.buf_size = next_buf->buf.data_len >> 1; - cmd.partition_number = 0; - /* complete the writes to the input buffer */ - wmb(); - audplay_send_queue0(audio, &cmd, sizeof(cmd)); - audio->out_needed = 0; - audio->drv_status |= ADRV_STATUS_OBUF_GIVEN; - } - } - } - -done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audplay_send_data(struct audio *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - MM_DBG("frame %d busy\n", audio->out_tail); - audplay_dsp_send_data_avail(audio, audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } -done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ -static void audmp3_async_flush(struct audio *audio) -{ - struct audmp3_buffer_node *buf_node; - struct list_head *ptr, *next; - union msm_audio_event_payload payload; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - MM_DBG("\n"); /* Macro prints the file name and function */ - list_for_each_safe(ptr, next, &audio->out_queue) { - buf_node = list_entry(ptr, struct audmp3_buffer_node, list); - list_del(&buf_node->list); - payload.aio_buf = buf_node->buf; - audmp3_post_event(audio, AUDIO_EVENT_WRITE_DONE, - payload); - kfree(buf_node); - } - audio->drv_status &= ~ADRV_STATUS_OBUF_GIVEN; - audio->out_needed = 0; - atomic_set(&audio->out_bytes, 0); - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audio_flush(struct audio *audio) -{ - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->reserved = 0; - audio->out_needed = 0; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - atomic_set(&audio->out_bytes, 0); -} - -static void audmp3_async_flush_pcm_buf(struct audio *audio) -{ - struct audmp3_buffer_node *buf_node; - struct list_head *ptr, *next; - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - list_for_each_safe(ptr, next, &audio->in_queue) { - buf_node = list_entry(ptr, struct audmp3_buffer_node, list); - list_del(&buf_node->list); - payload.aio_buf = buf_node->buf; - payload.aio_buf.data_len = 0; - audmp3_post_event(audio, AUDIO_EVENT_READ_DONE, - payload); - kfree(buf_node); - } - audio->drv_status &= ~ADRV_STATUS_IBUF_GIVEN; - -} - -static void audio_flush_pcm_buf(struct audio *audio) -{ - uint8_t index; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < PCM_BUF_MAX_COUNT; index++) - audio->in[index].used = 0; - audio->buf_refresh = 0; - audio->read_next = 0; - audio->fill_next = 0; - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audio_ioport_reset(struct audio *audio) -{ - if (audio->drv_status & ADRV_STATUS_AIO_INTF) { - /* If fsync is in progress, make sure - * return value of fsync indicates - * abort due to flush - */ - if (audio->drv_status & ADRV_STATUS_FSYNC) { - MM_DBG("fsync in progress\n"); - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audio->drv_ops.out_flush(audio); - mutex_unlock(&audio->write_lock); - } else - audio->drv_ops.out_flush(audio); - audio->drv_ops.in_flush(audio); - } else { - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audio->drv_ops.out_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->read_wait); - mutex_lock(&audio->read_lock); - audio->drv_ops.in_flush(audio); - mutex_unlock(&audio->read_lock); - } -} - -static int audmp3_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audmp3_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audmp3_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audmp3_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audmp3_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - -static long audmp3_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audmp3_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - audio->event_wait, audmp3_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audmp3_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - rc = 0; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audmp3_event, list); - list_del(&drv_evt->list); - } - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - if (drv_evt->event_type == AUDIO_EVENT_WRITE_DONE || - drv_evt->event_type == AUDIO_EVENT_READ_DONE) { - mutex_lock(&audio->lock); - audmp3_ion_fixup(audio, drv_evt->payload.aio_buf.buf_addr, - drv_evt->payload.aio_buf.buf_len, 0); - mutex_unlock(&audio->lock); - } - - /* order reads from the output buffer */ - if (drv_evt->event_type == AUDIO_EVENT_READ_DONE) - rmb(); - - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audmp3_ion_check(struct audio *audio, - void *vaddr, unsigned long len) -{ - struct audmp3_ion_region *region_elt; - struct audmp3_ion_region t = { .vaddr = vaddr, .len = len }; - - list_for_each_entry(region_elt, &audio->ion_region_queue, list) { - if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) || - OVERLAPS(region_elt, &t)) { - MM_ERR("region (vaddr %p len %ld)" - " clashes with registered region" - " (vaddr %p paddr %p len %ld)\n", - vaddr, len, - region_elt->vaddr, - (void *)region_elt->paddr, - region_elt->len); - return -EINVAL; - } - } - - return 0; -} - -static int audmp3_ion_add(struct audio *audio, - struct msm_audio_ion_info *info) -{ - ion_phys_addr_t paddr; - size_t len; - unsigned long kvaddr; - struct audmp3_ion_region *region; - int rc = -EINVAL; - struct ion_handle *handle; - unsigned long ionflag; - void *temp_ptr; - - MM_DBG("\n"); /* Macro prints the file name and function */ - region = kmalloc(sizeof(*region), GFP_KERNEL); - - if (!region) { - rc = -ENOMEM; - goto end; - } - - handle = ion_import_dma_buf(audio->client, info->fd); - if (IS_ERR_OR_NULL(handle)) { - pr_err("%s: could not get handle of the given fd\n", __func__); - goto import_error; - } - - rc = ion_handle_get_flags(audio->client, handle, &ionflag); - if (rc) { - pr_err("%s: could not get flags for the handle\n", __func__); - goto flag_error; - } - - temp_ptr = ion_map_kernel(audio->client, handle); - if (IS_ERR_OR_NULL(temp_ptr)) { - pr_err("%s: could not get virtual address\n", __func__); - goto map_error; - } - kvaddr = (unsigned long) temp_ptr; - - rc = ion_phys(audio->client, handle, &paddr, &len); - if (rc) { - pr_err("%s: could not get physical address\n", __func__); - goto ion_error; - } - - rc = audmp3_ion_check(audio, info->vaddr, len); - if (rc < 0) { - MM_ERR("audpcm_ion_check failed\n"); - goto ion_error; - } - - region->handle = handle; - region->vaddr = info->vaddr; - region->fd = info->fd; - region->paddr = paddr; - region->kvaddr = kvaddr; - region->len = len; - region->ref_cnt = 0; - MM_DBG("[%p]:add region paddr %lx vaddr %p, len %lu kvaddr %lx\n", - audio, region->paddr, region->vaddr, - region->len, region->kvaddr); - list_add_tail(®ion->list, &audio->ion_region_queue); - return rc; - -ion_error: - ion_unmap_kernel(audio->client, handle); -map_error: -flag_error: - ion_free(audio->client, handle); -import_error: - kfree(region); -end: - return rc; -} - -static int audmp3_ion_remove(struct audio *audio, - struct msm_audio_ion_info *info) -{ - struct audmp3_ion_region *region; - struct list_head *ptr, *next; - int rc = -EINVAL; - - list_for_each_safe(ptr, next, &audio->ion_region_queue) { - region = list_entry(ptr, struct audmp3_ion_region, list); - - if (region != NULL && (region->fd == info->fd) && - (region->vaddr == info->vaddr)) { - if (region->ref_cnt) { - MM_DBG("%s[%p]:region %p in use ref_cnt %d\n", - __func__, audio, region, - region->ref_cnt); - break; - } - MM_DBG("remove region fd %d vaddr %p\n", - info->fd, info->vaddr); - list_del(®ion->list); - ion_unmap_kernel(audio->client, region->handle); - ion_free(audio->client, region->handle); - kfree(region); - rc = 0; - break; - } - } - - return rc; -} - -static int audmp3_ion_lookup_vaddr(struct audio *audio, void *addr, - unsigned long len, struct audmp3_ion_region **region) -{ - struct audmp3_ion_region *region_elt; - int match_count = 0; - *region = NULL; - - /* returns physical address or zero */ - list_for_each_entry(region_elt, &audio->ion_region_queue, list) { - if (addr >= region_elt->vaddr && - addr < region_elt->vaddr + region_elt->len && - addr + len <= region_elt->vaddr + region_elt->len) { - /* offset since we could pass vaddr inside a registerd - * ion buffer - */ - - match_count++; - if (!*region) - *region = region_elt; - } - } - - if (match_count > 1) { - MM_ERR("%s[%p]:multiple hits for vaddr %p, len %ld\n", - __func__, audio, addr, len); - list_for_each_entry(region_elt, &audio->ion_region_queue, - list) { - if (addr >= region_elt->vaddr && - addr < region_elt->vaddr + region_elt->len && - addr + len <= region_elt->vaddr + region_elt->len) - MM_ERR("\t%s[%p]:%p, %ld --> %p\n", - __func__, audio, - region_elt->vaddr, - region_elt->len, - (void *)region_elt->paddr); - } - } - return *region ? 0 : -1; -} - -unsigned long audmp3_ion_fixup(struct audio *audio, void *addr, - unsigned long len, int ref_up) -{ - struct audmp3_ion_region *region; - unsigned long paddr; - int ret; - - ret = audmp3_ion_lookup_vaddr(audio, addr, len, ®ion); - if (ret) { - MM_ERR("lookup (%p, %ld) failed\n", addr, len); - return 0; - } - if (ref_up) - region->ref_cnt++; - else - region->ref_cnt--; - MM_DBG("found region %p ref_cnt %d\n", region, region->ref_cnt); - paddr = region->paddr + (addr - region->vaddr); - return paddr; -} - -/* audio -> lock must be held at this point */ -static int audmp3_aio_buf_add(struct audio *audio, unsigned dir, - void __user *arg) -{ - unsigned long flags; - struct audmp3_buffer_node *buf_node; - - buf_node = kmalloc(sizeof(*buf_node), GFP_KERNEL); - - if (!buf_node) - return -ENOMEM; - - if (copy_from_user(&buf_node->buf, arg, sizeof(buf_node->buf))) { - kfree(buf_node); - return -EFAULT; - } - - MM_DBG("node %p dir %x buf_addr %p buf_len %d data_len \ - %d\n", buf_node, dir, - buf_node->buf.buf_addr, buf_node->buf.buf_len, - buf_node->buf.data_len); - - buf_node->paddr = audmp3_ion_fixup( - audio, buf_node->buf.buf_addr, - buf_node->buf.buf_len, 1); - - if (dir) { - /* write */ - if (!buf_node->paddr || - (buf_node->paddr & 0x1) || - (buf_node->buf.data_len & 0x1) || - (!audio->pcm_feedback && - !buf_node->buf.data_len)) { - kfree(buf_node); - return -EINVAL; - } - spin_lock_irqsave(&audio->dsp_lock, flags); - list_add_tail(&buf_node->list, &audio->out_queue); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - audio->drv_ops.send_data(audio, 0); - } else { - /* read */ - if (!buf_node->paddr || - (buf_node->paddr & 0x1) || - (buf_node->buf.buf_len < PCM_BUFSZ_MIN)) { - kfree(buf_node); - return -EINVAL; - } - spin_lock_irqsave(&audio->dsp_lock, flags); - list_add_tail(&buf_node->list, &audio->in_queue); - audio->drv_ops.buffer_refresh(audio); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - } - - MM_DBG("Add buf_node %p paddr %lx\n", buf_node, buf_node->paddr); - - return 0; -} - -static int audio_enable_eq(struct audio *audio, int enable) -{ - if (audio->eq_enable == enable && !audio->eq_needs_commit) - return 0; - - audio->eq_enable = enable; - - if (audio->running) { - audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq); - audio->eq_needs_commit = 0; - } - return 0; -} - -static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - unsigned long flags = 0; - uint16_t enable_mask; - int enable; - int prev_state; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - int len = 0; - - MM_DBG("cmd = %d\n", cmd); - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = audpp_avsync_byte_count(audio->dec_id); - stats.sample_count = audpp_avsync_sample_count(audio->dec_id); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - switch (cmd) { - case AUDIO_ENABLE_AUDPP: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - spin_lock_irqsave(&audio->dsp_lock, flags); - enable = (enable_mask & EQ_ENABLE) ? 1 : 0; - audio_enable_eq(audio, enable); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - case AUDIO_SET_VOLUME: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.volume = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_PAN: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.pan = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_EQ: - prev_state = audio->eq_enable; - audio->eq_enable = 0; - if (copy_from_user(&audio->eq.num_bands, (void *) arg, - sizeof(audio->eq) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) { - rc = -EFAULT; - break; - } - audio->eq_enable = prev_state; - audio->eq_needs_commit = 1; - rc = 0; - break; - } - - if (-EINVAL != rc) - return rc; - - if (cmd == AUDIO_GET_EVENT) { - MM_DBG(" AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audmp3_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audio_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) - rc = -ENODEV; - else - rc = 0; - } - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audio_disable(audio); - audio_ioport_reset(audio); - audio->stopped = 0; - break; - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audio_ioport_reset(audio); - if (audio->running) { - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - - case AUDIO_SET_CONFIG: { - struct msm_audio_config config; - if (copy_from_user(&config, (void *) arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.channel_count == 1) { - config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V; - } else if (config.channel_count == 2) { - config.channel_count = AUDPP_CMD_PCM_INTF_STEREO_V; - } else { - rc = -EINVAL; - break; - } - audio->mfield = config.meta_field; - audio->out_sample_rate = config.sample_rate; - audio->out_channel_mode = config.channel_count; - rc = 0; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config config; - config.buffer_size = (audio->out_dma_sz >> 1); - config.buffer_count = 2; - config.sample_rate = audio->out_sample_rate; - if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) { - config.channel_count = 1; - } else { - config.channel_count = 2; - } - config.meta_field = 0; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *) arg, &config, sizeof(config))) { - rc = -EFAULT; - } else { - rc = 0; - } - break; - } - case AUDIO_GET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - config.pcm_feedback = audio->pcm_feedback; - config.buffer_count = PCM_BUF_MAX_COUNT; - config.buffer_size = PCM_BUFSZ_MIN; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - - if (config.pcm_feedback != audio->pcm_feedback) { - MM_ERR("Not sufficient permission to" - "change the playback mode\n"); - rc = -EACCES; - break; - } - if (audio->drv_status & ADRV_STATUS_AIO_INTF) { - rc = 0; - break; - } - - if ((config.buffer_count > PCM_BUF_MAX_COUNT) || - (config.buffer_count == 1)) - config.buffer_count = PCM_BUF_MAX_COUNT; - - if (config.buffer_size < PCM_BUFSZ_MIN) - config.buffer_size = PCM_BUFSZ_MIN; - - /* Check if pcm feedback is required */ - if ((config.pcm_feedback) && (!audio->read_data)) { - MM_DBG("allocate PCM buffer %d\n", - config.buffer_count * - config.buffer_size); - - handle = ion_alloc(audio->client, - (config.buffer_size * - config.buffer_count), - SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to alloc I/P buffs\n"); - rc = -ENOMEM; - break; - } - - audio->input_buff_handle = handle; - - rc = ion_phys(audio->client , - handle, &addr, &len); - if (rc) { - MM_ERR("Invalid phy: %x sz: %x\n", - (unsigned int) addr, - (unsigned int) len); - rc = -ENOMEM; - break; - } else { - MM_INFO("Got valid phy: %x sz: %x\n", - (unsigned int) audio->read_phys, - (unsigned int) len); - } - audio->read_phys = (int32_t)addr; - - rc = ion_handle_get_flags(audio->client, - handle, &ionflag); - if (rc) { - MM_ERR("could not get flags\n"); - rc = -ENOMEM; - break; - } - - audio->map_v_read = ion_map_kernel( - audio->client, handle); - - if (IS_ERR(audio->map_v_read)) { - MM_ERR("map of read buf failed\n"); - rc = -ENOMEM; - ion_free(audio->client, handle); - } else { - uint8_t index; - uint32_t offset = 0; - audio->read_data = - audio->map_v_read; - audio->buf_refresh = 0; - audio->pcm_buf_count = - config.buffer_count; - audio->read_next = 0; - audio->fill_next = 0; - - for (index = 0; - index < config.buffer_count; - index++) { - audio->in[index].data = - audio->read_data + offset; - audio->in[index].addr = - audio->read_phys + offset; - audio->in[index].size = - config.buffer_size; - audio->in[index].used = 0; - offset += config.buffer_size; - } - rc = 0; - MM_DBG("read buf: phy addr \ - 0x%08x kernel addr 0x%08x\n", - audio->read_phys, - (int)audio->read_data); - } - } else { - rc = 0; - } - break; - } - case AUDIO_PAUSE: - MM_DBG("AUDIO_PAUSE %ld\n", arg); - rc = audpp_pause(audio->dec_id, (int) arg); - break; - - case AUDIO_REGISTER_ION: { - struct msm_audio_ion_info info; - MM_DBG("AUDIO_REGISTER_ION\n"); - if (copy_from_user(&info, (void *) arg, sizeof(info))) - rc = -EFAULT; - else - rc = audmp3_ion_add(audio, &info); - break; - } - - case AUDIO_DEREGISTER_ION: { - struct msm_audio_ion_info info; - MM_DBG("AUDIO_DEREGISTER_ION\n"); - if (copy_from_user(&info, (void *) arg, sizeof(info))) - rc = -EFAULT; - else - rc = audmp3_ion_remove(audio, &info); - break; - } - case AUDIO_ASYNC_WRITE: - if (audio->drv_status & ADRV_STATUS_FSYNC) - rc = -EBUSY; - else - rc = audmp3_aio_buf_add(audio, 1, (void __user *) arg); - break; - - case AUDIO_ASYNC_READ: - if (audio->pcm_feedback) - rc = audmp3_aio_buf_add(audio, 0, (void __user *) arg); - else - rc = -EPERM; - break; - - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -int audmp3_async_fsync(struct audio *audio) -{ - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - /* Blocking client sends more data */ - mutex_lock(&audio->lock); - audio->drv_status |= ADRV_STATUS_FSYNC; - mutex_unlock(&audio->lock); - - mutex_lock(&audio->write_lock); - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - (audio->teos && audio->out_needed && - list_empty(&audio->out_queue)) - || audio->wflush || audio->stopped); - - if (audio->stopped || audio->wflush) - rc = -EBUSY; - - mutex_unlock(&audio->write_lock); - mutex_lock(&audio->lock); - audio->drv_status &= ~ADRV_STATUS_FSYNC; - mutex_unlock(&audio->lock); - - return rc; -} - -int audmp3_sync_fsync(struct audio *audio) -{ - struct buffer *frame; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (audio->reserved) { - MM_DBG("send reserved byte\n"); - frame = audio->out + audio->out_tail; - ((char *) frame->data)[0] = audio->rsv_byte; - ((char *) frame->data)[1] = 0; - frame->used = 2; - audio->drv_ops.send_data(audio, 0); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - } - - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush); - - if (audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); - return rc; -} - -int audmp3_fsync(struct file *file, loff_t a, loff_t b, int datasync) -{ - struct audio *audio = file->private_data; - - if (!audio->running || audio->pcm_feedback) - return -EINVAL; - - return audio->drv_ops.fsync(audio); -} - -static ssize_t audio_read(struct file *file, char __user *buf, size_t count, - loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - int rc = 0; - - if (audio->drv_status & ADRV_STATUS_AIO_INTF) - return -EPERM; - else if (!audio->pcm_feedback) - return 0; /* PCM feedback disabled. Nothing to read */ - - mutex_lock(&audio->read_lock); - MM_DBG("%d \n", count); - while (count > 0) { - rc = wait_event_interruptible( - audio->read_wait, - (audio->in[audio->read_next]. - used > 0) || (audio->stopped) - || (audio->rflush)); - - if (rc < 0) - break; - - if (audio->stopped || audio->rflush) { - rc = -EBUSY; - break; - } - - if (count < audio->in[audio->read_next].used) { - /* Read must happen in frame boundary. Since - * driver does not know frame size, read count - * must be greater or equal - * to size of PCM samples - */ - MM_DBG("no partial frame done reading\n"); - break; - } else { - MM_DBG("read from in[%d]\n", audio->read_next); - /* order reads from the output buffer */ - rmb(); - if (copy_to_user - (buf, audio->in[audio->read_next].data, - audio->in[audio->read_next].used)) { - MM_ERR("invalid addr %x \n", (unsigned int)buf); - rc = -EFAULT; - break; - } - count -= audio->in[audio->read_next].used; - buf += audio->in[audio->read_next].used; - audio->in[audio->read_next].used = 0; - if ((++audio->read_next) == audio->pcm_buf_count) - audio->read_next = 0; - break; /* Force to exit while loop - * to prevent output thread - * sleep too long if data is - * not ready at this moment. - */ - } - } - - /* don't feed output buffer to HW decoder during flushing - * buffer refresh command will be sent once flush completes - * send buf refresh command here can confuse HW decoder - */ - if (audio->buf_refresh && !audio->rflush) { - audio->buf_refresh = 0; - MM_DBG("kick start pcm feedback again\n"); - audio->drv_ops.buffer_refresh(audio); - } - - mutex_unlock(&audio->read_lock); - - if (buf > start) - rc = buf - start; - - MM_DBG("read %d bytes\n", rc); - return rc; -} - -static int audmp3_process_eos(struct audio *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - int rc = 0; - struct buffer *frame; - char *buf_ptr; - - if (audio->reserved) { - MM_DBG("flush reserve byte\n"); - frame = audio->out + audio->out_head; - buf_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - buf_ptr[0] = audio->rsv_byte; - buf_ptr[1] = 0; - audio->out_head ^= 1; - frame->mfield_sz = 0; - frame->used = 2; - audio->reserved = 0; - audio->drv_ops.send_data(audio, 0); - } - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - audio->drv_ops.send_data(audio, 0); -done: - return rc; -} - -static ssize_t audio_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - char *cpy_ptr; - int rc = 0, eos_condition = AUDMP3_EOS_NONE; - unsigned dsize; - unsigned short mfield_size = 0; - - if (audio->drv_status & ADRV_STATUS_AIO_INTF) - return -EPERM; - - MM_DBG("cnt=%d\n", count); - - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - cpy_ptr = frame->data; - dsize = 0; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - break; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - break; - } - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - break; - } else if (mfield_size > count) { - rc = -EINVAL; - break; - } - MM_DBG("mf offset_val %x\n", mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - break; - } - /* Check if EOS flag is set and buffer has - * contains just meta field - */ - if (cpy_ptr[AUDMP3_EOS_FLG_OFFSET] & - AUDMP3_EOS_FLG_MASK) { - MM_DBG("EOS SET\n"); - eos_condition = AUDMP3_EOS_SET; - if (mfield_size == count) { - buf += mfield_size; - break; - } else - cpy_ptr[AUDMP3_EOS_FLG_OFFSET] - &= ~AUDMP3_EOS_FLG_MASK; - } - cpy_ptr += mfield_size; - count -= mfield_size; - dsize += mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - - if (audio->reserved) { - MM_DBG("append reserved byte %x\n", audio->rsv_byte); - *cpy_ptr = audio->rsv_byte; - xfer = (count > ((frame->size - mfield_size) - 1)) ? - (frame->size - mfield_size) - 1 : count; - cpy_ptr++; - dsize += 1; - audio->reserved = 0; - } else - xfer = (count > (frame->size - mfield_size)) ? - (frame->size - mfield_size) : count; - - if (copy_from_user(cpy_ptr, buf, xfer)) { - rc = -EFAULT; - break; - } - - dsize += xfer; - if (dsize & 1) { - audio->rsv_byte = ((char *) frame->data)[dsize - 1]; - MM_DBG("odd length buf reserve last byte %x\n", - audio->rsv_byte); - audio->reserved = 1; - dsize--; - } - count -= xfer; - buf += xfer; - - if (dsize > 0) { - audio->out_head ^= 1; - frame->used = dsize; - audio->drv_ops.send_data(audio, 0); - } - } - if (eos_condition == AUDMP3_EOS_SET) - rc = audmp3_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - if (!rc) { - if (buf > start) - return buf - start; - } - return rc; -} -static void audmp3_reset_ion_region(struct audio *audio) -{ - struct audmp3_ion_region *region; - struct list_head *ptr, *next; - - list_for_each_safe(ptr, next, &audio->ion_region_queue) { - region = list_entry(ptr, struct audmp3_ion_region, list); - list_del(®ion->list); - ion_unmap_kernel(audio->client, region->handle); - ion_free(audio->client, region->handle); - kfree(region); - } - - return; -} - -static int audio_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_INFO("audio instance 0x%08x freeing\n", (int)audio); - mutex_lock(&audio->lock); - audio_disable(audio); - if (audio->rmt_resource_released == 0) - rmt_put_resource(audio); - audio->drv_ops.out_flush(audio); - audio->drv_ops.in_flush(audio); - audmp3_reset_ion_region(audio); - - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->opened = 0; - audio->event_abort = 1; - wake_up(&audio->event_wait); - audmp3_reset_event_queue(audio); - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - if (!(audio->drv_status & ADRV_STATUS_AIO_INTF)) { - ion_unmap_kernel(audio->client, audio->output_buff_handle); - ion_free(audio->client, audio->output_buff_handle); - ion_unmap_kernel(audio->client, audio->input_buff_handle); - ion_free(audio->client, audio->input_buff_handle); - } - ion_client_destroy(audio->client); - kfree(audio); - return 0; -} - -static void audmp3_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audmp3_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audmp3_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audmp3_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audmp3_suspend(struct early_suspend *h) -{ - struct audmp3_suspend_ctl *ctl = - container_of(h, struct audmp3_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audmp3_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audmp3_resume(struct early_suspend *h) -{ - struct audmp3_suspend_ctl *ctl = - container_of(h, struct audmp3_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audmp3_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audmp3_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audmp3_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 4096; - static char buffer[4096]; - int n = 0, i; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_feedback %d\n", audio->pcm_feedback); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_buf_sz %d\n", audio->out[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_count %d \n", audio->pcm_buf_count); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_sz %d \n", audio->in[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %x \n", audio->vol_pan.volume); - n += scnprintf(buffer + n, debug_bufmax - n, - "sample rate %d \n", audio->out_sample_rate); - n += scnprintf(buffer + n, debug_bufmax - n, - "channel mode %d \n", audio->out_channel_mode); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "rflush %d\n", audio->rflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d \n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d \n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d \n", audio->out_needed); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_head %d \n", audio->out_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_tail %d \n", audio->out_tail); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[0].used %d \n", audio->out[0].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[1].used %d \n", audio->out[1].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "buffer_refresh %d \n", audio->buf_refresh); - n += scnprintf(buffer + n, debug_bufmax - n, - "read_next %d \n", audio->read_next); - n += scnprintf(buffer + n, debug_bufmax - n, - "fill_next %d \n", audio->fill_next); - for (i = 0; i < audio->pcm_buf_count; i++) - n += scnprintf(buffer + n, debug_bufmax - n, - "in[%d].size %d \n", i, audio->in[i].used); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audmp3_debug_fops = { - .read = audmp3_debug_read, - .open = audmp3_debug_open, -}; -#endif - -static int audio_open(struct inode *inode, struct file *file) -{ - - struct audio *audio = NULL; - int rc, i, dec_attrb, decid; - struct audmp3_event *e_node = NULL; - unsigned mem_sz = DMASZ_MAX; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - struct ion_client *client = NULL; - int len = 0; - -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_mp3_" + 5]; -#endif - - /* Allocate audio instance, set to zero */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("no memory to allocate audio instance \n"); - rc = -ENOMEM; - goto done; - } - MM_INFO("audio instance 0x%08x created\n", (int)audio); - - /* Allocate the decoder */ - dec_attrb = AUDDEC_DEC_MP3; - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_NONTUNNEL; - audio->pcm_feedback = NON_TUNNEL_MODE_PLAYBACK; - } else if ((file->f_mode & FMODE_WRITE) && - !(file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_TUNNEL; - audio->pcm_feedback = TUNNEL_MODE_PLAYBACK; - } else { - kfree(audio); - rc = -EACCES; - goto done; - } - - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - if (decid < 0) { - MM_ERR("No free decoder available, freeing instance 0x%08x\n", - (int)audio); - rc = -ENODEV; - kfree(audio); - goto done; - } - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - client = msm_ion_client_create(UINT_MAX, "Audio_MP3_Client"); - if (IS_ERR_OR_NULL(client)) { - pr_err("Unable to create ION client\n"); - rc = -ENOMEM; - goto client_create_error; - } - audio->client = client; - - /* Non AIO interface */ - if (!(file->f_flags & O_NONBLOCK)) { - - MM_DBG("memsz = %d\n", mem_sz); - - handle = ion_alloc(client, mem_sz, SZ_4K, - ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to create allocate O/P buffers\n"); - rc = -ENOMEM; - goto output_buff_alloc_error; - } - audio->output_buff_handle = handle; - - rc = ion_phys(client , handle, &addr, &len); - if (rc) { - MM_ERR("O/P buffers:Invalid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - goto output_buff_get_phys_error; - } else { - MM_INFO("O/P buffers:valid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - } - audio->phys = (int32_t)addr; - - - rc = ion_handle_get_flags(client, handle, &ionflag); - if (rc) { - MM_ERR("could not get flags for the handle\n"); - goto output_buff_get_flags_error; - } - - audio->map_v_write = ion_map_kernel(client, handle); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write buffers\n"); - rc = -ENOMEM; - goto output_buff_map_error; - } - audio->data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->phys, (int)audio->data); - - audio->out_dma_sz = mem_sz; - } - - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) { - rc = audmgr_open(&audio->audmgr); - if (rc) { - MM_ERR("audmgr open failed, freeing instance \ - 0x%08x\n", (int)audio); - if (!(file->f_flags & O_NONBLOCK)) - goto err; - else - goto resource_err; - } - } - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audplay_adsp_ops, audio); - - if (rc) { - MM_ERR("failed to get %s module, freeing instance 0x%08x\n", - audio->module_name, (int)audio); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_close(&audio->audmgr); - if (!(file->f_flags & O_NONBLOCK)) - goto err; - else - goto resource_err; - } - - rc = rmt_get_resource(audio); - if (rc) { - MM_ERR("ADSP resources are not available for MP3 session \ - 0x%08x on decoder: %d\n", (int)audio, audio->dec_id); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_close(&audio->audmgr); - msm_adsp_put(audio->audplay); - if (!(file->f_flags & O_NONBLOCK)) - goto err; - else - goto resource_err; - } - - if (file->f_flags & O_NONBLOCK) { - MM_DBG("set to aio interface\n"); - audio->drv_status |= ADRV_STATUS_AIO_INTF; - audio->drv_ops.pcm_buf_update = audmp3_async_pcm_buf_update; - audio->drv_ops.buffer_refresh = audmp3_async_buffer_refresh; - audio->drv_ops.send_data = audmp3_async_send_data; - audio->drv_ops.out_flush = audmp3_async_flush; - audio->drv_ops.in_flush = audmp3_async_flush_pcm_buf; - audio->drv_ops.fsync = audmp3_async_fsync; - } else { - MM_DBG("set to std io interface\n"); - audio->drv_ops.pcm_buf_update = audio_update_pcm_buf_entry; - audio->drv_ops.buffer_refresh = audplay_buffer_refresh; - audio->drv_ops.send_data = audplay_send_data; - audio->drv_ops.out_flush = audio_flush; - audio->drv_ops.in_flush = audio_flush_pcm_buf; - audio->drv_ops.fsync = audmp3_sync_fsync; - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = (audio->out_dma_sz >> 1); - - audio->out[1].data = audio->data + audio->out[0].size; - audio->out[1].addr = audio->phys + audio->out[0].size; - audio->out[1].size = audio->out[0].size; - } - - /* Initialize all locks of audio instance */ - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->read_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - init_waitqueue_head(&audio->write_wait); - init_waitqueue_head(&audio->read_wait); - INIT_LIST_HEAD(&audio->out_queue); - INIT_LIST_HEAD(&audio->in_queue); - INIT_LIST_HEAD(&audio->ion_region_queue); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - spin_lock_init(&audio->event_queue_lock); - - audio->out_sample_rate = 44100; - audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V; - audio->vol_pan.volume = 0x2000; - - audio->drv_ops.out_flush(audio); - - file->private_data = audio; - audio->opened = 1; -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_mp3_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, &audmp3_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audmp3_resume; - audio->suspend_ctl.node.suspend = audmp3_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (i = 0; i < AUDMP3_EVENT_NUM; i++) { - e_node = kmalloc(sizeof(struct audmp3_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } - -done: - return rc; -err: - ion_unmap_kernel(client, audio->output_buff_handle); -output_buff_map_error: -output_buff_get_flags_error: -output_buff_get_phys_error: - ion_free(client, audio->output_buff_handle); -output_buff_alloc_error: - ion_client_destroy(client); -client_create_error: -resource_err: - audpp_adec_free(audio->dec_id); - kfree(audio); - return rc; -} - -static const struct file_operations audio_mp3_fops = { - .owner = THIS_MODULE, - .open = audio_open, - .release = audio_release, - .read = audio_read, - .write = audio_write, - .unlocked_ioctl = audio_ioctl, - .fsync = audmp3_fsync, -}; - -struct miscdevice audio_mp3_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_mp3", - .fops = &audio_mp3_fops, -}; - -static int __init audio_init(void) -{ - return misc_register(&audio_mp3_misc); -} - -static void __exit audio_exit(void) -{ - misc_deregister(&audio_mp3_misc); -} - -module_init(audio_init); -module_exit(audio_exit); - -MODULE_DESCRIPTION("MSM MP3 driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5/audio_mvs.c b/arch/arm/mach-msm/qdsp5/audio_mvs.c deleted file mode 100644 index 982c719f9fd1fb5cf2c1fdbc55b6472a81b61c36..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_mvs.c +++ /dev/null @@ -1,1714 +0,0 @@ -/* Copyright (c) 2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define MVS_PROG 0x30000014 -#define MVS_VERS 0x00030001 -#define MVS_VERS_COMP_VER2 0x00060001 -#define MVS_VERS_COMP_VER3 0x00030001 - - -#define MVS_CLIENT_ID_VOIP 0x00000003 - -#define MVS_ACQUIRE_PROC 4 -#define MVS_ENABLE_PROC 5 -#define MVS_RELEASE_PROC 6 -#define MVS_AMR_SET_AMR_MODE_PROC 7 -#define MVS_AMR_SET_AWB_MODE_PROC 8 -#define MVS_VOC_SET_FRAME_RATE_PROC 10 -#define MVS_GSM_SET_DTX_MODE_PROC 11 -#define MVS_G729A_SET_MODE_PROC 12 -#define MVS_G711_GET_MODE_PROC 14 -#define MVS_G711_SET_MODE_PROC 15 -#define MVS_G711A_GET_MODE_PROC 16 -#define MVS_G711A_SET_MODE_PROC 17 -#define MVS_G722_SET_MODE_PROC 20 -#define MVS_G722_GET_MODE_PROC 21 -#define MVS_SET_DTX_MODE_PROC 22 - -#define MVS_EVENT_CB_TYPE_PROC 1 -#define MVS_PACKET_UL_FN_TYPE_PROC 2 -#define MVS_PACKET_DL_FN_TYPE_PROC 3 - -#define MVS_CB_FUNC_ID 0xAAAABBBB -#define MVS_UL_CB_FUNC_ID 0xBBBBCCCC -#define MVS_DL_CB_FUNC_ID 0xCCCCDDDD - -#define MVS_FRAME_MODE_VOC_TX 1 -#define MVS_FRAME_MODE_VOC_RX 2 -#define MVS_FRAME_MODE_AMR_UL 3 -#define MVS_FRAME_MODE_AMR_DL 4 -#define MVS_FRAME_MODE_GSM_UL 5 -#define MVS_FRAME_MODE_GSM_DL 6 -#define MVS_FRAME_MODE_HR_UL 7 -#define MVS_FRAME_MODE_HR_DL 8 -#define MVS_FRAME_MODE_G711_UL 9 -#define MVS_FRAME_MODE_G711_DL 10 -#define MVS_FRAME_MODE_PCM_UL 13 -#define MVS_FRAME_MODE_PCM_DL 14 -#define MVS_FRAME_MODE_PCM_WB_UL 23 -#define MVS_FRAME_MODE_PCM_WB_DL 24 -#define MVS_FRAME_MODE_G729A_UL 17 -#define MVS_FRAME_MODE_G729A_DL 18 -#define MVS_FRAME_MODE_G711A_UL 19 -#define MVS_FRAME_MODE_G711A_DL 20 -#define MVS_FRAME_MODE_G722_UL 21 -#define MVS_FRAME_MODE_G722_DL 22 - - - -#define MVS_PKT_CONTEXT_ISR 0x00000001 - -#define RPC_TYPE_REQUEST 0 -#define RPC_TYPE_REPLY 1 - -#define RPC_STATUS_FAILURE 0 -#define RPC_STATUS_SUCCESS 1 -#define RPC_STATUS_REJECT 1 - -#define RPC_COMMON_HDR_SZ (sizeof(uint32_t) * 2) -#define RPC_REQUEST_HDR_SZ (sizeof(struct rpc_request_hdr)) -#define RPC_REPLY_HDR_SZ (sizeof(uint32_t) * 3) - -enum audio_mvs_state_type { - AUDIO_MVS_CLOSED, - AUDIO_MVS_OPENED, - AUDIO_MVS_STARTED, - AUDIO_MVS_STOPPED -}; - -enum audio_mvs_event_type { - AUDIO_MVS_COMMAND, - AUDIO_MVS_MODE, - AUDIO_MVS_NOTIFY -}; - -enum audio_mvs_cmd_status_type { - AUDIO_MVS_CMD_FAILURE, - AUDIO_MVS_CMD_BUSY, - AUDIO_MVS_CMD_SUCCESS -}; - -enum audio_mvs_mode_status_type { - AUDIO_MVS_MODE_NOT_AVAIL, - AUDIO_MVS_MODE_INIT, - AUDIO_MVS_MODE_READY -}; - -enum audio_mvs_pkt_status_type { - AUDIO_MVS_PKT_NORMAL, - AUDIO_MVS_PKT_FAST, - AUDIO_MVS_PKT_SLOW -}; - -/* Parameters required for MVS acquire. */ -struct rpc_audio_mvs_acquire_args { - uint32_t client_id; - uint32_t cb_func_id; -}; - -struct audio_mvs_acquire_msg { - struct rpc_request_hdr rpc_hdr; - struct rpc_audio_mvs_acquire_args acquire_args; -}; - -/* Parameters required for MVS enable. */ -struct rpc_audio_mvs_enable_args { - uint32_t client_id; - uint32_t mode; - uint32_t ul_cb_func_id; - uint32_t dl_cb_func_id; - uint32_t context; -}; - -struct audio_mvs_enable_msg { - struct rpc_request_hdr rpc_hdr; - struct rpc_audio_mvs_enable_args enable_args; -}; - -/* Parameters required for MVS release. */ -struct audio_mvs_release_msg { - struct rpc_request_hdr rpc_hdr; - uint32_t client_id; -}; - -/* Parameters required for setting AMR mode. */ -struct audio_mvs_set_amr_mode_msg { - struct rpc_request_hdr rpc_hdr; - uint32_t amr_mode; -}; - -/* Parameters required for setting DTX. */ -struct audio_mvs_set_dtx_mode_msg { - struct rpc_request_hdr rpc_hdr; - uint32_t dtx_mode; -}; - -/* Parameters required for setting EVRC mode. */ -struct audio_mvs_set_voc_mode_msg { - struct rpc_request_hdr rpc_hdr; - uint32_t max_rate; - uint32_t min_rate; -}; - -/* Parameters for G711 mode */ -struct audio_mvs_set_g711_mode_msg { - struct rpc_request_hdr rpc_hdr; - uint32_t g711_mode; -}; - -/* Parameters for G729 mode */ -struct audio_mvs_set_g729_mode_msg { - struct rpc_request_hdr rpc_hdr; - uint32_t g729_mode; -}; - -/* Parameters for G722 mode */ -struct audio_mvs_set_g722_mode_msg { - struct rpc_request_hdr rpc_hdr; - uint32_t g722_mode; -}; - - -/* Parameters for G711A mode */ -struct audio_mvs_set_g711A_mode_msg { - struct rpc_request_hdr rpc_hdr; - uint32_t g711A_mode; -}; - -/* Parameters for EFR FR and HR mode */ -struct audio_mvs_set_efr_mode_msg { - struct rpc_request_hdr rpc_hdr; - uint32_t efr_mode; -}; - -union audio_mvs_event_data { - struct mvs_ev_command_type { - uint32_t event; - uint32_t client_id; - uint32_t cmd_status; - } mvs_ev_command_type; - - struct mvs_ev_mode_type { - uint32_t event; - uint32_t client_id; - uint32_t mode_status; - uint32_t mode; - } mvs_ev_mode_type; - - struct mvs_ev_notify_type { - uint32_t event; - uint32_t client_id; - uint32_t buf_dir; - uint32_t max_frames; - } mvs_ev_notify_type; -}; - -struct audio_mvs_cb_func_args { - uint32_t cb_func_id; - uint32_t valid_ptr; - uint32_t event; - union audio_mvs_event_data event_data; -}; - -struct audio_mvs_frame_info_hdr { - uint32_t frame_mode; - uint32_t mvs_mode; - uint16_t buf_free_cnt; -}; - -struct audio_mvs_ul_reply { - struct rpc_reply_hdr reply_hdr; - uint32_t valid_pkt_status_ptr; - uint32_t pkt_status; -}; - -struct audio_mvs_dl_cb_func_args { - uint32_t cb_func_id; - - uint32_t valid_ptr; - uint32_t frame_mode; - uint32_t frame_mode_ignore; - - struct audio_mvs_frame_info_hdr frame_info_hdr; - - uint32_t amr_frame; - uint32_t amr_mode; -}; -/*general codec parameters includes AMR, G711A, PCM -G729, VOC and HR vocoders -*/ -struct gnr_cdc_param { - uint32_t param1; - uint32_t param2; - uint32_t valid_pkt_status_ptr; - uint32_t pkt_status; -}; -/*G711 codec parameter*/ -struct g711_param { - uint32_t param1; - uint32_t valid_pkt_status_ptr; - uint32_t pkt_status; -}; - -union codec_param { - struct gnr_cdc_param gnr_arg; - struct g711_param g711_arg; -}; - -struct audio_mvs_dl_reply { - struct rpc_reply_hdr reply_hdr; - - uint32_t voc_pkt[MVS_MAX_VOC_PKT_SIZE/4]; - - uint32_t valid_frame_info_ptr; - uint32_t frame_mode; - uint32_t frame_mode_again; - - struct audio_mvs_frame_info_hdr frame_info_hdr; - union codec_param cdc_param; -}; - -struct audio_mvs_buf_node { - struct list_head list; - struct msm_audio_mvs_frame frame; -}; - -/* Each buffer is 20 ms, queue holds 200 ms of data. */ -#define MVS_MAX_Q_LEN 10 - -struct audio_mvs_info_type { - enum audio_mvs_state_type state; - uint32_t frame_mode; - uint32_t mvs_mode; - uint32_t buf_free_cnt; - uint32_t rate_type; - uint32_t dtx_mode; - - struct msm_rpc_endpoint *rpc_endpt; - uint32_t rpc_prog; - uint32_t rpc_ver; - uint32_t rpc_status; - - uint8_t *mem_chunk; - - struct list_head in_queue; - struct list_head free_in_queue; - - struct list_head out_queue; - struct list_head free_out_queue; - - struct task_struct *task; - - wait_queue_head_t wait; - wait_queue_head_t mode_wait; - wait_queue_head_t out_wait; - - struct mutex lock; - struct mutex in_lock; - struct mutex out_lock; - - struct wake_lock suspend_lock; - struct pm_qos_request pm_qos_req; -}; - -static struct audio_mvs_info_type audio_mvs_info; - -static int audio_mvs_setup_mode(struct audio_mvs_info_type *audio) -{ - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - switch (audio->mvs_mode) { - case MVS_MODE_AMR: - case MVS_MODE_AMR_WB: { - struct audio_mvs_set_amr_mode_msg set_amr_mode_msg; - struct audio_mvs_set_dtx_mode_msg set_dtx_mode_msg; - - /* Set AMR mode. */ - memset(&set_amr_mode_msg, 0, sizeof(set_amr_mode_msg)); - set_amr_mode_msg.amr_mode = cpu_to_be32(audio->rate_type); - - if (audio->mvs_mode == MVS_MODE_AMR) { - msm_rpc_setup_req(&set_amr_mode_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_AMR_SET_AMR_MODE_PROC); - } else { - msm_rpc_setup_req(&set_amr_mode_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_AMR_SET_AWB_MODE_PROC); - } - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, - &set_amr_mode_msg, - sizeof(set_amr_mode_msg)); - - if (rc >= 0) { - MM_DBG("RPC write for set amr mode done\n"); - - /* Save the MVS configuration information. */ - audio->frame_mode = MVS_FRAME_MODE_AMR_DL; - - /* Disable DTX. */ - memset(&set_dtx_mode_msg, 0, sizeof(set_dtx_mode_msg)); - set_dtx_mode_msg.dtx_mode = cpu_to_be32(0); - - msm_rpc_setup_req(&set_dtx_mode_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_SET_DTX_MODE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, - &set_dtx_mode_msg, - sizeof(set_dtx_mode_msg)); - - if (rc >= 0) { - MM_DBG("RPC write for set dtx done\n"); - - rc = 0; - } - } else { - MM_ERR("RPC write for set amr mode failed %d\n", rc); - } - break; - } - case MVS_MODE_PCM: - case MVS_MODE_LINEAR_PCM: { - /* PCM does not have any params to be set. - Save the MVS configuration information. */ - audio->rate_type = MVS_AMR_MODE_UNDEF; - audio->frame_mode = MVS_FRAME_MODE_PCM_DL; - break; - } - case MVS_MODE_PCM_WB: { - audio->rate_type = MVS_AMR_MODE_UNDEF; - audio->frame_mode = MVS_FRAME_MODE_PCM_WB_DL; - break; - } - case MVS_MODE_IS127: - case MVS_MODE_IS733: - case MVS_MODE_4GV_NB: - case MVS_MODE_4GV_WB: { - struct audio_mvs_set_voc_mode_msg set_voc_mode_msg; - - /* Set EVRC mode. */ - memset(&set_voc_mode_msg, 0, sizeof(set_voc_mode_msg)); - set_voc_mode_msg.min_rate = cpu_to_be32(audio->rate_type); - set_voc_mode_msg.max_rate = cpu_to_be32(audio->rate_type); - - MM_DBG("audio->mvs_mode %d audio->rate_type %d\n", - audio->mvs_mode, audio->rate_type); - msm_rpc_setup_req(&set_voc_mode_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_VOC_SET_FRAME_RATE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, - &set_voc_mode_msg, - sizeof(set_voc_mode_msg)); - - if (rc >= 0) { - MM_DBG("RPC write for set voc mode done\n"); - - /* Save the MVS configuration information. */ - audio->frame_mode = MVS_FRAME_MODE_VOC_RX; - - rc = 0; - } else { - MM_ERR("RPC write for set voc mode failed %d\n", rc); - } - break; - } - case MVS_MODE_G711: { - struct audio_mvs_set_g711_mode_msg set_g711_mode_msg; - - /* Set G711 mode. */ - memset(&set_g711_mode_msg, 0, sizeof(set_g711_mode_msg)); - set_g711_mode_msg.g711_mode = cpu_to_be32(audio->rate_type); - - MM_DBG("mode of g711:%d\n", set_g711_mode_msg.g711_mode); - - msm_rpc_setup_req(&set_g711_mode_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_G711_SET_MODE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, - &set_g711_mode_msg, - sizeof(set_g711_mode_msg)); - - if (rc >= 0) { - MM_DBG("RPC write for set g711 mode done\n"); - /* Save the MVS configuration information. */ - audio->frame_mode = MVS_FRAME_MODE_G711_DL; - - rc = 0; - } else { - MM_ERR("RPC write for set g711 mode failed %d\n", rc); - } - break; - } - case MVS_MODE_G729A: { - struct audio_mvs_set_g729_mode_msg set_g729_mode_msg; - - /* Set G729 mode. */ - memset(&set_g729_mode_msg, 0, sizeof(set_g729_mode_msg)); - set_g729_mode_msg.g729_mode = cpu_to_be32(audio->dtx_mode); - - MM_DBG("mode of g729:%d\n", - set_g729_mode_msg.g729_mode); - - msm_rpc_setup_req(&set_g729_mode_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_G729A_SET_MODE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, - &set_g729_mode_msg, - sizeof(set_g729_mode_msg)); - - if (rc >= 0) { - MM_DBG("RPC write for set g729 mode done\n"); - - /* Save the MVS configuration information. */ - audio->frame_mode = MVS_FRAME_MODE_G729A_DL; - - rc = 0; - } else { - MM_ERR("RPC write for set g729 mode failed %d\n", rc); - } - break; - } - case MVS_MODE_G722: { - struct audio_mvs_set_g722_mode_msg set_g722_mode_msg; - - /* Set G722 mode. */ - memset(&set_g722_mode_msg, 0, sizeof(set_g722_mode_msg)); - set_g722_mode_msg.g722_mode = cpu_to_be32(audio->rate_type); - - MM_DBG("mode of g722:%d\n", - set_g722_mode_msg.g722_mode); - - msm_rpc_setup_req(&set_g722_mode_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_G722_SET_MODE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, - &set_g722_mode_msg, - sizeof(set_g722_mode_msg)); - - if (rc >= 0) { - MM_DBG("RPC write for set g722 mode done\n"); - - /* Save the MVS configuration information. */ - audio->frame_mode = MVS_FRAME_MODE_G722_DL; - - rc = 0; - } - break; - } - case MVS_MODE_G711A: { - struct audio_mvs_set_g711A_mode_msg set_g711A_mode_msg; - struct audio_mvs_set_dtx_mode_msg set_dtx_mode_msg; - - /* Set G711A mode. */ - memset(&set_g711A_mode_msg, 0, sizeof(set_g711A_mode_msg)); - set_g711A_mode_msg.g711A_mode = cpu_to_be32(audio->rate_type); - - MM_DBG("mode of g711A:%d\n", - set_g711A_mode_msg.g711A_mode); - - msm_rpc_setup_req(&set_g711A_mode_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_G711A_SET_MODE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, - &set_g711A_mode_msg, - sizeof(set_g711A_mode_msg)); - - if (rc >= 0) { - MM_DBG("RPC write for set g711A mode done\n"); - - /* Save the MVS configuration information. */ - audio->frame_mode = MVS_FRAME_MODE_G711A_DL; - /* Set DTX MODE. */ - memset(&set_dtx_mode_msg, 0, sizeof(set_dtx_mode_msg)); - set_dtx_mode_msg.dtx_mode = - cpu_to_be32((audio->dtx_mode)); - - msm_rpc_setup_req(&set_dtx_mode_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_SET_DTX_MODE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, - &set_dtx_mode_msg, - sizeof(set_dtx_mode_msg)); - - if (rc >= 0) { - MM_DBG("RPC write for set dtx done\n"); - - rc = 0; - } - rc = 0; - } else { - MM_ERR("RPC write for set g711A mode failed %d\n", rc); - } - break; - } - case MVS_MODE_EFR: - case MVS_MODE_FR: - case MVS_MODE_HR: { - struct audio_mvs_set_efr_mode_msg set_efr_mode_msg; - - /* Set G729 mode. */ - memset(&set_efr_mode_msg, 0, sizeof(set_efr_mode_msg)); - set_efr_mode_msg.efr_mode = cpu_to_be32(audio->dtx_mode); - - MM_DBG("mode of EFR, FR and HR:%d\n", - set_efr_mode_msg.efr_mode); - - msm_rpc_setup_req(&set_efr_mode_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_GSM_SET_DTX_MODE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, - &set_efr_mode_msg, - sizeof(set_efr_mode_msg)); - - if (rc >= 0) { - MM_DBG("RPC write for set EFR, FR and HR mode done\n"); - - /* Save the MVS configuration information. */ - if ((audio->mvs_mode == MVS_MODE_EFR) || - (audio->mvs_mode == MVS_MODE_FR)) - audio->frame_mode = MVS_FRAME_MODE_GSM_DL; - if (audio->mvs_mode == MVS_MODE_HR) - audio->frame_mode = MVS_FRAME_MODE_HR_DL; - - rc = 0; - } else { - MM_ERR("RPC write for set EFR, FR" - "and HR mode failed %d\n", rc); - } - break; - } - default: - rc = -EINVAL; - MM_ERR("Default case\n"); - } - return rc; -} - -static int audio_mvs_setup(struct audio_mvs_info_type *audio) -{ - int rc = 0; - struct audio_mvs_enable_msg enable_msg; - - MM_DBG("\n"); - - /* Enable MVS. */ - memset(&enable_msg, 0, sizeof(enable_msg)); - enable_msg.enable_args.client_id = cpu_to_be32(MVS_CLIENT_ID_VOIP); - enable_msg.enable_args.mode = cpu_to_be32(audio->mvs_mode); - enable_msg.enable_args.ul_cb_func_id = cpu_to_be32(MVS_UL_CB_FUNC_ID); - enable_msg.enable_args.dl_cb_func_id = cpu_to_be32(MVS_DL_CB_FUNC_ID); - enable_msg.enable_args.context = cpu_to_be32(MVS_PKT_CONTEXT_ISR); - - msm_rpc_setup_req(&enable_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_ENABLE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, &enable_msg, sizeof(enable_msg)); - - if (rc >= 0) { - MM_DBG("RPC write for enable done\n"); - - rc = wait_event_timeout(audio->mode_wait, - (audio->rpc_status != RPC_STATUS_FAILURE), - 10 * HZ); - - if (rc > 0) { - MM_DBG("Wait event for enable succeeded\n"); - rc = audio_mvs_setup_mode(audio); - if (rc < 0) { - MM_ERR("Unknown MVS mode %d\n", - audio->mvs_mode); - } - MM_ERR("rc value after mode setup: %d\n", rc); - } else { - MM_ERR("Wait event for enable failed %d\n", rc); - } - } else { - MM_ERR("RPC write for enable failed %d\n", rc); - } - - return rc; -} - -static int audio_mvs_start(struct audio_mvs_info_type *audio) -{ - int rc = 0; - struct audio_mvs_acquire_msg acquire_msg; - - MM_DBG("\n"); - - /* Prevent sleep. */ - wake_lock(&audio->suspend_lock); - pm_qos_update_request(&audio->pm_qos_req, - msm_cpuidle_get_deep_idle_latency()); - - /* Acquire MVS. */ - memset(&acquire_msg, 0, sizeof(acquire_msg)); - acquire_msg.acquire_args.client_id = cpu_to_be32(MVS_CLIENT_ID_VOIP); - acquire_msg.acquire_args.cb_func_id = cpu_to_be32(MVS_CB_FUNC_ID); - - msm_rpc_setup_req(&acquire_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_ACQUIRE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, - &acquire_msg, - sizeof(acquire_msg)); - - if (rc >= 0) { - MM_DBG("RPC write for acquire done\n"); - - rc = wait_event_timeout(audio->wait, - (audio->rpc_status != RPC_STATUS_FAILURE), - 1 * HZ); - - if (rc > 0) { - - rc = audio_mvs_setup(audio); - - if (rc == 0) - audio->state = AUDIO_MVS_STARTED; - - } else { - MM_ERR("Wait event for acquire failed %d\n", rc); - - rc = -EBUSY; - } - } else { - MM_ERR("RPC write for acquire failed %d\n", rc); - - rc = -EBUSY; - } - - return rc; -} - -static int audio_mvs_stop(struct audio_mvs_info_type *audio) -{ - int rc = 0; - struct audio_mvs_release_msg release_msg; - - MM_DBG("\n"); - - /* Release MVS. */ - memset(&release_msg, 0, sizeof(release_msg)); - release_msg.client_id = cpu_to_be32(MVS_CLIENT_ID_VOIP); - - msm_rpc_setup_req(&release_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_RELEASE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, &release_msg, sizeof(release_msg)); - - if (rc >= 0) { - MM_DBG("RPC write for release done\n"); - - rc = wait_event_timeout(audio->mode_wait, - (audio->rpc_status != RPC_STATUS_FAILURE), - 1 * HZ); - - if (rc > 0) { - MM_DBG("Wait event for release succeeded\n"); - - audio->state = AUDIO_MVS_STOPPED; - - /* Un-block read in case it is waiting for data. */ - wake_up(&audio->out_wait); - rc = 0; - } else { - MM_ERR("Wait event for release failed %d\n", rc); - } - } else { - MM_ERR("RPC write for release failed %d\n", rc); - } - - /* Allow sleep. */ - pm_qos_update_request(&audio->pm_qos_req, PM_QOS_DEFAULT_VALUE); - wake_unlock(&audio->suspend_lock); - - return rc; -} - -static void audio_mvs_process_rpc_request(uint32_t procedure, - uint32_t xid, - void *data, - uint32_t length, - struct audio_mvs_info_type *audio) -{ - int rc = 0; - - MM_DBG("\n"); - - switch (procedure) { - case MVS_EVENT_CB_TYPE_PROC: { - struct audio_mvs_cb_func_args *args = data; - struct rpc_reply_hdr reply_hdr; - - MM_DBG("MVS CB CB_FUNC_ID 0x%x\n", - be32_to_cpu(args->cb_func_id)); - - if (be32_to_cpu(args->valid_ptr)) { - uint32_t event_type = be32_to_cpu(args->event); - - MM_DBG("MVS CB event type %d\n", - be32_to_cpu(args->event)); - - if (event_type == AUDIO_MVS_COMMAND) { - uint32_t cmd_status = be32_to_cpu( - args->event_data.mvs_ev_command_type.cmd_status); - - MM_DBG("MVS CB command status %d\n", - cmd_status); - - if (cmd_status == AUDIO_MVS_CMD_SUCCESS) { - audio->rpc_status = RPC_STATUS_SUCCESS; - wake_up(&audio->wait); - } - - } else if (event_type == AUDIO_MVS_MODE) { - uint32_t mode_status = be32_to_cpu( - args->event_data.mvs_ev_mode_type.mode_status); - - MM_DBG("MVS CB mode status %d\n", mode_status); - - if (mode_status == AUDIO_MVS_MODE_READY) { - audio->rpc_status = RPC_STATUS_SUCCESS; - wake_up(&audio->mode_wait); - } - } else { - MM_ERR("MVS CB unknown event type %d\n", - event_type); - } - } else { - MM_ERR("MVS CB event pointer not valid\n"); - } - - /* Send ack to modem. */ - memset(&reply_hdr, 0, sizeof(reply_hdr)); - reply_hdr.xid = cpu_to_be32(xid); - reply_hdr.type = cpu_to_be32(RPC_TYPE_REPLY); - reply_hdr.reply_stat = cpu_to_be32(RPCMSG_REPLYSTAT_ACCEPTED); - - reply_hdr.data.acc_hdr.accept_stat = cpu_to_be32( - RPC_ACCEPTSTAT_SUCCESS); - reply_hdr.data.acc_hdr.verf_flavor = 0; - reply_hdr.data.acc_hdr.verf_length = 0; - - rc = msm_rpc_write(audio->rpc_endpt, - &reply_hdr, - sizeof(reply_hdr)); - - if (rc < 0) - MM_ERR("RPC write for response failed %d\n", rc); - - break; - } - - case MVS_PACKET_UL_FN_TYPE_PROC: { - uint32_t *args = data; - uint32_t pkt_len; - uint32_t frame_mode; - struct audio_mvs_ul_reply ul_reply; - struct audio_mvs_buf_node *buf_node = NULL; - - MM_DBG("MVS UL CB_FUNC_ID 0x%x\n", - be32_to_cpu(*args)); - args++; - - pkt_len = be32_to_cpu(*args); - MM_DBG("UL pkt_len %d\n", pkt_len); - args++; - - /* Copy the vocoder packets. */ - mutex_lock(&audio->out_lock); - - if (!list_empty(&audio->free_out_queue)) { - buf_node = list_first_entry(&audio->free_out_queue, - struct audio_mvs_buf_node, - list); - list_del(&buf_node->list); - - memcpy(&buf_node->frame.voc_pkt[0], args, pkt_len); - buf_node->frame.len = pkt_len; - pkt_len = ALIGN(pkt_len, 4); - args = args + pkt_len/4; - - MM_DBG("UL valid_ptr 0x%x\n", - be32_to_cpu(*args)); - args++; - - frame_mode = be32_to_cpu(*args); - MM_DBG("UL frame_mode %d\n", - frame_mode); - args++; - - MM_DBG("UL frame_mode %d\n", - be32_to_cpu(*args)); - args++; - - MM_DBG("UL frame_mode %d\n", - be32_to_cpu(*args)); - args++; - - MM_DBG("UL mvs_mode %d\n", - be32_to_cpu(*args)); - args++; - - MM_DBG("UL buf_free_cnt %d\n", - be32_to_cpu(*args)); - args++; - - if (frame_mode == MVS_FRAME_MODE_AMR_UL) { - /* Extract AMR frame type. */ - buf_node->frame.frame_type = be32_to_cpu(*args); - - MM_DBG("UL AMR frame_type %d\n", - be32_to_cpu(*args)); - } else if (frame_mode == MVS_FRAME_MODE_PCM_UL) { - /* PCM doesn't have frame_type */ - buf_node->frame.frame_type = 0; - } else if (frame_mode == MVS_FRAME_MODE_VOC_TX) { - /* Extracting EVRC current buffer frame rate*/ - buf_node->frame.frame_type = be32_to_cpu(*args); - pr_debug("%s: UL EVRC frame_type %d\n", - __func__, be32_to_cpu(*args)); - } else if (frame_mode == MVS_FRAME_MODE_G711_UL) { - /* Extract G711 frame type. */ - buf_node->frame.frame_type = be32_to_cpu(*args); - - MM_DBG("UL G711 frame_type %d\n", - be32_to_cpu(*args)); - } else if (frame_mode == MVS_FRAME_MODE_G729A_UL) { - /* Extract G729 frame type. */ - buf_node->frame.frame_type = be32_to_cpu(*args); - - MM_DBG("UL G729 frame_type %d\n", - be32_to_cpu(*args)); - } else if (frame_mode == MVS_FRAME_MODE_G722_UL) { - /* Extract G722 frame type. */ - buf_node->frame.frame_type = be32_to_cpu(*args); - - MM_DBG("UL G722 frame_type %d\n", - be32_to_cpu(*args)); - } else if (frame_mode == MVS_FRAME_MODE_G711A_UL) { - /* Extract G711A frame type. */ - buf_node->frame.frame_type = be32_to_cpu(*args); - - MM_DBG("UL G711A frame_type %d\n", - be32_to_cpu(*args)); - } else if ((frame_mode == MVS_FRAME_MODE_GSM_UL) || - (frame_mode == MVS_FRAME_MODE_HR_UL)) { - /* Extract EFR, FR and HR frame type. */ - buf_node->frame.frame_type = be32_to_cpu(*args); - - MM_DBG("UL EFR,FR,HR frame_type %d\n", - be32_to_cpu(*args)); - } else { - MM_DBG("UL Unknown frame mode %d\n", - frame_mode); - } - - list_add_tail(&buf_node->list, &audio->out_queue); - } else { - MM_ERR("UL data dropped, read is slow\n"); - } - - mutex_unlock(&audio->out_lock); - - wake_up(&audio->out_wait); - - /* Send UL message accept to modem. */ - memset(&ul_reply, 0, sizeof(ul_reply)); - ul_reply.reply_hdr.xid = cpu_to_be32(xid); - ul_reply.reply_hdr.type = cpu_to_be32(RPC_TYPE_REPLY); - ul_reply.reply_hdr.reply_stat = cpu_to_be32( - RPCMSG_REPLYSTAT_ACCEPTED); - - ul_reply.reply_hdr.data.acc_hdr.accept_stat = cpu_to_be32( - RPC_ACCEPTSTAT_SUCCESS); - ul_reply.reply_hdr.data.acc_hdr.verf_flavor = 0; - ul_reply.reply_hdr.data.acc_hdr.verf_length = 0; - - ul_reply.valid_pkt_status_ptr = cpu_to_be32(0x00000001); - ul_reply.pkt_status = cpu_to_be32(0x00000000); - - rc = msm_rpc_write(audio->rpc_endpt, - &ul_reply, - sizeof(ul_reply)); - - if (rc < 0) - MM_ERR("RPC write for UL response failed %d\n", - rc); - - break; - } - - case MVS_PACKET_DL_FN_TYPE_PROC: { - struct audio_mvs_dl_cb_func_args *args = data; - struct audio_mvs_dl_reply dl_reply; - uint32_t frame_mode; - struct audio_mvs_buf_node *buf_node = NULL; - - MM_DBG("MVS DL CB CB_FUNC_ID 0x%x\n", - be32_to_cpu(args->cb_func_id)); - - frame_mode = be32_to_cpu(args->frame_mode); - MM_DBG("DL frame_mode %d\n", frame_mode); - - /* Prepare and send the DL packets to modem. */ - memset(&dl_reply, 0, sizeof(dl_reply)); - dl_reply.reply_hdr.xid = cpu_to_be32(xid); - dl_reply.reply_hdr.type = cpu_to_be32(RPC_TYPE_REPLY); - dl_reply.reply_hdr.reply_stat = cpu_to_be32( - RPCMSG_REPLYSTAT_ACCEPTED); - - dl_reply.reply_hdr.data.acc_hdr.accept_stat = cpu_to_be32( - RPC_ACCEPTSTAT_SUCCESS); - dl_reply.reply_hdr.data.acc_hdr.verf_flavor = 0; - dl_reply.reply_hdr.data.acc_hdr.verf_length = 0; - - mutex_lock(&audio->in_lock); - - if (!list_empty(&audio->in_queue)) { - buf_node = list_first_entry(&audio->in_queue, - struct audio_mvs_buf_node, - list); - list_del(&buf_node->list); - - memcpy(&dl_reply.voc_pkt, - &buf_node->frame.voc_pkt[0], - buf_node->frame.len); - - MM_DBG("frame mode %d buf_node->frame.len %d\n", - frame_mode, buf_node->frame.len); - if (frame_mode == MVS_FRAME_MODE_AMR_DL) { - dl_reply.cdc_param.gnr_arg.param1 = cpu_to_be32( - buf_node->frame.frame_type); - dl_reply.cdc_param.gnr_arg.param2 = - cpu_to_be32(audio->rate_type); - dl_reply.cdc_param.\ - gnr_arg.valid_pkt_status_ptr = - cpu_to_be32(0x00000001); - dl_reply.cdc_param.gnr_arg.pkt_status = - cpu_to_be32(AUDIO_MVS_PKT_NORMAL); - } else if (frame_mode == MVS_FRAME_MODE_PCM_DL) { - dl_reply.cdc_param.gnr_arg.param1 = 0; - dl_reply.cdc_param.gnr_arg.param2 = 0; - dl_reply.cdc_param.\ - gnr_arg.valid_pkt_status_ptr = - cpu_to_be32(0x00000001); - dl_reply.cdc_param.gnr_arg.pkt_status = - cpu_to_be32(AUDIO_MVS_PKT_NORMAL); - } else if (frame_mode == MVS_FRAME_MODE_VOC_RX) { - dl_reply.cdc_param.gnr_arg.param1 = - cpu_to_be32(buf_node->frame.frame_type); - dl_reply.cdc_param.gnr_arg.param2 = 0; - dl_reply.cdc_param.\ - gnr_arg.valid_pkt_status_ptr = - cpu_to_be32(0x00000001); - dl_reply.cdc_param.gnr_arg.pkt_status = - cpu_to_be32(AUDIO_MVS_PKT_NORMAL); - } else if (frame_mode == MVS_FRAME_MODE_G711_DL) { - dl_reply.cdc_param.g711_arg.param1 = - cpu_to_be32(buf_node->frame.frame_type); - dl_reply.cdc_param.\ - g711_arg.valid_pkt_status_ptr = - cpu_to_be32(0x00000001); - dl_reply.cdc_param.g711_arg.pkt_status = - cpu_to_be32(AUDIO_MVS_PKT_NORMAL); - } else if (frame_mode == MVS_FRAME_MODE_G729A_DL) { - dl_reply.cdc_param.gnr_arg.param1 = cpu_to_be32( - buf_node->frame.frame_type); - dl_reply.cdc_param.gnr_arg.param2 = - cpu_to_be32(audio->rate_type); - dl_reply.cdc_param.\ - gnr_arg.valid_pkt_status_ptr = - cpu_to_be32(0x00000001); - dl_reply.cdc_param.gnr_arg.pkt_status = - cpu_to_be32(AUDIO_MVS_PKT_NORMAL); - } else if (frame_mode == MVS_FRAME_MODE_G722_DL) { - dl_reply.cdc_param.gnr_arg.param1 = cpu_to_be32( - buf_node->frame.frame_type); - dl_reply.cdc_param.gnr_arg.param2 = - cpu_to_be32(audio->rate_type); - dl_reply.cdc_param.\ - gnr_arg.valid_pkt_status_ptr = - cpu_to_be32(0x00000001); - dl_reply.cdc_param.gnr_arg.pkt_status = - cpu_to_be32(AUDIO_MVS_PKT_NORMAL); - } else if (frame_mode == MVS_FRAME_MODE_G711A_DL) { - dl_reply.cdc_param.gnr_arg.param1 = cpu_to_be32( - buf_node->frame.frame_type); - dl_reply.cdc_param.gnr_arg.param2 = - cpu_to_be32(audio->rate_type); - dl_reply.cdc_param.\ - gnr_arg.valid_pkt_status_ptr = - cpu_to_be32(0x00000001); - dl_reply.cdc_param.gnr_arg.pkt_status = - cpu_to_be32(AUDIO_MVS_PKT_NORMAL); - } else if ((frame_mode == MVS_FRAME_MODE_GSM_DL) || - (frame_mode == MVS_FRAME_MODE_HR_DL)) { - dl_reply.cdc_param.gnr_arg.param1 = cpu_to_be32( - buf_node->frame.frame_type); - dl_reply.cdc_param.gnr_arg.param2 = - cpu_to_be32(audio->rate_type); - dl_reply.cdc_param.\ - gnr_arg.valid_pkt_status_ptr = - cpu_to_be32(0x00000001); - dl_reply.cdc_param.gnr_arg.pkt_status = - cpu_to_be32(AUDIO_MVS_PKT_NORMAL); - } else { - MM_ERR("DL Unknown frame mode %d\n", - frame_mode); - } - list_add_tail(&buf_node->list, &audio->free_in_queue); - } else { - MM_DBG("No DL data available to send to MVS\n"); - if (frame_mode == MVS_FRAME_MODE_G711_DL) { - dl_reply.cdc_param.\ - g711_arg.valid_pkt_status_ptr = - cpu_to_be32(0x00000001); - dl_reply.cdc_param.g711_arg.pkt_status = - cpu_to_be32(AUDIO_MVS_PKT_SLOW); - } else { - dl_reply.cdc_param.\ - gnr_arg.valid_pkt_status_ptr = - cpu_to_be32(0x00000001); - dl_reply.cdc_param.gnr_arg.pkt_status = - cpu_to_be32(AUDIO_MVS_PKT_SLOW); - } - } - - mutex_unlock(&audio->in_lock); - - dl_reply.valid_frame_info_ptr = cpu_to_be32(0x00000001); - - dl_reply.frame_mode = cpu_to_be32(audio->frame_mode); - dl_reply.frame_mode_again = cpu_to_be32(audio->frame_mode); - - dl_reply.frame_info_hdr.frame_mode = - cpu_to_be32(audio->frame_mode); - dl_reply.frame_info_hdr.mvs_mode = cpu_to_be32(audio->mvs_mode); - dl_reply.frame_info_hdr.buf_free_cnt = 0; - - rc = msm_rpc_write(audio->rpc_endpt, - &dl_reply, - sizeof(dl_reply)); - - if (rc < 0) - MM_ERR("RPC write for DL response failed %d\n", - rc); - - break; - } - - default: - MM_ERR("Unknown CB type %d\n", procedure); - } -} - -static int audio_mvs_thread(void *data) -{ - struct audio_mvs_info_type *audio = data; - struct rpc_request_hdr *rpc_hdr = NULL; - - MM_DBG("\n"); - - while (!kthread_should_stop()) { - - int rpc_hdr_len = msm_rpc_read(audio->rpc_endpt, - (void **) &rpc_hdr, - -1, - -1); - - if (rpc_hdr_len < 0) { - MM_ERR("RPC read failed %d\n", - rpc_hdr_len); - - break; - } else if (rpc_hdr_len < RPC_COMMON_HDR_SZ) { - continue; - } else { - uint32_t rpc_type = be32_to_cpu(rpc_hdr->type); - if (rpc_type == RPC_TYPE_REPLY) { - struct rpc_reply_hdr *rpc_reply = - (void *) rpc_hdr; - uint32_t reply_status; - - if (rpc_hdr_len < RPC_REPLY_HDR_SZ) - continue; - - reply_status = - be32_to_cpu(rpc_reply->reply_stat); - - if (reply_status != RPCMSG_REPLYSTAT_ACCEPTED) { - /* If the command is not accepted, there - * will be no response callback. Wake - * the caller and report error. */ - audio->rpc_status = RPC_STATUS_REJECT; - - wake_up(&audio->wait); - - MM_ERR("RPC reply status denied\n"); - } - } else if (rpc_type == RPC_TYPE_REQUEST) { - if (rpc_hdr_len < RPC_REQUEST_HDR_SZ) - continue; - - audio_mvs_process_rpc_request( - be32_to_cpu(rpc_hdr->procedure), - be32_to_cpu(rpc_hdr->xid), - (void *) (rpc_hdr + 1), - (rpc_hdr_len - sizeof(*rpc_hdr)), - audio); - } else { - MM_ERR("Unexpected RPC type %d\n", rpc_type); - } - } - - kfree(rpc_hdr); - rpc_hdr = NULL; - } - - MM_DBG("MVS thread stopped\n"); - - return 0; -} - -static int audio_mvs_alloc_buf(struct audio_mvs_info_type *audio) -{ - int i = 0; - struct audio_mvs_buf_node *buf_node = NULL; - struct list_head *ptr = NULL; - struct list_head *next = NULL; - - MM_DBG("\n"); - - /* Allocate input buffers. */ - for (i = 0; i < MVS_MAX_Q_LEN; i++) { - buf_node = kmalloc(sizeof(struct audio_mvs_buf_node), - GFP_KERNEL); - - if (buf_node != NULL) { - list_add_tail(&buf_node->list, - &audio->free_in_queue); - } else { - MM_ERR("No memory for IO buffers\n"); - goto err; - } - buf_node = NULL; - } - - /* Allocate output buffers. */ - for (i = 0; i < MVS_MAX_Q_LEN; i++) { - buf_node = kmalloc(sizeof(struct audio_mvs_buf_node), - GFP_KERNEL); - - if (buf_node != NULL) { - list_add_tail(&buf_node->list, - &audio->free_out_queue); - } else { - MM_ERR("No memory for IO buffers\n"); - goto err; - } - buf_node = NULL; - } - - return 0; - -err: - list_for_each_safe(ptr, next, &audio->free_in_queue) { - buf_node = list_entry(ptr, struct audio_mvs_buf_node, list); - list_del(&buf_node->list); - kfree(buf_node); - buf_node = NULL; - } - - ptr = next = NULL; - list_for_each_safe(ptr, next, &audio->free_out_queue) { - buf_node = list_entry(ptr, struct audio_mvs_buf_node, list); - list_del(&buf_node->list); - kfree(buf_node); - buf_node = NULL; - } - - return -ENOMEM; -} - -static void audio_mvs_free_buf(struct audio_mvs_info_type *audio) -{ - struct list_head *ptr = NULL; - struct list_head *next = NULL; - struct audio_mvs_buf_node *buf_node = NULL; - - MM_DBG("\n"); - - mutex_lock(&audio->in_lock); - /* Free input buffers. */ - list_for_each_safe(ptr, next, &audio->in_queue) { - buf_node = list_entry(ptr, struct audio_mvs_buf_node, list); - list_del(&buf_node->list); - kfree(buf_node); - buf_node = NULL; - } - - ptr = next = NULL; - /* Free free_input buffers. */ - list_for_each_safe(ptr, next, &audio->free_in_queue) { - buf_node = list_entry(ptr, struct audio_mvs_buf_node, list); - list_del(&buf_node->list); - kfree(buf_node); - buf_node = NULL; - } - mutex_unlock(&audio->in_lock); - - mutex_lock(&audio->out_lock); - ptr = next = NULL; - /* Free output buffers. */ - list_for_each_safe(ptr, next, &audio->out_queue) { - buf_node = list_entry(ptr, struct audio_mvs_buf_node, list); - list_del(&buf_node->list); - kfree(buf_node); - buf_node = NULL; - } - - /* Free free_ioutput buffers. */ - ptr = next = NULL; - list_for_each_safe(ptr, next, &audio->free_out_queue) { - buf_node = list_entry(ptr, struct audio_mvs_buf_node, list); - list_del(&buf_node->list); - kfree(buf_node); - buf_node = NULL; - } - mutex_unlock(&audio->out_lock); -} -static int audio_mvs_release(struct inode *inode, struct file *file) -{ - - struct audio_mvs_info_type *audio = file->private_data; - - MM_DBG("\n"); - - mutex_lock(&audio->lock); - if (audio->state == AUDIO_MVS_STARTED) - audio_mvs_stop(audio); - audio_mvs_free_buf(audio); - audio->state = AUDIO_MVS_CLOSED; - mutex_unlock(&audio->lock); - - MM_DBG("Release done\n"); - return 0; -} - -static ssize_t audio_mvs_read(struct file *file, - char __user *buf, - size_t count, - loff_t *pos) -{ - int rc = 0; - struct audio_mvs_buf_node *buf_node = NULL; - struct audio_mvs_info_type *audio = file->private_data; - - MM_DBG("\n"); - - rc = wait_event_interruptible_timeout(audio->out_wait, - (!list_empty(&audio->out_queue) || - audio->state == AUDIO_MVS_STOPPED), - 1 * HZ); - - if (rc > 0) { - mutex_lock(&audio->out_lock); - if ((audio->state == AUDIO_MVS_STARTED) && - (!list_empty(&audio->out_queue))) { - - if (count >= sizeof(struct msm_audio_mvs_frame)) { - buf_node = list_first_entry(&audio->out_queue, - struct audio_mvs_buf_node, - list); - list_del(&buf_node->list); - - rc = copy_to_user(buf, - &buf_node->frame, - sizeof(struct msm_audio_mvs_frame)); - - if (rc == 0) { - rc = buf_node->frame.len + - sizeof(buf_node->frame.frame_type) + - sizeof(buf_node->frame.len); - } else { - MM_ERR("Copy to user retuned %d", rc); - - rc = -EFAULT; - } - - list_add_tail(&buf_node->list, - &audio->free_out_queue); - } else { - MM_ERR("Read count %d < sizeof(frame) %d", - count, - sizeof(struct msm_audio_mvs_frame)); - - rc = -ENOMEM; - } - } else { - MM_ERR("Read performed in state %d\n", - audio->state); - - rc = -EPERM; - } - mutex_unlock(&audio->out_lock); - - } else if (rc == 0) { - MM_ERR("No UL data available\n"); - - rc = -ETIMEDOUT; - } else { - MM_ERR("Read was interrupted\n"); - - rc = -ERESTARTSYS; - } - - return rc; -} - -static ssize_t audio_mvs_write(struct file *file, - const char __user *buf, - size_t count, - loff_t *pos) -{ - int rc = 0; - struct audio_mvs_buf_node *buf_node = NULL; - struct audio_mvs_info_type *audio = file->private_data; - - MM_DBG("\n"); - - mutex_lock(&audio->in_lock); - if (audio->state == AUDIO_MVS_STARTED) { - if (count <= sizeof(struct msm_audio_mvs_frame)) { - if (!list_empty(&audio->free_in_queue)) { - buf_node = - list_first_entry(&audio->free_in_queue, - struct audio_mvs_buf_node, - list); - list_del(&buf_node->list); - - rc = copy_from_user(&buf_node->frame, - buf, - count); - - list_add_tail(&buf_node->list, - &audio->in_queue); - } else { - MM_ERR("No free DL buffs\n"); - } - } else { - MM_ERR("Write count %d < sizeof(frame) %d", - count, - sizeof(struct msm_audio_mvs_frame)); - - rc = -ENOMEM; - } - } else { - MM_ERR("Write performed in invalid state %d\n", - audio->state); - - rc = -EPERM; - } - mutex_unlock(&audio->in_lock); - - return rc; -} - -static long audio_mvs_ioctl(struct file *file, - unsigned int cmd, - unsigned long arg) -{ - int rc = 0; - - struct audio_mvs_info_type *audio = file->private_data; - - MM_DBG("\n"); - - switch (cmd) { - case AUDIO_GET_MVS_CONFIG: { - struct msm_audio_mvs_config config; - - MM_DBG("GET_MVS_CONFIG mvs_mode %d rate_type %d\n", - config.mvs_mode, config.rate_type); - - mutex_lock(&audio->lock); - config.mvs_mode = audio->mvs_mode; - config.rate_type = audio->rate_type; - mutex_unlock(&audio->lock); - - rc = copy_to_user((void *)arg, &config, sizeof(config)); - if (rc == 0) - rc = sizeof(config); - else - MM_ERR("Config copy failed %d\n", rc); - - break; - } - - case AUDIO_SET_MVS_CONFIG: { - struct msm_audio_mvs_config config; - - MM_DBG("IOCTL SET_MVS_CONFIG\n"); - - rc = copy_from_user(&config, (void *)arg, sizeof(config)); - if (rc == 0) { - mutex_lock(&audio->lock); - - if (audio->state == AUDIO_MVS_OPENED) { - audio->mvs_mode = config.mvs_mode; - audio->rate_type = config.rate_type; - audio->dtx_mode = config.dtx_mode; - } else { - MM_ERR("Set confg called in state %d\n", - audio->state); - - rc = -EPERM; - } - - mutex_unlock(&audio->lock); - } else { - MM_ERR("Config copy failed %d\n", rc); - } - - break; - } - - case AUDIO_START: { - MM_DBG("IOCTL START\n"); - - mutex_lock(&audio->lock); - - if (audio->state == AUDIO_MVS_OPENED || - audio->state == AUDIO_MVS_STOPPED) { - rc = audio_mvs_start(audio); - if (rc != 0) - audio_mvs_stop(audio); - } else { - MM_ERR("Start called in invalid state %d\n", - audio->state); - - rc = -EPERM; - } - - mutex_unlock(&audio->lock); - - break; - } - - case AUDIO_STOP: { - MM_DBG("IOCTL STOP\n"); - - mutex_lock(&audio->lock); - - if (audio->state == AUDIO_MVS_STARTED) { - rc = audio_mvs_stop(audio); - } else { - MM_ERR("Stop called in invalid state %d\n", - audio->state); - - rc = -EPERM; - } - - mutex_unlock(&audio->lock); - break; - } - - default: { - MM_ERR("Unknown IOCTL %d\n", cmd); - } - } - - return rc; -} - -static int audio_mvs_open(struct inode *inode, struct file *file) -{ - int rc = 0; - - MM_DBG("\n"); - - memset(&audio_mvs_info, 0, sizeof(audio_mvs_info)); - mutex_init(&audio_mvs_info.lock); - mutex_init(&audio_mvs_info.in_lock); - mutex_init(&audio_mvs_info.out_lock); - - init_waitqueue_head(&audio_mvs_info.wait); - init_waitqueue_head(&audio_mvs_info.mode_wait); - init_waitqueue_head(&audio_mvs_info.out_wait); - - INIT_LIST_HEAD(&audio_mvs_info.in_queue); - INIT_LIST_HEAD(&audio_mvs_info.free_in_queue); - INIT_LIST_HEAD(&audio_mvs_info.out_queue); - INIT_LIST_HEAD(&audio_mvs_info.free_out_queue); - - wake_lock_init(&audio_mvs_info.suspend_lock, - WAKE_LOCK_SUSPEND, - "audio_mvs_suspend"); - pm_qos_add_request(&audio_mvs_info.pm_qos_req, PM_QOS_CPU_DMA_LATENCY, - PM_QOS_DEFAULT_VALUE); - - audio_mvs_info.rpc_endpt = msm_rpc_connect_compatible(MVS_PROG, - MVS_VERS_COMP_VER2, - MSM_RPC_UNINTERRUPTIBLE); - - if (IS_ERR(audio_mvs_info.rpc_endpt)) { - MM_ERR("MVS RPC connect failed ver 0x%x\n", - MVS_VERS_COMP_VER2); - audio_mvs_info.rpc_endpt = msm_rpc_connect_compatible(MVS_PROG, - MVS_VERS_COMP_VER3, - MSM_RPC_UNINTERRUPTIBLE); - if (IS_ERR(audio_mvs_info.rpc_endpt)) { - MM_ERR("MVS RPC connect failed ver 0x%x\n", - MVS_VERS_COMP_VER3); - } else { - MM_DBG("MVS RPC connect succeeded ver 0x%x\n", - MVS_VERS_COMP_VER3); - audio_mvs_info.rpc_prog = MVS_PROG; - audio_mvs_info.rpc_ver = MVS_VERS_COMP_VER3; - } - } else { - MM_DBG("MVS RPC connect succeeded ver 0x%x\n", - MVS_VERS_COMP_VER2); - audio_mvs_info.rpc_prog = MVS_PROG; - audio_mvs_info.rpc_ver = MVS_VERS_COMP_VER2; - } - audio_mvs_info.task = kthread_run(audio_mvs_thread, - &audio_mvs_info, - "audio_mvs"); - if (IS_ERR(audio_mvs_info.task)) { - MM_ERR("MVS thread create failed\n"); - rc = PTR_ERR(audio_mvs_info.task); - audio_mvs_info.task = NULL; - msm_rpc_close(audio_mvs_info.rpc_endpt); - audio_mvs_info.rpc_endpt = NULL; - goto done; - } - - mutex_lock(&audio_mvs_info.lock); - - if (audio_mvs_info.state == AUDIO_MVS_CLOSED) { - - if (audio_mvs_info.task != NULL || - audio_mvs_info.rpc_endpt != NULL) { - rc = audio_mvs_alloc_buf(&audio_mvs_info); - - if (rc == 0) { - audio_mvs_info.state = AUDIO_MVS_OPENED; - file->private_data = &audio_mvs_info; - } - } else { - MM_ERR("MVS thread and RPC end point do not exist\n"); - - rc = -ENODEV; - } - } else { - MM_ERR("MVS driver exists, state %d\n", - audio_mvs_info.state); - - rc = -EBUSY; - } - - mutex_unlock(&audio_mvs_info.lock); - -done: - return rc; -} - -static const struct file_operations audio_mvs_fops = { - .owner = THIS_MODULE, - .open = audio_mvs_open, - .release = audio_mvs_release, - .read = audio_mvs_read, - .write = audio_mvs_write, - .unlocked_ioctl = audio_mvs_ioctl -}; - -struct miscdevice audio_mvs_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_mvs", - .fops = &audio_mvs_fops -}; -static int __init audio_mvs_init(void) -{ - return misc_register(&audio_mvs_misc); -} - -static void __exit audio_mvs_exit(void) -{ - MM_DBG("\n"); - - misc_deregister(&audio_mvs_misc); -} - -module_init(audio_mvs_init); -module_exit(audio_mvs_exit); - -MODULE_DESCRIPTION("MSM MVS driver"); -MODULE_LICENSE("GPL v2"); - diff --git a/arch/arm/mach-msm/qdsp5/audio_out.c b/arch/arm/mach-msm/qdsp5/audio_out.c deleted file mode 100644 index 9e9d89bff73fad9360b4b27d3133527de8e19195..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_out.c +++ /dev/null @@ -1,1158 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/audio_out.c - * - * pcm audio output device - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2012 The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include "audmgr.h" - -#include -#include - -#include -#include - -#include "evlog.h" - -#define LOG_AUDIO_EVENTS 1 -#define LOG_AUDIO_FAULTS 0 - -#define SRS_ID_GLOBAL 0x00000001 -#define SRS_ID_WOWHD 0x00000002 -#define SRS_ID_CSHP 0x00000003 -#define SRS_ID_HPF 0x00000004 -#define SRS_ID_PEQ 0x00000005 -#define SRS_ID_HL 0x00000006 - -#define SRS_MASK_G 1 -#define SRS_MASK_W 2 -#define SRS_MASK_C 4 -#define SRS_MASK_HP 8 -#define SRS_MASK_P 16 -#define SRS_MASK_HL 32 - - -enum { - EV_NULL, - EV_OPEN, - EV_WRITE, - EV_RETURN, - EV_IOCTL, - EV_WRITE_WAIT, - EV_WAIT_EVENT, - EV_FILL_BUFFER, - EV_SEND_BUFFER, - EV_DSP_EVENT, - EV_ENABLE, -}; - -#if (LOG_AUDIO_EVENTS != 1) -static inline void LOG(unsigned id, unsigned arg) {} -#else -static const char *pcm_log_strings[] = { - "NULL", - "OPEN", - "WRITE", - "RETURN", - "IOCTL", - "WRITE_WAIT", - "WAIT_EVENT", - "FILL_BUFFER", - "SEND_BUFFER", - "DSP_EVENT", - "ENABLE", -}; - -DECLARE_LOG(pcm_log, 64, pcm_log_strings); - -static int __init _pcm_log_init(void) -{ - return ev_log_init(&pcm_log); -} -module_init(_pcm_log_init); - -#define LOG(id,arg) ev_log_write(&pcm_log, id, arg) -#endif - - - - - -#define BUFSZ (5248) -#define DMASZ (BUFSZ * 2) - -#define COMMON_OBJ_ID 6 - -struct buffer { - void *data; - unsigned size; - unsigned used; - unsigned addr; -}; - -struct audio { - struct buffer out[2]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t wait; - - /* configuration to use on next enable */ - uint32_t out_sample_rate; - uint32_t out_channel_mode; - uint32_t out_weight; - uint32_t out_buffer_size; - - struct audmgr audmgr; - - /* data allocated for various buffers */ - char *data; - dma_addr_t phys; - - int teos; /* valid only if tunnel mode & no data left for decoder */ - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - - struct wake_lock wakelock; - struct pm_qos_request pm_qos_req; - - audpp_cmd_cfg_object_params_volume vol_pan; -}; - -struct audio_copp { - int mbadrc_enable; - int mbadrc_needs_commit; - char *mbadrc_data; - dma_addr_t mbadrc_phys; - - audpp_cmd_cfg_object_params_mbadrc mbadrc; - - int eq_enable; - int eq_needs_commit; - audpp_cmd_cfg_object_params_eqalizer eq; - - int rx_iir_enable; - int rx_iir_needs_commit; - audpp_cmd_cfg_object_params_pcm iir; - - audpp_cmd_cfg_object_params_volume vol_pan; - - int qconcert_plus_enable; - int qconcert_plus_needs_commit; - - int srs_enable; - int srs_needs_commit; - int srs_feature_mask; - audpp_cmd_cfg_object_params_qconcert qconcert_plus; - - int status; - int opened; - struct mutex lock; - - struct audpp_event_callback ecb; - - struct audpp_cmd_cfg_object_params_srstm_g g; - struct audpp_cmd_cfg_object_params_srstm_w w; - struct audpp_cmd_cfg_object_params_srstm_c c; - struct audpp_cmd_cfg_object_params_srstm_h h; - struct audpp_cmd_cfg_object_params_srstm_p p; - struct audpp_cmd_cfg_object_params_srstm_l l; -} the_audio_copp; - -static void audio_prevent_sleep(struct audio *audio) -{ - MM_DBG("\n"); /* Macro prints the file name and function */ - wake_lock(&audio->wakelock); - pm_qos_update_request(&audio->pm_qos_req, - msm_cpuidle_get_deep_idle_latency()); -} - -static void audio_allow_sleep(struct audio *audio) -{ - pm_qos_update_request(&audio->pm_qos_req, PM_QOS_DEFAULT_VALUE); - wake_unlock(&audio->wakelock); - MM_DBG("\n"); /* Macro prints the file name and function */ -} - -static int audio_dsp_out_enable(struct audio *audio, int yes); -static int audio_dsp_send_buffer(struct audio *audio, unsigned id, unsigned len); - -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg); -static int audio_enable_srs_trumedia(struct audio_copp *audio_copp, int enable); -/* must be called with audio->lock held */ -static int audio_enable(struct audio *audio) -{ - struct audmgr_config cfg; - int rc; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (audio->enabled) - return 0; - - /* refuse to start if we're not ready */ - if (!audio->out[0].used || !audio->out[1].used) - return -EIO; - - /* we start buffers 0 and 1, so buffer 0 will be the - * next one the dsp will want - */ - audio->out_tail = 0; - audio->out_needed = 0; - - cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; - cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000; - cfg.def_method = RPC_AUD_DEF_METHOD_HOST_PCM; - cfg.codec = RPC_AUD_DEF_CODEC_PCM; - cfg.snd_method = RPC_SND_METHOD_MIDI; - - audio_prevent_sleep(audio); - rc = audmgr_enable(&audio->audmgr, &cfg); - if (rc < 0) { - audio_allow_sleep(audio); - return rc; - } - - if (audpp_enable(-1, audio_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - audmgr_disable(&audio->audmgr); - audio_allow_sleep(audio); - return -ENODEV; - } - - audio->enabled = 1; - htc_pwrsink_set(PWRSINK_AUDIO, 100); - return 0; -} - -/* must be called with audio->lock held */ -static int audio_disable(struct audio *audio) -{ - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audio_dsp_out_enable(audio, 0); - - audpp_disable(-1, audio); - - audio->stopped = 1; - wake_up(&audio->wait); - audmgr_disable(&audio->audmgr); - audio->out_needed = 0; - audio_allow_sleep(audio); - } - return 0; -} - -void audio_commit_pending_pp_params(void *priv, unsigned id, uint16_t *msg) -{ - struct audio_copp *audio_copp = priv; - - if (AUDPP_MSG_CFG_MSG == id && msg[0] == AUDPP_MSG_ENA_DIS) - return; - - if (!audio_copp->status) - return; - - audpp_dsp_set_mbadrc(COMMON_OBJ_ID, audio_copp->mbadrc_enable, - &audio_copp->mbadrc); - - audpp_dsp_set_eq(COMMON_OBJ_ID, audio_copp->eq_enable, - &audio_copp->eq); - - audpp_dsp_set_rx_iir(COMMON_OBJ_ID, audio_copp->rx_iir_enable, - &audio_copp->iir); - audpp_dsp_set_vol_pan(COMMON_OBJ_ID, &audio_copp->vol_pan); - - audpp_dsp_set_qconcert_plus(COMMON_OBJ_ID, - audio_copp->qconcert_plus_enable, - &audio_copp->qconcert_plus); - audio_enable_srs_trumedia(audio_copp, true); -} -EXPORT_SYMBOL(audio_commit_pending_pp_params); - -/* ------------------- dsp --------------------- */ -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - struct buffer *frame; - unsigned long flags; - - LOG(EV_DSP_EVENT, id); - switch (id) { - case AUDPP_MSG_HOST_PCM_INTF_MSG: { - unsigned id = msg[2]; - unsigned idx = msg[3] - 1; - - /* MM_INFO("HOST_PCM id %d idx %d\n", id, idx); */ - if (id != AUDPP_MSG_HOSTPCM_ID_ARM_RX) { - MM_ERR("bogus id\n"); - break; - } - if (idx > 1) { - MM_ERR("bogus buffer idx\n"); - break; - } - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (audio->running) { - atomic_add(audio->out[idx].used, &audio->out_bytes); - audio->out[idx].used = 0; - - frame = audio->out + audio->out_tail; - if (frame->used) { - audio_dsp_send_buffer( - audio, audio->out_tail, frame->used); - audio->out_tail ^= 1; - } else { - audio->out_needed++; - } - wake_up(&audio->wait); - } - spin_unlock_irqrestore(&audio->dsp_lock, flags); - break; - } - case AUDPP_MSG_PCMDMAMISSED: - MM_INFO("PCMDMAMISSED %d\n", msg[0]); - audio->teos = 1; - wake_up(&audio->wait); - break; - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - LOG(EV_ENABLE, 1); - MM_DBG("CFG_MSG ENABLE\n"); - audio->out_needed = 0; - audio->running = 1; - audpp_dsp_set_vol_pan(5, &audio->vol_pan); - audio_dsp_out_enable(audio, 1); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - LOG(EV_ENABLE, 0); - MM_DBG("CFG_MSG DISABLE\n"); - audio->running = 0; - } else { - MM_ERR("CFG_MSG %d?\n", msg[0]); - } - break; - default: - MM_ERR("UNKNOWN (%d)\n", id); - } -} - -static int audio_dsp_out_enable(struct audio *audio, int yes) -{ - audpp_cmd_pcm_intf cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_PCM_INTF_2; - cmd.object_num = AUDPP_CMD_PCM_INTF_OBJECT_NUM; - cmd.config = AUDPP_CMD_PCM_INTF_CONFIG_CMD_V; - cmd.intf_type = AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V; - - if (yes) { - cmd.write_buf1LSW = audio->out[0].addr; - cmd.write_buf1MSW = audio->out[0].addr >> 16; - if (audio->out[0].used) - cmd.write_buf1_len = audio->out[0].used; - else - cmd.write_buf1_len = audio->out[0].size; - cmd.write_buf2LSW = audio->out[1].addr; - cmd.write_buf2MSW = audio->out[1].addr >> 16; - if (audio->out[1].used) - cmd.write_buf2_len = audio->out[1].used; - else - cmd.write_buf2_len = audio->out[1].size; - cmd.arm_to_rx_flag = AUDPP_CMD_PCM_INTF_ENA_V; - cmd.weight_decoder_to_rx = audio->out_weight; - cmd.weight_arm_to_rx = 1; - cmd.partition_number_arm_to_dsp = 0; - cmd.sample_rate = audio->out_sample_rate; - cmd.channel_mode = audio->out_channel_mode; - } - - return audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static int audio_dsp_send_buffer(struct audio *audio, unsigned idx, unsigned len) -{ - audpp_cmd_pcm_intf_send_buffer cmd; - - cmd.cmd_id = AUDPP_CMD_PCM_INTF_2; - cmd.host_pcm_object = AUDPP_CMD_PCM_INTF_OBJECT_NUM; - cmd.config = AUDPP_CMD_PCM_INTF_BUFFER_CMD_V; - cmd.intf_type = AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V; - cmd.dsp_to_arm_buf_id = 0; - cmd.arm_to_dsp_buf_id = idx + 1; - cmd.arm_to_dsp_buf_len = len; - - LOG(EV_SEND_BUFFER, idx); - dma_coherent_pre_ops(); - return audpp_send_queue2(&cmd, sizeof(cmd)); -} - -/* ------------------- device --------------------- */ - -static int audio_enable_mbadrc(struct audio_copp *audio_copp, int enable) -{ - if (audio_copp->mbadrc_enable == enable && - !audio_copp->mbadrc_needs_commit) - return 0; - - audio_copp->mbadrc_enable = enable; - if (is_audpp_enable()) { - audpp_dsp_set_mbadrc(COMMON_OBJ_ID, enable, - &audio_copp->mbadrc); - audio_copp->mbadrc_needs_commit = 0; - } - - return 0; -} - -static int audio_enable_eq(struct audio_copp *audio_copp, int enable) -{ - if (audio_copp->eq_enable == enable && - !audio_copp->eq_needs_commit) - return 0; - - audio_copp->eq_enable = enable; - - if (is_audpp_enable()) { - audpp_dsp_set_eq(COMMON_OBJ_ID, enable, &audio_copp->eq); - audio_copp->eq_needs_commit = 0; - } - return 0; -} - -static int audio_enable_rx_iir(struct audio_copp *audio_copp, int enable) -{ - if (audio_copp->rx_iir_enable == enable && - !audio_copp->rx_iir_needs_commit) - return 0; - - audio_copp->rx_iir_enable = enable; - - if (is_audpp_enable()) { - audpp_dsp_set_rx_iir(COMMON_OBJ_ID, enable, &audio_copp->iir); - audio_copp->rx_iir_needs_commit = 0; - } - return 0; -} - -static int audio_enable_srs_trumedia(struct audio_copp *audio_copp, int enable) -{ - - if (!audio_copp->srs_needs_commit) - return 0; - - audio_copp->srs_enable = enable; - - MM_DBG("Enable SRS flags 0x%x enable %d\n", - audio_copp->srs_feature_mask, enable); - if (is_audpp_enable()) { - MM_DBG("Updating audpp for srs\n"); - if (audio_copp->srs_feature_mask & SRS_MASK_W) - audpp_dsp_set_rx_srs_trumedia_w(&audio_copp->w); - if (audio_copp->srs_feature_mask & SRS_MASK_C) - audpp_dsp_set_rx_srs_trumedia_c(&audio_copp->c); - if (audio_copp->srs_feature_mask & SRS_MASK_HP) - audpp_dsp_set_rx_srs_trumedia_h(&audio_copp->h); - if (audio_copp->srs_feature_mask & SRS_MASK_P) - audpp_dsp_set_rx_srs_trumedia_p(&audio_copp->p); - if (audio_copp->srs_feature_mask & SRS_MASK_HL) - audpp_dsp_set_rx_srs_trumedia_l(&audio_copp->l); - if (audio_copp->srs_feature_mask & SRS_MASK_G) - audpp_dsp_set_rx_srs_trumedia_g(&audio_copp->g); - - audio_copp->srs_needs_commit = 0; - audio_copp->srs_feature_mask = 0; - } - return 0; -} - -static int audio_enable_vol_pan(struct audio_copp *audio_copp) -{ - if (is_audpp_enable()) - audpp_dsp_set_vol_pan(COMMON_OBJ_ID, &audio_copp->vol_pan); - return 0; -} - -static int audio_enable_qconcert_plus(struct audio_copp *audio_copp, int enable) -{ - if (audio_copp->qconcert_plus_enable == enable && - !audio_copp->qconcert_plus_needs_commit) - return 0; - - audio_copp->qconcert_plus_enable = enable; - - if (is_audpp_enable()) { - audpp_dsp_set_qconcert_plus(COMMON_OBJ_ID, enable, - &audio_copp->qconcert_plus); - audio_copp->qconcert_plus_needs_commit = 0; - } - return 0; -} - -static void audio_flush(struct audio *audio) -{ - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->stopped = 0; -} - -static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - unsigned long flags = 0; - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = atomic_read(&audio->out_bytes); - if (copy_to_user((void*) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - switch (cmd) { - case AUDIO_SET_VOLUME: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.volume = arg; - if (audio->running) - audpp_dsp_set_vol_pan(5, &audio->vol_pan); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - return 0; - - case AUDIO_SET_PAN: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.pan = arg; - if (audio->running) - audpp_dsp_set_vol_pan(5, &audio->vol_pan); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - return 0; - } - - LOG(EV_IOCTL, cmd); - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - rc = audio_enable(audio); - break; - case AUDIO_STOP: - rc = audio_disable(audio); - break; - case AUDIO_FLUSH: - if (audio->stopped) { - /* Make sure we're stopped and we wake any threads - * that might be blocked holding the write_lock. - * While audio->stopped write threads will always - * exit immediately. - */ - wake_up(&audio->wait); - mutex_lock(&audio->write_lock); - audio_flush(audio); - mutex_unlock(&audio->write_lock); - } - break; - case AUDIO_SET_CONFIG: { - struct msm_audio_config config; - if (copy_from_user(&config, (void*) arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.channel_count == 1) { - config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V; - } else if (config.channel_count == 2) { - config.channel_count= AUDPP_CMD_PCM_INTF_STEREO_V; - } else { - rc = -EINVAL; - break; - } - audio->out_sample_rate = config.sample_rate; - audio->out_channel_mode = config.channel_count; - rc = 0; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config config; - config.buffer_size = BUFSZ; - config.buffer_count = 2; - config.sample_rate = audio->out_sample_rate; - if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) { - config.channel_count = 1; - } else { - config.channel_count = 2; - } - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void*) arg, &config, sizeof(config))) { - rc = -EFAULT; - } else { - rc = 0; - } - break; - } - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -static int audio_fsync(struct file *file, loff_t a, loff_t b, int datasync) -{ - struct audio *audio = file->private_data; - int rc = 0; - - if (!audio->running) - return -EINVAL; - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->wait, - (!audio->out[0].used && - !audio->out[1].used)); - - if (rc < 0) - goto done; - - /* pcm dmamiss message is sent continously when - * decoder is starved so no race condition concern - */ - - audio->teos = 0; - - rc = wait_event_interruptible(audio->wait, - audio->teos); - -done: - mutex_unlock(&audio->write_lock); - return rc; -} - -static ssize_t audio_read(struct file *file, char __user *buf, size_t count, loff_t *pos) -{ - return -EINVAL; -} - -static inline int rt_policy(int policy) -{ - if (unlikely(policy == SCHED_FIFO) || unlikely(policy == SCHED_RR)) - return 1; - return 0; -} - -static inline int task_has_rt_policy(struct task_struct *p) -{ - return rt_policy(p->policy); -} - -static ssize_t audio_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct sched_param s = { .sched_priority = 1 }; - struct audio *audio = file->private_data; - unsigned long flags; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - int old_prio = current->rt_priority; - int old_policy = current->policy; - int cap_nice = cap_raised(current_cap(), CAP_SYS_NICE); - int rc = 0; - - LOG(EV_WRITE, count | (audio->running << 28) | (audio->stopped << 24)); - - /* just for this write, set us real-time */ - if (!task_has_rt_policy(current)) { - struct cred *new = prepare_creds(); - cap_raise(new->cap_effective, CAP_SYS_NICE); - commit_creds(new); - if ((sched_setscheduler(current, SCHED_RR, &s)) < 0) - MM_ERR("sched_setscheduler failed\n"); - } - - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - - LOG(EV_WAIT_EVENT, 0); - rc = wait_event_interruptible(audio->wait, - (frame->used == 0) || (audio->stopped)); - LOG(EV_WAIT_EVENT, 1); - - if (rc < 0) - break; - if (audio->stopped) { - rc = -EBUSY; - break; - } - xfer = count > frame->size ? frame->size : count; - if (copy_from_user(frame->data, buf, xfer)) { - rc = -EFAULT; - break; - } - frame->used = xfer; - audio->out_head ^= 1; - count -= xfer; - buf += xfer; - - spin_lock_irqsave(&audio->dsp_lock, flags); - LOG(EV_FILL_BUFFER, audio->out_head ^ 1); - frame = audio->out + audio->out_tail; - if (frame->used && audio->out_needed) { - audio_dsp_send_buffer(audio, audio->out_tail, frame->used); - audio->out_tail ^= 1; - audio->out_needed--; - } - spin_unlock_irqrestore(&audio->dsp_lock, flags); - } - - mutex_unlock(&audio->write_lock); - - /* restore scheduling policy and priority */ - if (!rt_policy(old_policy)) { - struct sched_param v = { .sched_priority = old_prio }; - if ((sched_setscheduler(current, old_policy, &v)) < 0) - MM_ERR("sched_setscheduler failed\n"); - if (likely(!cap_nice)) { - struct cred *new = prepare_creds(); - cap_lower(new->cap_effective, CAP_SYS_NICE); - commit_creds(new); - } - } - - LOG(EV_RETURN,(buf > start) ? (buf - start) : rc); - if (buf > start) - return buf - start; - return rc; -} - -static int audio_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - LOG(EV_OPEN, 0); - mutex_lock(&audio->lock); - audio_disable(audio); - audio_flush(audio); - audio->opened = 0; - mutex_unlock(&audio->lock); - htc_pwrsink_set(PWRSINK_AUDIO, 0); - return 0; -} - -struct audio the_audio; - -static int audio_open(struct inode *inode, struct file *file) -{ - struct audio *audio = &the_audio; - int rc; - - mutex_lock(&audio->lock); - - if (audio->opened) { - MM_ERR("busy\n"); - rc = -EBUSY; - goto done; - } - - if (!audio->data) { - audio->data = dma_alloc_coherent(NULL, DMASZ, - &audio->phys, GFP_KERNEL); - if (!audio->data) { - MM_ERR("could not allocate DMA buffers\n"); - rc = -ENOMEM; - goto done; - } - } - - rc = audmgr_open(&audio->audmgr); - if (rc) - goto done; - - audio->out_buffer_size = BUFSZ; - audio->out_sample_rate = 48000; - audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V; - audio->out_weight = 100; - - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = BUFSZ; - - audio->out[1].data = audio->data + BUFSZ; - audio->out[1].addr = audio->phys + BUFSZ; - audio->out[1].size = BUFSZ; - - audio->vol_pan.volume = 0x2000; - audio->vol_pan.pan = 0x0; - - audio_flush(audio); - - file->private_data = audio; - audio->opened = 1; - rc = 0; - LOG(EV_OPEN, 1); -done: - mutex_unlock(&audio->lock); - return rc; -} - -static long audpp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct audio_copp *audio_copp = file->private_data; - int rc = 0, enable; - uint16_t enable_mask; - int prev_state; - uint32_t to_set, size = 0; - void *tmpbuf, *srs_params = NULL; - - mutex_lock(&audio_copp->lock); - switch (cmd) { - case AUDIO_ENABLE_AUDPP: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - enable = ((enable_mask & ADRC_ENABLE) || - (enable_mask & MBADRC_ENABLE)) ? 1 : 0; - audio_enable_mbadrc(audio_copp, enable); - enable = (enable_mask & EQ_ENABLE) ? 1 : 0; - audio_enable_eq(audio_copp, enable); - enable = (enable_mask & IIR_ENABLE) ? 1 : 0; - audio_enable_rx_iir(audio_copp, enable); - enable = (enable_mask & QCONCERT_PLUS_ENABLE) ? 1 : 0; - audio_enable_qconcert_plus(audio_copp, enable); - enable = (enable_mask & SRS_ENABLE) ? 1 : 0; - audio_enable_srs_trumedia(audio_copp, enable); - break; - - case AUDIO_SET_MBADRC: { - uint32_t mbadrc_coeff_buf; - prev_state = audio_copp->mbadrc_enable; - audio_copp->mbadrc_enable = 0; - if (copy_from_user(&audio_copp->mbadrc.num_bands, (void *) arg, - sizeof(audio_copp->mbadrc) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) - rc = -EFAULT; - else if (audio_copp->mbadrc.ext_buf_size) { - mbadrc_coeff_buf = (uint32_t) ((char *) arg + - sizeof(audio_copp->mbadrc) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2)); - if ((copy_from_user(audio_copp->mbadrc_data, - (void *) mbadrc_coeff_buf, - AUDPP_MBADRC_EXTERNAL_BUF_SIZE * 2))) { - rc = -EFAULT; - break; - } - audio_copp->mbadrc.ext_buf_lsw = - audio_copp->mbadrc_phys & 0xFFFF; - audio_copp->mbadrc.ext_buf_msw = - ((audio_copp->mbadrc_phys & 0xFFFF0000) >> 16); - } - audio_copp->mbadrc_enable = prev_state; - if (!rc) - audio_copp->mbadrc_needs_commit = 1; - break; - } - - case AUDIO_SET_ADRC: { - struct audpp_cmd_cfg_object_params_adrc adrc; - prev_state = audio_copp->mbadrc_enable; - audio_copp->mbadrc_enable = 0; - if (copy_from_user(&adrc.compression_th, (void *) arg, - sizeof(adrc) - 2)) { - rc = -EFAULT; - audio_copp->mbadrc_enable = prev_state; - break; - } - audio_copp->mbadrc.num_bands = 1; - audio_copp->mbadrc.down_samp_level = 8; - audio_copp->mbadrc.adrc_delay = adrc.adrc_delay; - audio_copp->mbadrc.ext_buf_size = 0; - audio_copp->mbadrc.ext_partition = 0; - audio_copp->mbadrc.adrc_band[0].subband_enable = 1; - audio_copp->mbadrc.adrc_band[0].adrc_sub_mute = 0; - audio_copp->mbadrc.adrc_band[0].rms_time = - adrc.rms_time; - audio_copp->mbadrc.adrc_band[0].compression_th = - adrc.compression_th; - audio_copp->mbadrc.adrc_band[0].compression_slope = - adrc.compression_slope; - audio_copp->mbadrc.adrc_band[0].attack_const_lsw = - adrc.attack_const_lsw; - audio_copp->mbadrc.adrc_band[0].attack_const_msw = - adrc.attack_const_msw; - audio_copp->mbadrc.adrc_band[0].release_const_lsw = - adrc.release_const_lsw; - audio_copp->mbadrc.adrc_band[0].release_const_msw = - adrc.release_const_msw; - audio_copp->mbadrc.adrc_band[0].makeup_gain = 0x2000; - audio_copp->mbadrc_enable = prev_state; - audio_copp->mbadrc_needs_commit = 1; - break; - } - - case AUDIO_SET_EQ: - prev_state = audio_copp->eq_enable; - audio_copp->eq_enable = 0; - if (copy_from_user(&audio_copp->eq.num_bands, (void *) arg, - sizeof(audio_copp->eq) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) - rc = -EFAULT; - audio_copp->eq_enable = prev_state; - audio_copp->eq_needs_commit = 1; - break; - - case AUDIO_SET_RX_IIR: - prev_state = audio_copp->rx_iir_enable; - audio_copp->rx_iir_enable = 0; - if (copy_from_user(&audio_copp->iir.num_bands, (void *) arg, - sizeof(audio_copp->iir) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) - rc = -EFAULT; - audio_copp->rx_iir_enable = prev_state; - audio_copp->rx_iir_needs_commit = 1; - break; - - case AUDIO_SET_VOLUME: - audio_copp->vol_pan.volume = arg; - audio_enable_vol_pan(audio_copp); - break; - - case AUDIO_SET_PAN: - audio_copp->vol_pan.pan = arg; - audio_enable_vol_pan(audio_copp); - break; - - case AUDIO_SET_QCONCERT_PLUS: - prev_state = audio_copp->qconcert_plus_enable; - audio_copp->qconcert_plus_enable = 0; - if (copy_from_user(&audio_copp->qconcert_plus.op_mode, - (void *) arg, - sizeof(audio_copp->qconcert_plus) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) - rc = -EFAULT; - audio_copp->qconcert_plus_enable = prev_state; - audio_copp->qconcert_plus_needs_commit = 1; - break; - - case AUDIO_SET_SRS_TRUMEDIA_PARAM: { - prev_state = audio_copp->srs_enable; - audio_copp->srs_enable = 0; - - if (copy_from_user(&to_set, (void *)arg, sizeof(uint32_t))) { - rc = -EFAULT; - break; - } - switch (to_set) { - case SRS_ID_GLOBAL: - srs_params = (void *)audio_copp->g.v; - size = sizeof(audio_copp->g.v); - audio_copp->srs_feature_mask |= SRS_MASK_G; - break; - case SRS_ID_WOWHD: - srs_params = (void *)audio_copp->w.v; - size = sizeof(audio_copp->w.v); - audio_copp->srs_feature_mask |= SRS_MASK_W; - break; - case SRS_ID_CSHP: - srs_params = (void *)audio_copp->c.v; - size = sizeof(audio_copp->c.v); - audio_copp->srs_feature_mask |= SRS_MASK_C; - break; - case SRS_ID_HPF: - srs_params = (void *)audio_copp->h.v; - size = sizeof(audio_copp->h.v); - audio_copp->srs_feature_mask |= SRS_MASK_HP; - break; - case SRS_ID_PEQ: - srs_params = (void *)audio_copp->p.v; - size = sizeof(audio_copp->p.v); - audio_copp->srs_feature_mask |= SRS_MASK_P; - break; - case SRS_ID_HL: - srs_params = (void *)audio_copp->l.v; - size = sizeof(audio_copp->l.v); - audio_copp->srs_feature_mask |= SRS_MASK_HL; - break; - default: - MM_ERR("SRS TruMedia error: invalid ioctl\n"); - rc = -EINVAL; - } - - if (rc >= 0) { - tmpbuf = kzalloc(sizeof(uint32_t) + size , GFP_KERNEL); - if (!tmpbuf) { - MM_ERR("SRS TruMedia error: no kernel mem\n"); - rc = -ENOMEM; - } else { - if (copy_from_user(tmpbuf, (void *)arg, - sizeof(uint32_t) + size)) - rc = -EFAULT; - memcpy(srs_params, - &(((uint32_t *)tmpbuf)[1]), size); - kfree(tmpbuf); - } - } - - MM_DBG("Ioctl SRS flags=0x%x\n", audio_copp->srs_feature_mask); - if (rc < 0) - MM_ERR("SRS TruMedia error setting params failed.\n"); - else{ - audio_copp->srs_needs_commit = 1; - audio_copp->srs_enable = prev_state; - } - break; - } - - default: - rc = -EINVAL; - } - - mutex_unlock(&audio_copp->lock); - return rc; -} - -static int audpp_open(struct inode *inode, struct file *file) -{ - struct audio_copp *audio_copp = &the_audio_copp; - int rc; - - mutex_lock(&audio_copp->lock); - if (audio_copp->opened) { - mutex_unlock(&audio_copp->lock); - return -EBUSY; - } - - audio_copp->opened = 1; - - if (!audio_copp->status) { - audio_copp->ecb.fn = audio_commit_pending_pp_params; - audio_copp->ecb.private = audio_copp; - rc = audpp_register_event_callback(&audio_copp->ecb); - if (rc) { - audio_copp->opened = 0; - mutex_unlock(&audio_copp->lock); - return rc; - } - audio_copp->mbadrc_data = dma_alloc_coherent(NULL, - AUDPP_MBADRC_EXTERNAL_BUF_SIZE * 2, - &audio_copp->mbadrc_phys, GFP_KERNEL); - if (!audio_copp->mbadrc_data) { - MM_ERR("could not allocate DMA buffers\n"); - audio_copp->opened = 0; - audpp_unregister_event_callback(&audio_copp->ecb); - mutex_unlock(&audio_copp->lock); - return -ENOMEM; - } - audio_copp->vol_pan.volume = 0x2000; - audio_copp->vol_pan.pan = 0x0; - audio_copp->status = 1; - } - - file->private_data = audio_copp; - mutex_unlock(&audio_copp->lock); - - return 0; -} - -static int audpp_release(struct inode *inode, struct file *file) -{ - struct audio_copp *audio_copp = &the_audio_copp; - - audio_copp->opened = 0; - - return 0; -} - -static struct file_operations audio_fops = { - .owner = THIS_MODULE, - .open = audio_open, - .release = audio_release, - .read = audio_read, - .write = audio_write, - .unlocked_ioctl = audio_ioctl, - .fsync = audio_fsync, -}; - -static struct file_operations audpp_fops = { - .owner = THIS_MODULE, - .open = audpp_open, - .release = audpp_release, - .unlocked_ioctl = audpp_ioctl, -}; - -struct miscdevice audio_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_pcm_out", - .fops = &audio_fops, -}; - -struct miscdevice audpp_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_pcm_ctl", - .fops = &audpp_fops, -}; - -static int __init audio_init(void) -{ - mutex_init(&the_audio.lock); - mutex_init(&the_audio.write_lock); - mutex_init(&the_audio_copp.lock); - spin_lock_init(&the_audio.dsp_lock); - init_waitqueue_head(&the_audio.wait); - wake_lock_init(&the_audio.wakelock, WAKE_LOCK_SUSPEND, "audio_pcm"); - pm_qos_add_request(&the_audio.pm_qos_req, PM_QOS_CPU_DMA_LATENCY, - PM_QOS_DEFAULT_VALUE); - return (misc_register(&audio_misc) || misc_register(&audpp_misc)); -} - -device_initcall(audio_init); diff --git a/arch/arm/mach-msm/qdsp5/audio_pcm.c b/arch/arm/mach-msm/qdsp5/audio_pcm.c deleted file mode 100644 index 554af098a591a50cb2ddce44b1e26f05821090aa..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_pcm.c +++ /dev/null @@ -1,1742 +0,0 @@ - -/* audio_pcm.c - pcm audio decoder driver - * - * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. - * - * Based on the mp3 decoder driver in arch/arm/mach-msm/qdsp5/audio_mp3.c - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * - * All source code in this file is licensed under the following license except - * where indicated. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "audmgr.h" - -/* for queue ids - should be relative to module number*/ -#include "adsp.h" - -#define ADRV_STATUS_AIO_INTF 0x00000001 -#define ADRV_STATUS_OBUF_GIVEN 0x00000002 -#define ADRV_STATUS_IBUF_GIVEN 0x00000004 -#define ADRV_STATUS_FSYNC 0x00000008 - -/* Size must be power of 2 */ -#define BUFSZ_MAX 32768 -#define BUFSZ_MIN 4096 -#define DMASZ_MAX (BUFSZ_MAX * 2) -#define DMASZ_MIN (BUFSZ_MIN * 2) - -#define AUDDEC_DEC_PCM 0 - -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDPCM_EVENT_NUM 10 /* Default number of pre-allocated event packets */ - -#define __CONTAINS(r, v, l) ({ \ - typeof(r) __r = r; \ - typeof(v) __v = v; \ - typeof(v) __e = __v + l; \ - int res = ((__v >= __r->vaddr) && \ - (__e <= __r->vaddr + __r->len)); \ - res; \ -}) - -#define CONTAINS(r1, r2) ({ \ - typeof(r2) __r2 = r2; \ - __CONTAINS(r1, __r2->vaddr, __r2->len); \ -}) - -#define IN_RANGE(r, v) ({ \ - typeof(r) __r = r; \ - typeof(v) __vv = v; \ - int res = ((__vv >= __r->vaddr) && \ - (__vv < (__r->vaddr + __r->len))); \ - res; \ -}) - -#define OVERLAPS(r1, r2) ({ \ - typeof(r1) __r1 = r1; \ - typeof(r2) __r2 = r2; \ - typeof(__r2->vaddr) __v = __r2->vaddr; \ - typeof(__v) __e = __v + __r2->len - 1; \ - int res = (IN_RANGE(__r1, __v) || IN_RANGE(__r1, __e)); \ - res; \ -}) - -struct audio; - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audpcm_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct audpcm_event { - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audpcm_ion_region { - struct list_head list; - struct ion_handle *handle; - int fd; - void *vaddr; - unsigned long paddr; - unsigned long kvaddr; - unsigned long len; - unsigned ref_cnt; -}; - -struct audpcm_buffer_node { - struct list_head list; - struct msm_audio_aio_buf buf; - unsigned long paddr; -}; - -struct audpcm_drv_operations { - void (*send_data)(struct audio *, unsigned); - void (*out_flush)(struct audio *); - int (*fsync)(struct audio *); -}; - -struct audio { - struct buffer out[2]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - unsigned out_dma_sz; - struct list_head out_queue; /* queue to retain output buffers */ - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - struct msm_adsp_module *audplay; - - /* configuration to use on next enable */ - uint32_t out_sample_rate; - uint32_t out_channel_mode; - uint32_t out_bits; /* bits per sample */ - - struct audmgr audmgr; - - /* data allocated for various buffers */ - char *data; - int32_t phys; - void *map_v_write; - - uint32_t drv_status; - int wflush; /* Write flush */ - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - int teos; /* valid only if tunnel mode & no data left for decoder */ - int rmt_resource_released; - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - int reserved; /* A byte is being reserved */ - char rsv_byte; /* Handle odd length user data */ - - const char *module_name; - unsigned queue_id; - - unsigned volume; - - uint16_t dec_id; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audpcm_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - - struct list_head ion_region_queue; - struct audpcm_drv_operations drv_ops; - struct ion_client *client; - struct ion_handle *output_buff_handle; -}; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audpp_cmd_cfg_adec_params(struct audio *audio); -static void audplay_send_data(struct audio *audio, unsigned needed); -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg); -static void audpcm_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); -static unsigned long audpcm_ion_fixup(struct audio *audio, void *addr, - unsigned long len, int ref_up); - -static int rmt_put_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_DISABLE; - cmd.dec_type = AUDDEC_DEC_PCM; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - - return put_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -static int rmt_get_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_ENABLE; - cmd.dec_type = AUDDEC_DEC_PCM; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - - return get_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -/* must be called with audio->lock held */ -static int audio_enable(struct audio *audio) -{ - struct audmgr_config cfg; - int rc; - - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) - return 0; - - if (audio->rmt_resource_released == 1) { - audio->rmt_resource_released = 0; - rc = rmt_get_resource(audio); - if (rc) { - MM_ERR("ADSP resources are not available for PCM \ - session 0x%08x on decoder: %d\n Ignoring \ - error and going ahead with the playback\n", - (int)audio, audio->dec_id); - } - } - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_tail = 0; - audio->out_needed = 0; - - cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; - cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000; - cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK; - cfg.codec = RPC_AUD_DEF_CODEC_PCM; - cfg.snd_method = RPC_SND_METHOD_MIDI; - - rc = audmgr_enable(&audio->audmgr, &cfg); - if (rc < 0) - return rc; - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - - audio->enabled = 1; - return 0; -} - -/* must be called with audio->lock held */ -static int audio_disable(struct audio *audio) -{ - int rc = 0; - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - audio->stopped = 1; - wake_up(&audio->write_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - audmgr_disable(&audio->audmgr); - audio->out_needed = 0; - rmt_put_resource(audio); - audio->rmt_resource_released = 1; - } - return rc; -} - -/* ------------------- dsp --------------------- */ -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - getevent(msg, sizeof(msg)); - - MM_DBG("msg_id=%x\n", id); - - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audio->drv_ops.send_data(audio, 1); - break; - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audplaytask)\n"); - break; - default: - MM_ERR("unexpected message from decoder \n"); - break; - } -} - -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status: sleep reason = \ - 0x%04x\n", reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init\n"); - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg \n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play \n"); - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - default: - MM_ERR("unknown decoder status \n"); - break; - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - audpp_set_volume_and_pan(audio->dec_id, audio->volume, - 0); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audio->running = 0; - } else { - MM_ERR("CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - wake_up(&audio->write_wait); - break; - - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - - default: - MM_ERR("UNKNOWN (%d)\n", id); - } - -} - - -struct msm_adsp_ops audpcmdec_adsp_ops = { - .event = audplay_dsp_event, -}; - - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id, \ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - u16 cfg_dec_cmd[AUDPP_CMD_CFG_DEC_TYPE_LEN / sizeof(unsigned short)]; - - memset(cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - - cfg_dec_cmd[0] = AUDPP_CMD_CFG_DEC_TYPE; - if (enable) - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_PCM; - else - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} - -static void audpp_cmd_cfg_adec_params(struct audio *audio) -{ - audpp_cmd_cfg_adec_params_wav cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_WAV_LEN; - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = audio->out_sample_rate; - cmd.stereo_cfg = audio->out_channel_mode; - cmd.pcm_width = audio->out_bits; - cmd.sign = 0; - audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static int audplay_dsp_send_data_avail(struct audio *audio, - unsigned idx, unsigned len) -{ - audplay_cmd_bitstream_data_avail cmd; - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL; - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = audio->out[idx].addr; - cmd.buf_size = len/2; - cmd.partition_number = 0; - /* complete writes to the input buffer */ - wmb(); - return audplay_send_queue0(audio, &cmd, sizeof(cmd)); -} - -static void audpcm_async_send_data(struct audio *audio, unsigned needed) -{ - unsigned long flags; - - if (!audio->running) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - - if (needed && !audio->wflush) { - audio->out_needed = 1; - if (audio->drv_status & ADRV_STATUS_OBUF_GIVEN) { - /* pop one node out of queue */ - union msm_audio_event_payload payload; - struct audpcm_buffer_node *used_buf; - - MM_DBG("consumed\n"); - - BUG_ON(list_empty(&audio->out_queue)); - used_buf = list_first_entry(&audio->out_queue, - struct audpcm_buffer_node, list); - list_del(&used_buf->list); - payload.aio_buf = used_buf->buf; - audpcm_post_event(audio, AUDIO_EVENT_WRITE_DONE, - payload); - kfree(used_buf); - audio->drv_status &= ~ADRV_STATUS_OBUF_GIVEN; - } - } - if (audio->out_needed) { - struct audpcm_buffer_node *next_buf; - audplay_cmd_bitstream_data_avail cmd; - if (!list_empty(&audio->out_queue)) { - next_buf = list_first_entry(&audio->out_queue, - struct audpcm_buffer_node, list); - MM_DBG("next_buf %p\n", next_buf); - if (next_buf) { - MM_DBG("next buf phy %lx len %d\n", - next_buf->paddr, next_buf->buf.data_len); - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL; - if (next_buf->buf.data_len) - cmd.decoder_id = audio->dec_id; - else { - cmd.decoder_id = -1; - MM_DBG("input EOS signaled\n"); - } - cmd.buf_ptr = (unsigned) next_buf->paddr; - cmd.buf_size = next_buf->buf.data_len >> 1; - cmd.partition_number = 0; - /* complete writes to the input buffer */ - wmb(); - audplay_send_queue0(audio, &cmd, sizeof(cmd)); - audio->out_needed = 0; - audio->drv_status |= ADRV_STATUS_OBUF_GIVEN; - } - } - } - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audplay_send_data(struct audio *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - - if (!audio->running) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - MM_DBG("frame %d busy\n", audio->out_tail); - audplay_dsp_send_data_avail(audio, audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ -static void audpcm_async_flush(struct audio *audio) -{ - struct audpcm_buffer_node *buf_node; - struct list_head *ptr, *next; - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - list_for_each_safe(ptr, next, &audio->out_queue) { - buf_node = list_entry(ptr, struct audpcm_buffer_node, list); - list_del(&buf_node->list); - payload.aio_buf = buf_node->buf; - audpcm_post_event(audio, AUDIO_EVENT_WRITE_DONE, - payload); - kfree(buf_node); - } - audio->drv_status &= ~ADRV_STATUS_OBUF_GIVEN; - audio->out_needed = 0; - atomic_set(&audio->out_bytes, 0); -} - -static void audio_flush(struct audio *audio) -{ - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->reserved = 0; - audio->out_needed = 0; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - atomic_set(&audio->out_bytes, 0); -} - -static void audio_ioport_reset(struct audio *audio) -{ - if (audio->drv_status & ADRV_STATUS_AIO_INTF) { - /* If fsync is in progress, make sure - * return value of fsync indicates - * abort due to flush - */ - if (audio->drv_status & ADRV_STATUS_FSYNC) { - MM_DBG("fsync in progress\n"); - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audio->drv_ops.out_flush(audio); - mutex_unlock(&audio->write_lock); - } else - audio->drv_ops.out_flush(audio); - } else { - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audio->drv_ops.out_flush(audio); - mutex_unlock(&audio->write_lock); - } -} - -static int audpcm_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audpcm_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audpcm_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audpcm_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audpcm_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - -static long audpcm_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audpcm_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - audio->event_wait, audpcm_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audpcm_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audpcm_event, list); - list_del(&drv_evt->list); - } - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - if (drv_evt && drv_evt->event_type == AUDIO_EVENT_WRITE_DONE) { - mutex_lock(&audio->lock); - audpcm_ion_fixup(audio, drv_evt->payload.aio_buf.buf_addr, - drv_evt->payload.aio_buf.buf_len, 0); - mutex_unlock(&audio->lock); - } - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audpcm_ion_check(struct audio *audio, - void *vaddr, unsigned long len) -{ - struct audpcm_ion_region *region_elt; - struct audpcm_ion_region t = {.vaddr = vaddr, .len = len }; - - list_for_each_entry(region_elt, &audio->ion_region_queue, list) { - if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) || - OVERLAPS(region_elt, &t)) { - MM_ERR("[%p]:region (vaddr %p len %ld)" - " clashes with registered region" - " (vaddr %p paddr %p len %ld)\n", - audio, vaddr, len, - region_elt->vaddr, - (void *)region_elt->paddr, region_elt->len); - return -EINVAL; - } - } - - return 0; -} -static int audpcm_ion_add(struct audio *audio, - struct msm_audio_ion_info *info) -{ - ion_phys_addr_t paddr; - size_t len; - unsigned long kvaddr; - struct audpcm_ion_region *region; - int rc = -EINVAL; - struct ion_handle *handle; - unsigned long ionflag; - - MM_ERR("\n"); /* Macro prints the file name and function */ - region = kmalloc(sizeof(*region), GFP_KERNEL); - - if (!region) { - rc = -ENOMEM; - goto end; - } - handle = ion_import_dma_buf(audio->client, info->fd); - if (IS_ERR_OR_NULL(handle)) { - pr_err("%s: could not get handle of the given fd\n", __func__); - goto import_error; - } - rc = ion_handle_get_flags(audio->client, handle, &ionflag); - if (rc) { - pr_err("%s: could not get flags for the handle\n", __func__); - goto flag_error; - } - kvaddr = (unsigned long)ion_map_kernel(audio->client, handle); - if (IS_ERR_OR_NULL((void *)kvaddr)) { - pr_err("%s: could not get virtual address\n", __func__); - goto map_error; - } - rc = ion_phys(audio->client, handle, &paddr, &len); - if (rc) { - pr_err("%s: could not get physical address\n", __func__); - goto ion_error; - } - rc = audpcm_ion_check(audio, info->vaddr, len); - if (rc < 0) { - MM_ERR("audpcm_ion_check failed\n"); - goto ion_error; - } - region->handle = handle; - region->vaddr = info->vaddr; - region->fd = info->fd; - region->paddr = paddr; - region->kvaddr = kvaddr; - region->len = len; - region->ref_cnt = 0; - MM_DBG("[%p]:add region paddr %lx vaddr %p, len %lu kvaddr %lx\n", - audio, region->paddr, region->vaddr, - region->len, region->kvaddr); - list_add_tail(®ion->list, &audio->ion_region_queue); - - return rc; - -ion_error: - ion_unmap_kernel(audio->client, handle); -map_error: -flag_error: - ion_free(audio->client, handle); -import_error: - kfree(region); -end: - return rc; -} - -static int audpcm_ion_remove(struct audio *audio, - struct msm_audio_ion_info *info) -{ - struct audpcm_ion_region *region; - struct list_head *ptr, *next; - int rc = -EINVAL; - - list_for_each_safe(ptr, next, &audio->ion_region_queue) { - region = list_entry(ptr, struct audpcm_ion_region, list); - - if (region != NULL && (region->fd == info->fd) && - (region->vaddr == info->vaddr)) { - if (region->ref_cnt) { - MM_DBG("%s[%p]:region %p in use ref_cnt %d\n", - __func__, audio, region, - region->ref_cnt); - break; - } - MM_DBG("remove region fd %d vaddr %p\n", - info->fd, info->vaddr); - list_del(®ion->list); - ion_unmap_kernel(audio->client, region->handle); - ion_free(audio->client, region->handle); - kfree(region); - rc = 0; - break; - } - } - - return rc; -} - -static int audpcm_ion_lookup_vaddr(struct audio *audio, void *addr, - unsigned long len, struct audpcm_ion_region **region) -{ - struct audpcm_ion_region *region_elt; - int match_count = 0; - *region = NULL; - - /* returns physical address or zero */ - list_for_each_entry(region_elt, &audio->ion_region_queue, list) { - if (addr >= region_elt->vaddr && - addr < region_elt->vaddr + region_elt->len && - addr + len <= region_elt->vaddr + region_elt->len) { - /* offset since we could pass vaddr inside a registerd - * ion buffer - */ - - match_count++; - if (!*region) - *region = region_elt; - } - } - - if (match_count > 1) { - MM_ERR("%s[%p]:multiple hits for vaddr %p, len %ld\n", - __func__, audio, addr, len); - list_for_each_entry(region_elt, &audio->ion_region_queue, - list) { - if (addr >= region_elt->vaddr && - addr < region_elt->vaddr + region_elt->len && - addr + len <= region_elt->vaddr + region_elt->len) - MM_ERR("\t%s[%p]:%p, %ld --> %p\n", - __func__, audio, - region_elt->vaddr, - region_elt->len, - (void *)region_elt->paddr); - } - } - return *region ? 0 : -1; -} -static unsigned long audpcm_ion_fixup(struct audio *audio, void *addr, - unsigned long len, int ref_up) -{ - struct audpcm_ion_region *region; - unsigned long paddr; - int ret; - - ret = audpcm_ion_lookup_vaddr(audio, addr, len, ®ion); - if (ret) { - MM_ERR("%s[%p]:lookup (%p, %ld) failed\n", - __func__, audio, addr, len); - return 0; - } - if (ref_up) - region->ref_cnt++; - else - region->ref_cnt--; - MM_DBG("found region %p ref_cnt %d\n", region, region->ref_cnt); - paddr = region->paddr + (addr - region->vaddr); - return paddr; -} - -/* audio -> lock must be held at this point */ -static int audpcm_aio_buf_add(struct audio *audio, unsigned dir, - void __user *arg) -{ - unsigned long flags; - struct audpcm_buffer_node *buf_node; - - buf_node = kmalloc(sizeof(*buf_node), GFP_KERNEL); - - if (!buf_node) - return -ENOMEM; - - if (copy_from_user(&buf_node->buf, arg, sizeof(buf_node->buf))) { - kfree(buf_node); - return -EFAULT; - } - - MM_DBG("node %p dir %x buf_addr %p buf_len %d data_len %d\n", - buf_node, dir, buf_node->buf.buf_addr, - buf_node->buf.buf_len, buf_node->buf.data_len); - - buf_node->paddr = audpcm_ion_fixup( - audio, buf_node->buf.buf_addr, - buf_node->buf.buf_len, 1); - if (dir) { - /* write */ - if (!buf_node->paddr || - (buf_node->paddr & 0x1) || - (buf_node->buf.data_len & 0x1) || - (!buf_node->buf.data_len)) { - kfree(buf_node); - return -EINVAL; - } - spin_lock_irqsave(&audio->dsp_lock, flags); - list_add_tail(&buf_node->list, &audio->out_queue); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - audio->drv_ops.send_data(audio, 0); - } - - MM_DBG("Add buf_node %p paddr %lx\n", buf_node, buf_node->paddr); - - return 0; -} - -static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = 0; - - MM_DBG("cmd = %d\n", cmd); - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = audpp_avsync_byte_count(audio->dec_id); - stats.sample_count = audpp_avsync_sample_count(audio->dec_id); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - if (cmd == AUDIO_SET_VOLUME) { - unsigned long flags; - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->volume = arg; - if (audio->running) - audpp_set_volume_and_pan(audio->dec_id, arg, 0); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - return 0; - } - if (cmd == AUDIO_GET_EVENT) { - MM_DBG("AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audpcm_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audio_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) - rc = -ENODEV; - else - rc = 0; - } - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audio_disable(audio); - audio_ioport_reset(audio); - audio->stopped = 0; - break; - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH\n"); - audio->wflush = 1; - audio_ioport_reset(audio); - if (audio->running) { - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->wflush = 0; - } - break; - - case AUDIO_SET_CONFIG: { - struct msm_audio_config config; - if (copy_from_user(&config, (void *) arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.channel_count == 1) { - config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V; - } else if (config.channel_count == 2) { - config.channel_count = AUDPP_CMD_PCM_INTF_STEREO_V; - } else { - rc = -EINVAL; - break; - } - if (config.bits == 8) - config.bits = AUDPP_CMD_WAV_PCM_WIDTH_8; - else if (config.bits == 16) - config.bits = AUDPP_CMD_WAV_PCM_WIDTH_16; - else if (config.bits == 24) - config.bits = AUDPP_CMD_WAV_PCM_WIDTH_24; - else { - rc = -EINVAL; - break; - } - audio->out_sample_rate = config.sample_rate; - audio->out_channel_mode = config.channel_count; - audio->out_bits = config.bits; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config config; - config.buffer_size = (audio->out_dma_sz >> 1); - config.buffer_count = 2; - config.sample_rate = audio->out_sample_rate; - if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) - config.channel_count = 1; - else - config.channel_count = 2; - if (audio->out_bits == AUDPP_CMD_WAV_PCM_WIDTH_8) - config.bits = 8; - else if (audio->out_bits == AUDPP_CMD_WAV_PCM_WIDTH_24) - config.bits = 24; - else - config.bits = 16; - config.unused[0] = 0; - config.unused[1] = 0; - - if (copy_to_user((void *) arg, &config, sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - - - case AUDIO_PAUSE: - MM_DBG("AUDIO_PAUSE %ld\n", arg); - rc = audpp_pause(audio->dec_id, (int) arg); - break; - - case AUDIO_REGISTER_ION: { - struct msm_audio_ion_info info; - MM_ERR("AUDIO_REGISTER_ION\n"); - if (copy_from_user(&info, (void *) arg, sizeof(info))) - rc = -EFAULT; - else - rc = audpcm_ion_add(audio, &info); - break; - } - - case AUDIO_DEREGISTER_ION: { - struct msm_audio_ion_info info; - MM_ERR("AUDIO_DEREGISTER_ION\n"); - if (copy_from_user(&info, (void *) arg, sizeof(info))) - rc = -EFAULT; - else - rc = audpcm_ion_remove(audio, &info); - break; - } - - case AUDIO_ASYNC_WRITE: - if (audio->drv_status & ADRV_STATUS_FSYNC) - rc = -EBUSY; - else - rc = audpcm_aio_buf_add(audio, 1, (void __user *) arg); - break; - - case AUDIO_ASYNC_READ: - MM_ERR("AUDIO_ASYNC_READ not supported\n"); - rc = -EPERM; - break; - - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -int audpcm_async_fsync(struct audio *audio) -{ - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - /* Blocking client sends more data */ - mutex_lock(&audio->lock); - audio->drv_status |= ADRV_STATUS_FSYNC; - mutex_unlock(&audio->lock); - - mutex_lock(&audio->write_lock); - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - (audio->teos && audio->out_needed && - list_empty(&audio->out_queue)) - || audio->wflush || audio->stopped); - - if (audio->stopped || audio->wflush) - rc = -EBUSY; - - mutex_unlock(&audio->write_lock); - mutex_lock(&audio->lock); - audio->drv_status &= ~ADRV_STATUS_FSYNC; - mutex_unlock(&audio->lock); - - return rc; -} - -int audpcm_sync_fsync(struct audio *audio) -{ - struct buffer *frame; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (audio->reserved) { - MM_DBG("send reserved byte\n"); - frame = audio->out + audio->out_tail; - ((char *) frame->data)[0] = audio->rsv_byte; - ((char *) frame->data)[1] = 0; - frame->used = 2; - audio->drv_ops.send_data(audio, 0); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - } - - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush); - - if (audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); - return rc; -} - -int audpcm_fsync(struct file *file, loff_t a, loff_t b, int datasync) -{ - struct audio *audio = file->private_data; - - if (!audio->running) - return -EINVAL; - - return audio->drv_ops.fsync(audio); -} - -static ssize_t audio_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - char *cpy_ptr; - int rc = 0; - unsigned dsize; - - if (audio->drv_status & ADRV_STATUS_AIO_INTF) - return -EPERM; - - MM_DBG("cnt=%d\n", count); - - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - cpy_ptr = frame->data; - dsize = 0; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - break; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - break; - } - - if (audio->reserved) { - MM_DBG("append reserved byte %x\n", audio->rsv_byte); - *cpy_ptr = audio->rsv_byte; - xfer = (count > (frame->size - 1)) ? - frame->size - 1 : count; - cpy_ptr++; - dsize = 1; - audio->reserved = 0; - } else - xfer = (count > frame->size) ? frame->size : count; - - if (copy_from_user(cpy_ptr, buf, xfer)) { - rc = -EFAULT; - break; - } - - dsize += xfer; - if (dsize & 1) { - audio->rsv_byte = ((char *) frame->data)[dsize - 1]; - MM_DBG("odd length buf reserve last byte %x\n", - audio->rsv_byte); - audio->reserved = 1; - dsize--; - } - count -= xfer; - buf += xfer; - - if (dsize > 0) { - audio->out_head ^= 1; - frame->used = dsize; - audio->drv_ops.send_data(audio, 0); - } - } - mutex_unlock(&audio->write_lock); - if (buf > start) - return buf - start; - - return rc; -} - -static void audpcm_reset_ion_region(struct audio *audio) -{ - struct audpcm_ion_region *region; - struct list_head *ptr, *next; - - list_for_each_safe(ptr, next, &audio->ion_region_queue) { - region = list_entry(ptr, struct audpcm_ion_region, list); - list_del(®ion->list); - ion_unmap_kernel(audio->client, region->handle); - ion_free(audio->client, region->handle); - kfree(region); - } - - return; -} - -static int audio_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_DBG("audio instance 0x%08x freeing\n", (int)audio); - mutex_lock(&audio->lock); - audio_disable(audio); - if (audio->rmt_resource_released == 0) - rmt_put_resource(audio); - audio->drv_ops.out_flush(audio); - audpcm_reset_ion_region(audio); - - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->opened = 0; - audio->event_abort = 1; - wake_up(&audio->event_wait); - audpcm_reset_event_queue(audio); - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - ion_client_destroy(audio->client); - kfree(audio); - return 0; -} - -static void audpcm_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audpcm_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audpcm_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audpcm_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audpcm_suspend(struct early_suspend *h) -{ - struct audpcm_suspend_ctl *ctl = - container_of(h, struct audpcm_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audpcm_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audpcm_resume(struct early_suspend *h) -{ - struct audpcm_suspend_ctl *ctl = - container_of(h, struct audpcm_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audpcm_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audpcm_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audpcm_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 4096; - static char buffer[4096]; - int n = 0; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_buf_sz %d\n", audio->out[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %x \n", audio->volume); - n += scnprintf(buffer + n, debug_bufmax - n, - "sample rate %d \n", audio->out_sample_rate); - n += scnprintf(buffer + n, debug_bufmax - n, - "channel mode %d \n", audio->out_channel_mode); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d \n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d \n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d \n", audio->out_needed); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_head %d \n", audio->out_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_tail %d \n", audio->out_tail); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[0].used %d \n", audio->out[0].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[1].used %d \n", audio->out[1].used); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audpcm_debug_fops = { - .read = audpcm_debug_read, - .open = audpcm_debug_open, -}; -#endif - -static int audio_open(struct inode *inode, struct file *file) -{ - struct audio *audio = NULL; - int rc, i, dec_attrb, decid; - struct audpcm_event *e_node = NULL; - unsigned mem_sz = DMASZ_MAX; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - struct ion_client *client = NULL; - int len = 0; - - -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_pcm_dec_" + 5]; -#endif - - /* Allocate audio instance, set to zero */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("no memory to allocate audio instance \n"); - rc = -ENOMEM; - goto done; - } - MM_DBG("audio instance 0x%08x created\n", (int)audio); - - /* Allocate the decoder */ - dec_attrb = AUDDEC_DEC_PCM; - if (file->f_mode & FMODE_READ) { - MM_ERR("Non-Tunneled mode not supported\n"); - rc = -EPERM; - kfree(audio); - goto done; - } else - dec_attrb |= MSM_AUD_MODE_TUNNEL; - - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - if (decid < 0) { - MM_ERR("No free decoder available\n"); - rc = -ENODEV; - MM_DBG("audio instance 0x%08x freeing\n", (int)audio); - kfree(audio); - goto done; - } - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - client = msm_ion_client_create(UINT_MAX, "Audio_PCM_Client"); - if (IS_ERR_OR_NULL(client)) { - pr_err("Unable to create ION client\n"); - rc = -ENOMEM; - goto client_create_error; - } - audio->client = client; - - /* Non AIO interface */ - if (!(file->f_flags & O_NONBLOCK)) { - - MM_DBG("memsz = %d\n", mem_sz); - - handle = ion_alloc(client, mem_sz, SZ_4K, - ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to create allocate O/P buffers\n"); - rc = -ENOMEM; - goto output_buff_alloc_error; - } - audio->output_buff_handle = handle; - - rc = ion_phys(client , handle, &addr, &len); - if (rc) { - MM_ERR("O/P buffers:Invalid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - goto output_buff_get_phys_error; - } else { - MM_INFO("O/P buffers:valid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - } - audio->phys = (int32_t)addr; - - - rc = ion_handle_get_flags(client, handle, &ionflag); - if (rc) { - MM_ERR("could not get flags for the handle\n"); - goto output_buff_get_flags_error; - } - - audio->map_v_write = ion_map_kernel(client, handle); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write buffers\n"); - rc = -ENOMEM; - goto output_buff_map_error; - } - audio->data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->phys, (int)audio->data); - - audio->out_dma_sz = mem_sz; - } - - rc = audmgr_open(&audio->audmgr); - if (rc) - goto err; - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audpcmdec_adsp_ops, audio); - if (rc) { - MM_ERR("failed to get %s module\n", audio->module_name); - audmgr_close(&audio->audmgr); - goto err; - } - - rc = rmt_get_resource(audio); - if (rc) { - MM_ERR("ADSP resources are not available for PCM session \ - 0x%08x on decoder: %d\n", (int)audio, audio->dec_id); - audmgr_close(&audio->audmgr); - msm_adsp_put(audio->audplay); - goto err; - } - - if (file->f_flags & O_NONBLOCK) { - MM_DBG("set to aio interface\n"); - audio->drv_status |= ADRV_STATUS_AIO_INTF; - audio->drv_ops.send_data = audpcm_async_send_data; - audio->drv_ops.out_flush = audpcm_async_flush; - audio->drv_ops.fsync = audpcm_async_fsync; - } else { - MM_DBG("set to std io interface\n"); - audio->drv_ops.send_data = audplay_send_data; - audio->drv_ops.out_flush = audio_flush; - audio->drv_ops.fsync = audpcm_sync_fsync; - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = (audio->out_dma_sz >> 1); - - audio->out[1].data = audio->data + audio->out[0].size; - audio->out[1].addr = audio->phys + audio->out[0].size; - audio->out[1].size = audio->out[0].size; - } - - /* Initialize all locks of audio instance */ - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - init_waitqueue_head(&audio->write_wait); - INIT_LIST_HEAD(&audio->out_queue); - INIT_LIST_HEAD(&audio->ion_region_queue); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - spin_lock_init(&audio->event_queue_lock); - - audio->out_sample_rate = 44100; - audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V; - audio->out_bits = AUDPP_CMD_WAV_PCM_WIDTH_16; - audio->volume = 0x2000; - audio->drv_ops.out_flush(audio); - - file->private_data = audio; - audio->opened = 1; - -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_pcm_dec_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, &audpcm_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audpcm_resume; - audio->suspend_ctl.node.suspend = audpcm_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (i = 0; i < AUDPCM_EVENT_NUM; i++) { - e_node = kmalloc(sizeof(struct audpcm_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } -done: - return rc; -err: - ion_unmap_kernel(client, audio->output_buff_handle); -output_buff_map_error: -output_buff_get_flags_error: -output_buff_get_phys_error: - ion_free(client, audio->output_buff_handle); -output_buff_alloc_error: - ion_client_destroy(client); -client_create_error: - audpp_adec_free(audio->dec_id); - MM_DBG("audio instance 0x%08x freeing\n", (int)audio); - kfree(audio); - return rc; -} - -static const struct file_operations audio_pcm_fops = { - .owner = THIS_MODULE, - .open = audio_open, - .release = audio_release, - .write = audio_write, - .unlocked_ioctl = audio_ioctl, - .fsync = audpcm_fsync, -}; - -struct miscdevice audio_pcm_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_pcm_dec", - .fops = &audio_pcm_fops, -}; - -static int __init audio_init(void) -{ - return misc_register(&audio_pcm_misc); -} - -device_initcall(audio_init); diff --git a/arch/arm/mach-msm/qdsp5/audio_pcm_in.c b/arch/arm/mach-msm/qdsp5/audio_pcm_in.c deleted file mode 100644 index 201ee373cde91f2c51fc8708682383acca6a9e78..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_pcm_in.c +++ /dev/null @@ -1,1002 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/audio_pcm_in.c - * - * pcm audio input device - * - * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. - * - * This code is based in part on arch/arm/mach-msm/qdsp5v2/audio_pcm_in.c, - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include - -#include -#include -#include -#include - -#include "audmgr.h" - -#include -#include -#include -#include -#include -#include - -/* FRAME_NUM must be a power of two */ -#define FRAME_NUM (8) -#define FRAME_SIZE (2052 * 2) -#define MONO_DATA_SIZE (2048) -#define STEREO_DATA_SIZE (MONO_DATA_SIZE * 2) -#define DMASZ (FRAME_SIZE * FRAME_NUM) -#define MSM_AUD_BUFFER_UPDATE_WAIT_MS 2000 - -struct buffer { - void *data; - uint32_t size; - uint32_t read; - uint32_t addr; -}; - -struct audio_in { - struct buffer in[FRAME_NUM]; - - spinlock_t dsp_lock; - - atomic_t in_bytes; - - struct mutex lock; - struct mutex read_lock; - wait_queue_head_t wait; - - struct msm_adsp_module *audpre; - struct msm_adsp_module *audrec; - const char *module_name; - unsigned queue_ids; - uint16_t enc_id; /* Session Id */ - - /* configuration to use on next enable */ - uint32_t samp_rate; - uint32_t channel_mode; - uint32_t buffer_size; /* 2048 for mono, 4096 for stereo */ - uint32_t enc_type; /* 0 for PCM */ - uint32_t mode; /* Tunnel for PCM */ - uint32_t dsp_cnt; - uint32_t in_head; /* next buffer dsp will write */ - uint32_t in_tail; /* next buffer read() will read */ - uint32_t in_count; /* number of buffers available to read() */ - - unsigned short samp_rate_index; - uint32_t audrec_obj_idx ; - - struct audmgr audmgr; - - /* data allocated for various buffers */ - char *data; - dma_addr_t phys; - - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - - /* audpre settings */ - int tx_agc_enable; - audpreproc_cmd_cfg_agc_params tx_agc_cfg; - int ns_enable; - audpreproc_cmd_cfg_ns_params ns_cfg; - /* For different sample rate, the coeff might be different. * - * All the coeff should be passed from user space */ - int iir_enable; - audpreproc_cmd_cfg_iir_tuning_filter_params iir_cfg; - struct ion_client *client; - struct ion_handle *output_buff_handle; -}; - -static int audpcm_in_dsp_enable(struct audio_in *audio, int enable); -static int audpcm_in_encmem_config(struct audio_in *audio); -static int audpcm_in_encparam_config(struct audio_in *audio); -static int audpcm_in_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt); -static void audpcm_in_flush(struct audio_in *audio); -static int audio_dsp_set_tx_agc(struct audio_in *audio); -static int audio_dsp_set_ns(struct audio_in *audio); -static int audio_dsp_set_iir(struct audio_in *audio); - -static unsigned convert_dsp_samp_index(unsigned index) -{ - switch (index) { - case 48000: return AUDREC_CMD_SAMP_RATE_INDX_48000; - case 44100: return AUDREC_CMD_SAMP_RATE_INDX_44100; - case 32000: return AUDREC_CMD_SAMP_RATE_INDX_32000; - case 24000: return AUDREC_CMD_SAMP_RATE_INDX_24000; - case 22050: return AUDREC_CMD_SAMP_RATE_INDX_22050; - case 16000: return AUDREC_CMD_SAMP_RATE_INDX_16000; - case 12000: return AUDREC_CMD_SAMP_RATE_INDX_12000; - case 11025: return AUDREC_CMD_SAMP_RATE_INDX_11025; - case 8000: return AUDREC_CMD_SAMP_RATE_INDX_8000; - default: return AUDREC_CMD_SAMP_RATE_INDX_11025; - } -} - -static unsigned convert_samp_rate(unsigned hz) -{ - switch (hz) { - case 48000: return RPC_AUD_DEF_SAMPLE_RATE_48000; - case 44100: return RPC_AUD_DEF_SAMPLE_RATE_44100; - case 32000: return RPC_AUD_DEF_SAMPLE_RATE_32000; - case 24000: return RPC_AUD_DEF_SAMPLE_RATE_24000; - case 22050: return RPC_AUD_DEF_SAMPLE_RATE_22050; - case 16000: return RPC_AUD_DEF_SAMPLE_RATE_16000; - case 12000: return RPC_AUD_DEF_SAMPLE_RATE_12000; - case 11025: return RPC_AUD_DEF_SAMPLE_RATE_11025; - case 8000: return RPC_AUD_DEF_SAMPLE_RATE_8000; - default: return RPC_AUD_DEF_SAMPLE_RATE_11025; - } -} - -static unsigned convert_samp_index(unsigned index) -{ - switch (index) { - case RPC_AUD_DEF_SAMPLE_RATE_48000: return 48000; - case RPC_AUD_DEF_SAMPLE_RATE_44100: return 44100; - case RPC_AUD_DEF_SAMPLE_RATE_32000: return 32000; - case RPC_AUD_DEF_SAMPLE_RATE_24000: return 24000; - case RPC_AUD_DEF_SAMPLE_RATE_22050: return 22050; - case RPC_AUD_DEF_SAMPLE_RATE_16000: return 16000; - case RPC_AUD_DEF_SAMPLE_RATE_12000: return 12000; - case RPC_AUD_DEF_SAMPLE_RATE_11025: return 11025; - case RPC_AUD_DEF_SAMPLE_RATE_8000: return 8000; - default: return 11025; - } -} - -/* must be called with audio->lock held */ -static int audpcm_in_enable(struct audio_in *audio) -{ - struct audmgr_config cfg; - int rc; - - if (audio->enabled) - return 0; - - cfg.tx_rate = audio->samp_rate; - cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; - cfg.def_method = RPC_AUD_DEF_METHOD_RECORD; - cfg.codec = RPC_AUD_DEF_CODEC_PCM; - cfg.snd_method = RPC_SND_METHOD_MIDI; - - rc = audmgr_enable(&audio->audmgr, &cfg); - if (rc < 0) - return rc; - - if (msm_adsp_enable(audio->audpre)) { - MM_ERR("msm_adsp_enable(audpre) failed\n"); - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - if (msm_adsp_enable(audio->audrec)) { - audmgr_disable(&audio->audmgr); - msm_adsp_disable(audio->audpre); - MM_ERR("msm_adsp_enable(audrec) failed\n"); - return -ENODEV; - } - - audio->enabled = 1; - audpcm_in_dsp_enable(audio, 1); - - return 0; -} - -/* must be called with audio->lock held */ -static int audpcm_in_disable(struct audio_in *audio) -{ - if (audio->enabled) { - audio->enabled = 0; - - audpcm_in_dsp_enable(audio, 0); - - audio->stopped = 1; - wake_up(&audio->wait); - - msm_adsp_disable(audio->audrec); - msm_adsp_disable(audio->audpre); - audmgr_disable(&audio->audmgr); - } - return 0; -} - -/* ------------------- dsp --------------------- */ -static void audpre_dsp_event(void *data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - uint16_t msg[2]; - getevent(msg, sizeof(msg)); - - switch (id) { - case AUDPREPROC_MSG_CMD_CFG_DONE_MSG: - MM_INFO("type %d, status_flag %d\n", msg[0], msg[1]); - break; - case AUDPREPROC_MSG_ERROR_MSG_ID: - MM_ERR("err_index %d\n", msg[0]); - break; - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audpreproctask)\n"); - break; - default: - MM_ERR("unknown event %d\n", id); - } -} - -struct audio_frame { - uint16_t count_low; - uint16_t count_high; - uint16_t bytes; - uint16_t unknown; - unsigned char samples[]; -} __packed; - -static void audpcm_in_get_dsp_frames(struct audio_in *audio) -{ - struct audio_frame *frame; - uint32_t index; - unsigned long flags; - - index = audio->in_head; - - frame = (void *) (((char *)audio->in[index].data) - - sizeof(*frame)); - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->in[index].size = frame->bytes; - - audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1); - - /* If overflow, move the tail index foward. */ - if (audio->in_head == audio->in_tail) { - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - MM_ERR("Error! not able to keep up the read\n"); - } else - audio->in_count++; - - audpcm_in_dsp_read_buffer(audio, audio->dsp_cnt++); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - - wake_up(&audio->wait); -} - -static void audrec_dsp_event(void *data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - struct audio_in *audio = NULL; - uint16_t msg[3]; - - if (data) - audio = data; - else { - MM_ERR("invalid data for event %x\n", id); - return; - } - - getevent(msg, sizeof(msg)); - - switch (id) { - case AUDREC_MSG_CMD_CFG_DONE_MSG: { - if (msg[0] & AUDREC_MSG_CFG_DONE_ENC_ENA) { - audio->audrec_obj_idx = msg[1]; - MM_INFO("CFG ENABLED\n"); - audpcm_in_encmem_config(audio); - } else { - MM_INFO("CFG SLEEP\n"); - audio->running = 0; - audio->tx_agc_enable = 0; - audio->ns_enable = 0; - audio->iir_enable = 0; - } - break; - } - case AUDREC_MSG_CMD_AREC_MEM_CFG_DONE_MSG: { - MM_DBG("AREC_MEM_CFG_DONE_MSG\n"); - audpcm_in_encparam_config(audio); - break; - } - case AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG: { - MM_INFO("PARAM CFG DONE\n"); - audio->running = 1; - audio_dsp_set_tx_agc(audio); - audio_dsp_set_ns(audio); - audio_dsp_set_iir(audio); - break; - } - case AUDREC_MSG_NO_EXT_PKT_AVAILABLE_MSG: { - MM_DBG("ERROR %x\n", msg[0]); - break; - } - case AUDREC_MSG_PACKET_READY_MSG: { - struct audrec_msg_packet_ready_msg pkt_ready_msg; - - getevent(&pkt_ready_msg, AUDREC_MSG_PACKET_READY_MSG_LEN); - MM_DBG("UP_PACKET_READY_MSG: write cnt msw %d \ - write cnt lsw %d read cnt msw %d read cnt lsw %d \n",\ - pkt_ready_msg.pkt_counter_msw, \ - pkt_ready_msg.pkt_counter_lsw, \ - pkt_ready_msg.pkt_read_cnt_msw, \ - pkt_ready_msg.pkt_read_cnt_lsw); - - audpcm_in_get_dsp_frames(audio); - break; - } - case ADSP_MESSAGE_ID: { - MM_DBG("Received ADSP event: module \ - enable/disable(audrectask)\n"); - break; - } - default: - MM_ERR("unknown event %d\n", id); - } -} - -static struct msm_adsp_ops audpre_adsp_ops = { - .event = audpre_dsp_event, -}; - -static struct msm_adsp_ops audrec_adsp_ops = { - .event = audrec_dsp_event, -}; - - -#define audio_send_queue_pre(audio, cmd, len) \ - msm_adsp_write(audio->audpre, QDSP_uPAudPreProcCmdQueue, cmd, len) - -#define audio_send_queue_recbs(audio, cmd, len) \ - msm_adsp_write(audio->audrec, ((audio->queue_ids & 0xFFFF0000) >> 16),\ - cmd, len) -#define audio_send_queue_rec(audio, cmd, len) \ - msm_adsp_write(audio->audrec, (audio->queue_ids & 0x0000FFFF),\ - cmd, len) - -static int audio_dsp_set_tx_agc(struct audio_in *audio) -{ - audpreproc_cmd_cfg_agc_params cmd; - - memset(&cmd, 0, sizeof(cmd)); - - audio->tx_agc_cfg.cmd_id = AUDPREPROC_CMD_CFG_AGC_PARAMS; - if (audio->tx_agc_enable) { - /* cmd.tx_agc_param_mask = 0xFE00 from sample code */ - audio->tx_agc_cfg.tx_agc_param_mask = - (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_SLOPE) | - (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_TH) | - (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_SLOPE) | - (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_TH) | - (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_AIG_FLAG) | - (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_STATIC_GAIN) | - (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG); - audio->tx_agc_cfg.tx_agc_enable_flag = - AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA; - /* cmd.param_mask = 0xFFF0 from sample code */ - audio->tx_agc_cfg.param_mask = - (1 << AUDPREPROC_CMD_PARAM_MASK_RMS_TAY) | - (1 << AUDPREPROC_CMD_PARAM_MASK_RELEASEK) | - (1 << AUDPREPROC_CMD_PARAM_MASK_DELAY) | - (1 << AUDPREPROC_CMD_PARAM_MASK_ATTACKK) | - (1 << AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_SLOW) | - (1 << AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_FAST) | - (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_RELEASEK) | - (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_MIN) | - (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_MAX) | - (1 << AUDPREPROC_CMD_PARAM_MASK_LEAK_UP) | - (1 << AUDPREPROC_CMD_PARAM_MASK_LEAK_DOWN) | - (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_ATTACKK); - } else { - audio->tx_agc_cfg.tx_agc_param_mask = - (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG); - audio->tx_agc_cfg.tx_agc_enable_flag = - AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS; - } - cmd = audio->tx_agc_cfg; - - return audio_send_queue_pre(audio, &cmd, sizeof(cmd)); -} - -static int audio_enable_tx_agc(struct audio_in *audio, int enable) -{ - if (audio->tx_agc_enable != enable) { - audio->tx_agc_enable = enable; - if (audio->running) - audio_dsp_set_tx_agc(audio); - } - return 0; -} - -static int audio_dsp_set_ns(struct audio_in *audio) -{ - audpreproc_cmd_cfg_ns_params cmd; - - memset(&cmd, 0, sizeof(cmd)); - - audio->ns_cfg.cmd_id = AUDPREPROC_CMD_CFG_NS_PARAMS; - - if (audio->ns_enable) { - /* cmd.ec_mode_new is fixed as 0x0064 when enable - * from sample code */ - audio->ns_cfg.ec_mode_new = - AUDPREPROC_CMD_EC_MODE_NEW_NS_ENA | - AUDPREPROC_CMD_EC_MODE_NEW_HB_ENA | - AUDPREPROC_CMD_EC_MODE_NEW_VA_ENA; - } else { - audio->ns_cfg.ec_mode_new = - AUDPREPROC_CMD_EC_MODE_NEW_NLMS_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_DES_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_NS_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_CNI_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_NLES_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_HB_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_VA_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_PCD_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_FEHI_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_NEHI_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_NLPP_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_FNE_DIS | - AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_DIS; - } - cmd = audio->ns_cfg; - - return audio_send_queue_pre(audio, &cmd, sizeof(cmd)); -} - -static int audio_enable_ns(struct audio_in *audio, int enable) -{ - if (audio->ns_enable != enable) { - audio->ns_enable = enable; - if (audio->running) - audio_dsp_set_ns(audio); - } - return 0; -} - -static int audio_dsp_set_iir(struct audio_in *audio) -{ - audpreproc_cmd_cfg_iir_tuning_filter_params cmd; - - memset(&cmd, 0, sizeof(cmd)); - - audio->iir_cfg.cmd_id = AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS; - - if (audio->iir_enable) - /* cmd.active_flag is 0xFFFF from sample code but 0x0001 here */ - audio->iir_cfg.active_flag = AUDPREPROC_CMD_IIR_ACTIVE_FLAG_ENA; - else - audio->iir_cfg.active_flag = AUDPREPROC_CMD_IIR_ACTIVE_FLAG_DIS; - - cmd = audio->iir_cfg; - - return audio_send_queue_pre(audio, &cmd, sizeof(cmd)); -} - -static int audio_enable_iir(struct audio_in *audio, int enable) -{ - if (audio->iir_enable != enable) { - audio->iir_enable = enable; - if (audio->running) - audio_dsp_set_iir(audio); - } - return 0; -} - -static int audpcm_in_dsp_enable(struct audio_in *audio, int enable) -{ - struct audrec_cmd_enc_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_ENC_CFG; - - cmd.audrec_enc_type = (audio->enc_type & 0xFF) | - (enable ? AUDREC_CMD_ENC_ENA : AUDREC_CMD_ENC_DIS); - /* Don't care */ - cmd.audrec_obj_idx = audio->audrec_obj_idx; - - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audpcm_in_encmem_config(struct audio_in *audio) -{ - struct audrec_cmd_arecmem_cfg cmd; - uint16_t cnt = 0; - uint16_t *data = (void *) audio->data; - - memset(&cmd, 0, sizeof(cmd)); - - cmd.cmd_id = AUDREC_CMD_ARECMEM_CFG; - cmd.audrec_obj_idx = audio->audrec_obj_idx; - /* Rate at which packet complete message comes */ - cmd.audrec_up_pkt_intm_cnt = 1; - cmd.audrec_extpkt_buffer_msw = audio->phys >> 16; - cmd.audrec_extpkt_buffer_lsw = audio->phys; - /* Max Buffer no available for frames */ - cmd.audrec_extpkt_buffer_num = FRAME_NUM; - - /* prepare buffer pointers: - * Mono: 1024 samples + 4 halfword header - * Stereo: 2048 samples + 4 halfword header - */ - for (cnt = 0; cnt < FRAME_NUM; cnt++) { - audio->in[cnt].data = data + 4; - data += (4 + (audio->channel_mode ? 2048 : 1024)); - } - - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audpcm_in_encparam_config(struct audio_in *audio) -{ - struct audrec_cmd_arecparam_wav_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDREC_CMD_ARECPARAM_CFG; - cmd.common.audrec_obj_idx = audio->audrec_obj_idx; - cmd.samp_rate_idx = audio->samp_rate_index; - cmd.stereo_mode = audio->channel_mode; /* 0 for mono, 1 for stereo */ - - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audpcm_in_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt) -{ - audrec_cmd_packet_ext_ptr cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_PACKET_EXT_PTR; - cmd.type = audio->audrec_obj_idx; - cmd.curr_rec_count_msw = read_cnt >> 16; - cmd.curr_rec_count_lsw = read_cnt; - - return audio_send_queue_recbs(audio, &cmd, sizeof(cmd)); -} - -/* ------------------- device --------------------- */ - -static void audpcm_in_flush(struct audio_in *audio) -{ - int i; - - audio->dsp_cnt = 0; - audio->in_head = 0; - audio->in_tail = 0; - audio->in_count = 0; - for (i = FRAME_NUM-1; i >= 0; i--) { - audio->in[i].size = 0; - audio->in[i].read = 0; - } -} - -static long audpcm_in_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct audio_in *audio = file->private_data; - int rc = 0; - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = atomic_read(&audio->in_bytes); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: { - rc = audpcm_in_enable(audio); - audio->stopped = 0; - break; - } - case AUDIO_STOP: - rc = audpcm_in_disable(audio); - break; - case AUDIO_FLUSH: - if (audio->stopped) { - /* Make sure we're stopped and we wake any threads - * that might be blocked holding the read_lock. - * While audio->stopped read threads will always - * exit immediately. - */ - wake_up(&audio->wait); - mutex_lock(&audio->read_lock); - audpcm_in_flush(audio); - mutex_unlock(&audio->read_lock); - } - break; - case AUDIO_SET_CONFIG: { - struct msm_audio_config cfg; - - if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - if (cfg.channel_count == 1) { - cfg.channel_count = AUDREC_CMD_STEREO_MODE_MONO; - } else if (cfg.channel_count == 2) { - cfg.channel_count = AUDREC_CMD_STEREO_MODE_STEREO; - } else { - rc = -EINVAL; - break; - } - - audio->samp_rate = convert_samp_rate(cfg.sample_rate); - audio->samp_rate_index = - convert_dsp_samp_index(cfg.sample_rate); - audio->channel_mode = cfg.channel_count; - audio->buffer_size = - audio->channel_mode ? STEREO_DATA_SIZE - : MONO_DATA_SIZE; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config cfg; - cfg.buffer_size = audio->buffer_size; - cfg.buffer_count = FRAME_NUM; - cfg.sample_rate = convert_samp_index(audio->samp_rate); - if (audio->channel_mode == AUDREC_CMD_STEREO_MODE_MONO) - cfg.channel_count = 1; - else - cfg.channel_count = 2; - cfg.type = 0; - cfg.unused[0] = 0; - cfg.unused[1] = 0; - cfg.unused[2] = 0; - if (copy_to_user((void *) arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - break; - } - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -static ssize_t audpcm_in_read(struct file *file, - char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_in *audio = file->private_data; - unsigned long flags; - const char __user *start = buf; - void *data; - uint32_t index; - uint32_t size; - int rc = 0; - - mutex_lock(&audio->read_lock); - while (count > 0) { - rc = wait_event_interruptible_timeout( - audio->wait, (audio->in_count > 0) || audio->stopped, - msecs_to_jiffies(MSM_AUD_BUFFER_UPDATE_WAIT_MS)); - if (rc == 0) { - rc = -ETIMEDOUT; - break; - } else if (rc < 0) { - break; - } - - if (audio->stopped && !audio->in_count) { - rc = 0;/* End of File */ - break; - } - - index = audio->in_tail; - data = (uint8_t *) audio->in[index].data; - size = audio->in[index].size; - if (count >= size) { - /* order the reads on the buffer */ - dma_coherent_post_ops(); - if (copy_to_user(buf, data, size)) { - rc = -EFAULT; - break; - } - spin_lock_irqsave(&audio->dsp_lock, flags); - if (index != audio->in_tail) { - /* overrun -- data is invalid and we need to - * retry - */ - spin_unlock_irqrestore(&audio->dsp_lock, flags); - continue; - } - audio->in[index].size = 0; - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - audio->in_count--; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - count -= size; - buf += size; - } else { - MM_ERR("short read\n"); - break; - } - } - mutex_unlock(&audio->read_lock); - - if (buf > start) - return buf - start; - - return rc; -} - -static ssize_t audpcm_in_write(struct file *file, - const char __user *buf, - size_t count, loff_t *pos) -{ - return -EINVAL; -} - -static int audpcm_in_release(struct inode *inode, struct file *file) -{ - struct audio_in *audio = file->private_data; - - mutex_lock(&audio->lock); - audpcm_in_disable(audio); - audpcm_in_flush(audio); - audpreproc_aenc_free(audio->enc_id); - msm_adsp_put(audio->audrec); - msm_adsp_put(audio->audpre); - audio->audrec = NULL; - audio->audpre = NULL; - audio->opened = 0; - if (audio->data) { - ion_unmap_kernel(audio->client, audio->output_buff_handle); - ion_free(audio->client, audio->output_buff_handle); - audio->data = NULL; - } - ion_client_destroy(audio->client); - mutex_unlock(&audio->lock); - return 0; -} - -static struct audio_in the_audio_in; - -static int audpcm_in_open(struct inode *inode, struct file *file) -{ - struct audio_in *audio = &the_audio_in; - int rc; - int len = 0; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - struct ion_client *client = NULL; - - int encid; - mutex_lock(&audio->lock); - if (audio->opened) { - rc = -EBUSY; - goto done; - } - - /* Settings will be re-config at AUDIO_SET_CONFIG, - * but at least we need to have initial config - */ - audio->mode = MSM_AUD_ENC_MODE_TUNNEL; - audio->samp_rate = RPC_AUD_DEF_SAMPLE_RATE_11025; - audio->samp_rate_index = AUDREC_CMD_SAMP_RATE_INDX_11025; - audio->channel_mode = AUDREC_CMD_STEREO_MODE_MONO; - audio->buffer_size = MONO_DATA_SIZE; - audio->enc_type = AUDREC_CMD_TYPE_0_INDEX_WAV | audio->mode; - - rc = audmgr_open(&audio->audmgr); - if (rc) - goto done; - encid = audpreproc_aenc_alloc(audio->enc_type, &audio->module_name, - &audio->queue_ids); - if (encid < 0) { - MM_ERR("No free encoder available\n"); - rc = -ENODEV; - goto done; - } - audio->enc_id = encid; - - rc = msm_adsp_get(audio->module_name, &audio->audrec, - &audrec_adsp_ops, audio); - if (rc) { - audpreproc_aenc_free(audio->enc_id); - goto done; - } - - rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre, - &audpre_adsp_ops, audio); - if (rc) { - msm_adsp_put(audio->audrec); - audpreproc_aenc_free(audio->enc_id); - goto done; - } - - audio->dsp_cnt = 0; - audio->stopped = 0; - - audpcm_in_flush(audio); - - client = msm_ion_client_create(UINT_MAX, "Audio_PCM_in_client"); - if (IS_ERR_OR_NULL(client)) { - MM_ERR("Unable to create ION client\n"); - rc = -ENOMEM; - goto client_create_error; - } - audio->client = client; - - MM_DBG("allocating mem sz = %d\n", DMASZ); - handle = ion_alloc(client, DMASZ, SZ_4K, - ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to create allocate O/P buffers\n"); - rc = -ENOMEM; - goto output_buff_alloc_error; - } - - audio->output_buff_handle = handle; - - rc = ion_phys(client , handle, &addr, &len); - if (rc) { - MM_ERR("O/P buffers:Invalid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - rc = -ENOMEM; - goto output_buff_get_phys_error; - } else { - MM_INFO("O/P buffers:valid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - } - audio->phys = (int32_t)addr; - - rc = ion_handle_get_flags(client, handle, &ionflag); - if (rc) { - MM_ERR("could not get flags for the handle\n"); - rc = -ENOMEM; - goto output_buff_get_flags_error; - } - - audio->data = ion_map_kernel(client, handle); - if (IS_ERR(audio->data)) { - MM_ERR("could not map read buffers,freeing instance 0x%08x\n", - (int)audio); - rc = -ENOMEM; - goto output_buff_map_error; - } - MM_DBG("read buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->phys, (int)audio->data); - - file->private_data = audio; - audio->opened = 1; - rc = 0; -done: - mutex_unlock(&audio->lock); - return rc; -output_buff_map_error: -output_buff_get_phys_error: -output_buff_get_flags_error: - ion_free(client, audio->output_buff_handle); -output_buff_alloc_error: - ion_client_destroy(client); -client_create_error: - msm_adsp_put(audio->audrec); - msm_adsp_put(audio->audpre); - audpreproc_aenc_free(audio->enc_id); - mutex_unlock(&audio->lock); - return rc; -} - -static long audpre_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct audio_in *audio = file->private_data; - int rc = 0, enable; - uint16_t enable_mask; - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_ENABLE_AUDPRE: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - enable = (enable_mask & AGC_ENABLE) ? 1 : 0; - audio_enable_tx_agc(audio, enable); - enable = (enable_mask & NS_ENABLE) ? 1 : 0; - audio_enable_ns(audio, enable); - enable = (enable_mask & TX_IIR_ENABLE) ? 1 : 0; - audio_enable_iir(audio, enable); - break; - - case AUDIO_SET_AGC: - if (copy_from_user(&audio->tx_agc_cfg, (void *) arg, - sizeof(audio->tx_agc_cfg))) - rc = -EFAULT; - break; - - case AUDIO_SET_NS: - if (copy_from_user(&audio->ns_cfg, (void *) arg, - sizeof(audio->ns_cfg))) - rc = -EFAULT; - break; - - case AUDIO_SET_TX_IIR: - if (copy_from_user(&audio->iir_cfg, (void *) arg, - sizeof(audio->iir_cfg))) - rc = -EFAULT; - break; - - default: - rc = -EINVAL; - } - - mutex_unlock(&audio->lock); - return rc; -} - -static int audpre_open(struct inode *inode, struct file *file) -{ - struct audio_in *audio = &the_audio_in; - - file->private_data = audio; - - return 0; -} - -static const struct file_operations audio_fops = { - .owner = THIS_MODULE, - .open = audpcm_in_open, - .release = audpcm_in_release, - .read = audpcm_in_read, - .write = audpcm_in_write, - .unlocked_ioctl = audpcm_in_ioctl, -}; - -static struct miscdevice audpcm_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_pcm_in", - .fops = &audio_fops, -}; - -static const struct file_operations audpre_fops = { - .owner = THIS_MODULE, - .open = audpre_open, - .unlocked_ioctl = audpre_ioctl, -}; - -static struct miscdevice audpre_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_preproc_ctl", - .fops = &audpre_fops, -}; - -static int __init audpcm_in_init(void) -{ - - mutex_init(&the_audio_in.lock); - mutex_init(&the_audio_in.read_lock); - spin_lock_init(&the_audio_in.dsp_lock); - init_waitqueue_head(&the_audio_in.wait); - return misc_register(&audpcm_in_misc) || misc_register(&audpre_misc); -} -device_initcall(audpcm_in_init); diff --git a/arch/arm/mach-msm/qdsp5/audio_qcelp.c b/arch/arm/mach-msm/qdsp5/audio_qcelp.c deleted file mode 100644 index 0871ffec64021348755bfb61b29f5dd649c31eb3..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_qcelp.c +++ /dev/null @@ -1,1692 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/audio_qcelp.c - * - * qcelp 13k audio decoder device - * - * Copyright (c) 2008-2009, 2011-2012 The Linux Foundation. All rights reserved. - * - * This code is based in part on audio_mp3.c, which is - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org. - * - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "audmgr.h" - -#define BUFSZ 1094 /* QCELP 13K Hold 600ms packet data = 36 * 30 and - 14 bytes of meta in */ -#define BUF_COUNT 2 -#define DMASZ (BUFSZ * BUF_COUNT) - -#define PCM_BUFSZ_MIN 1624 /* 100ms worth of data and - 24 bytes of meta out */ -#define PCM_BUF_MAX_COUNT 5 - -#define AUDDEC_DEC_QCELP 9 - -#define ROUTING_MODE_FTRT 1 -#define ROUTING_MODE_RT 2 -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDQCELP_METAFIELD_MASK 0xFFFF0000 -#define AUDQCELP_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */ -#define AUDQCELP_EOS_FLG_MASK 0x01 -#define AUDQCELP_EOS_NONE 0x0 /* No EOS detected */ -#define AUDQCELP_EOS_SET 0x1 /* EOS set in meta field */ - -#define AUDQCELP_EVENT_NUM 10 /* Default number of pre-allocated event pkts */ - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; - unsigned short mfield_sz; /*only useful for data has meta field */ -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audqcelp_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct audqcelp_event{ - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audio { - struct buffer out[BUF_COUNT]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - /* Host PCM section - START */ - struct buffer in[PCM_BUF_MAX_COUNT]; - struct mutex read_lock; - wait_queue_head_t read_wait; /* Wait queue for read */ - char *read_data; /* pointer to reader buffer */ - int32_t read_phys; /* physical address of reader buffer */ - uint8_t read_next; /* index to input buffers to be read next */ - uint8_t fill_next; /* index to buffer that DSP should be filling */ - uint8_t pcm_buf_count; /* number of pcm buffer allocated */ - /* Host PCM section - END */ - - struct msm_adsp_module *audplay; - - struct audmgr audmgr; - - /* data allocated for various buffers */ - char *data; - int32_t phys; /* physical address of write buffer */ - void *map_v_read; - void *map_v_write; - int mfield; /* meta field embedded in data */ - int rflush; /* Read flush */ - int wflush; /* Write flush */ - uint8_t opened:1; - uint8_t enabled:1; - uint8_t running:1; - uint8_t stopped:1; /* set when stopped, cleared on flush */ - uint8_t pcm_feedback:1; /* set when non-tunnel mode */ - uint8_t buf_refresh:1; - int teos; /* valid only if tunnel mode & no data left for decoder */ - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - int rmt_resource_released; - - const char *module_name; - unsigned queue_id; - uint16_t dec_id; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audqcelp_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - - int eq_enable; - int eq_needs_commit; - audpp_cmd_cfg_object_params_eqalizer eq; - audpp_cmd_cfg_object_params_volume vol_pan; - struct ion_client *client; - struct ion_handle *input_buff_handle; - struct ion_handle *output_buff_handle; -}; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audpp_cmd_cfg_adec_params(struct audio *audio); -static void audpp_cmd_cfg_routing_mode(struct audio *audio); -static void audqcelp_send_data(struct audio *audio, unsigned needed); -static void audqcelp_config_hostpcm(struct audio *audio); -static void audqcelp_buffer_refresh(struct audio *audio); -static void audqcelp_dsp_event(void *private, unsigned id, uint16_t *msg); -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audqcelp_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); -#endif - -static int rmt_put_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_DISABLE; - cmd.dec_type = AUDDEC_DEC_QCELP; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - - return put_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -static int rmt_get_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_ENABLE; - cmd.dec_type = AUDDEC_DEC_QCELP; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - - return get_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -/* must be called with audio->lock held */ -static int audqcelp_enable(struct audio *audio) -{ - struct audmgr_config cfg; - int rc; - - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) - return 0; - - if (audio->rmt_resource_released == 1) { - audio->rmt_resource_released = 0; - rc = rmt_get_resource(audio); - if (rc) { - MM_ERR("ADSP resources are not available for QCELP \ - session 0x%08x on decoder: %d\n Ignoring \ - error and going ahead with the playback\n", - (int)audio, audio->dec_id); - } - } - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_tail = 0; - audio->out_needed = 0; - - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) { - cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; - cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000; - cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK; - cfg.codec = RPC_AUD_DEF_CODEC_13K; - cfg.snd_method = RPC_SND_METHOD_MIDI; - - rc = audmgr_enable(&audio->audmgr, &cfg); - if (rc < 0) - return rc; - } - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audqcelp_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - audio->enabled = 1; - return 0; -} - -/* must be called with audio->lock held */ -static int audqcelp_disable(struct audio *audio) -{ - int rc = 0; - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - audio->stopped = 1; - wake_up(&audio->write_wait); - wake_up(&audio->read_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - audio->out_needed = 0; - rmt_put_resource(audio); - audio->rmt_resource_released = 1; - } - return rc; -} - -/* ------------------- dsp --------------------- */ -static void audqcelp_update_pcm_buf_entry(struct audio *audio, - uint32_t *payload) -{ - uint8_t index; - unsigned long flags; - - if (audio->rflush) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < payload[1]; index++) { - if (audio->in[audio->fill_next].addr == - payload[2 + index * 2]) { - MM_DBG("in[%d] ready\n", audio->fill_next); - audio->in[audio->fill_next].used = - payload[3 + index * 2]; - if ((++audio->fill_next) == audio->pcm_buf_count) - audio->fill_next = 0; - } else { - MM_ERR("expected=%x ret=%x\n", - audio->in[audio->fill_next].addr, - payload[1 + index * 2]); - break; - } - } - if (audio->in[audio->fill_next].used == 0) { - audqcelp_buffer_refresh(audio); - } else { - MM_DBG("read cannot keep up\n"); - audio->buf_refresh = 1; - } - wake_up(&audio->read_wait); - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - getevent(msg, sizeof(msg)); - - MM_DBG("msg_id=%x\n", id); - - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audqcelp_send_data(audio, 1); - break; - - case AUDPLAY_MSG_BUFFER_UPDATE: - audqcelp_update_pcm_buf_entry(audio, msg); - break; - - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audplaytask)\n"); - break; - - default: - MM_ERR("unexpected message from decoder \n"); - } -} - -static void audqcelp_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status:sleep reason = \ - 0x%04x\n", reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init \n"); - if (audio->pcm_feedback) - audpp_cmd_cfg_routing_mode(audio); - else - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg \n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play \n"); - if (audio->pcm_feedback) { - audqcelp_config_hostpcm(audio); - audqcelp_buffer_refresh(audio); - } - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - default: - MM_ERR("unknown decoder status\n"); - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - audpp_dsp_set_eq(audio->dec_id, audio->eq_enable, - &audio->eq); - audpp_avsync(audio->dec_id, 22050); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audpp_avsync(audio->dec_id, 0); - audio->running = 0; - } else { - MM_DBG("CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_ROUTING_ACK: - MM_DBG("ROUTING_ACK mode=%d\n", msg[1]); - audpp_cmd_cfg_adec_params(audio); - break; - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - audio->rflush = 0; - wake_up(&audio->write_wait); - if (audio->pcm_feedback) - audqcelp_buffer_refresh(audio); - break; - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - default: - MM_ERR("UNKNOWN (%d)\n", id); - } - -} - -struct msm_adsp_ops audplay_adsp_ops_qcelp = { - .event = audplay_dsp_event, -}; - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id, \ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - u16 cfg_dec_cmd[AUDPP_CMD_CFG_DEC_TYPE_LEN / sizeof(unsigned short)]; - - memset(cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - - cfg_dec_cmd[0] = AUDPP_CMD_CFG_DEC_TYPE; - if (enable) - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_QCELP; - else - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} - -static void audpp_cmd_cfg_adec_params(struct audio *audio) -{ - struct audpp_cmd_cfg_adec_params_v13k cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN; - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = 8000; - cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V; - - audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static void audpp_cmd_cfg_routing_mode(struct audio *audio) -{ - struct audpp_cmd_routing_mode cmd; - MM_DBG("\n"); /* Macro prints the file name and function */ - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; - cmd.object_number = audio->dec_id; - if (audio->pcm_feedback) - cmd.routing_mode = ROUTING_MODE_FTRT; - else - cmd.routing_mode = ROUTING_MODE_RT; - audpp_send_queue1(&cmd, sizeof(cmd)); -} - -static int audplay_dsp_send_data_avail(struct audio *audio, - unsigned idx, unsigned len) -{ - struct audplay_cmd_bitstream_data_avail_nt2 cmd; - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2; - if (audio->mfield) - cmd.decoder_id = AUDQCELP_METAFIELD_MASK | - (audio->out[idx].mfield_sz >> 1); - else - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = audio->out[idx].addr; - cmd.buf_size = len / 2; - cmd.partition_number = 0; - /* complete writes to the input buffer */ - wmb(); - return audplay_send_queue0(audio, &cmd, sizeof(cmd)); -} - -static void audqcelp_buffer_refresh(struct audio *audio) -{ - struct audplay_cmd_buffer_refresh refresh_cmd; - - refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; - refresh_cmd.num_buffers = 1; - refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; - refresh_cmd.buf0_length = audio->in[audio->fill_next].size; - refresh_cmd.buf_read_count = 0; - MM_DBG("buf0_addr=%x buf0_len=%d\n", refresh_cmd.buf0_address, - refresh_cmd.buf0_length); - - (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); -} - -static void audqcelp_config_hostpcm(struct audio *audio) -{ - struct audplay_cmd_hpcm_buf_cfg cfg_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; - cfg_cmd.max_buffers = 1; - cfg_cmd.byte_swap = 0; - cfg_cmd.hostpcm_config = (0x8000) | (0x4000); - cfg_cmd.feedback_frequency = 1; - cfg_cmd.partition_number = 0; - - (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); -} - -static void audqcelp_send_data(struct audio *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - MM_DBG("frame %d busy\n", audio->out_tail); - audplay_dsp_send_data_avail(audio, audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } - done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ - -static void audqcelp_flush(struct audio *audio) -{ - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->out_needed = 0; - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audqcelp_flush_pcm_buf(struct audio *audio) -{ - uint8_t index; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < PCM_BUF_MAX_COUNT; index++) - audio->in[index].used = 0; - - audio->buf_refresh = 0; - audio->read_next = 0; - audio->fill_next = 0; - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audqcelp_ioport_reset(struct audio *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audqcelp_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->read_wait); - mutex_lock(&audio->read_lock); - audqcelp_flush_pcm_buf(audio); - mutex_unlock(&audio->read_lock); -} - -static int audqcelp_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audqcelp_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audqcelp_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audqcelp_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audqcelp_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - - -static long audqcelp_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audqcelp_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - audio->event_wait, audqcelp_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audqcelp_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - rc = 0; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audqcelp_event, list); - list_del(&drv_evt->list); - } - - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audio_enable_eq(struct audio *audio, int enable) -{ - if (audio->eq_enable == enable && !audio->eq_needs_commit) - return 0; - - audio->eq_enable = enable; - - if (audio->running) { - audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq); - audio->eq_needs_commit = 0; - } - return 0; -} - -static long audqcelp_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - unsigned long flags = 0; - uint16_t enable_mask; - int enable; - int prev_state; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - int len = 0; - - MM_DBG("cmd = %d\n", cmd); - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = audpp_avsync_byte_count(audio->dec_id); - stats.sample_count = audpp_avsync_sample_count(audio->dec_id); - if (copy_to_user((void *)arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - switch (cmd) { - case AUDIO_ENABLE_AUDPP: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - spin_lock_irqsave(&audio->dsp_lock, flags); - enable = (enable_mask & EQ_ENABLE) ? 1 : 0; - audio_enable_eq(audio, enable); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - case AUDIO_SET_VOLUME: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.volume = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_PAN: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.pan = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_EQ: - prev_state = audio->eq_enable; - audio->eq_enable = 0; - if (copy_from_user(&audio->eq.num_bands, (void *) arg, - sizeof(audio->eq) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) { - rc = -EFAULT; - break; - } - audio->eq_enable = prev_state; - audio->eq_needs_commit = 1; - rc = 0; - break; - } - - if (-EINVAL != rc) - return rc; - - if (cmd == AUDIO_GET_EVENT) { - MM_DBG("AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audqcelp_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audqcelp_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) - rc = -ENODEV; - else - rc = 0; - } - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audqcelp_disable(audio); - audqcelp_ioport_reset(audio); - audio->stopped = 0; - break; - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audqcelp_ioport_reset(audio); - if (audio->running) { - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - case AUDIO_SET_CONFIG:{ - struct msm_audio_config config; - if (copy_from_user(&config, (void *)arg, - sizeof(config))) { - rc = -EFAULT; - break; - } - audio->mfield = config.meta_field; - MM_DBG("AUDIO_SET_CONFIG applicable \ - for metafield configuration\n"); - rc = 0; - break; - } - case AUDIO_GET_CONFIG:{ - struct msm_audio_config config; - config.buffer_size = BUFSZ; - config.buffer_count = BUF_COUNT; - config.sample_rate = 8000; - config.channel_count = 1; - config.meta_field = 0; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - - break; - } - case AUDIO_GET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - - config.pcm_feedback = audio->pcm_feedback; - config.buffer_count = PCM_BUF_MAX_COUNT; - config.buffer_size = PCM_BUFSZ_MIN; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - - if (copy_from_user(&config, (void *)arg, - sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.pcm_feedback != audio->pcm_feedback) { - MM_ERR("Not sufficient permission to" - "change the playback mode\n"); - rc = -EACCES; - break; - } - if ((config.buffer_count > PCM_BUF_MAX_COUNT) || - (config.buffer_count == 1)) - config.buffer_count = PCM_BUF_MAX_COUNT; - - if (config.buffer_size < PCM_BUFSZ_MIN) - config.buffer_size = PCM_BUFSZ_MIN; - - /* Check if pcm feedback is required */ - if ((config.pcm_feedback) && (!audio->read_data)) { - MM_DBG("allocate PCM buf %d\n", - config.buffer_count * config.buffer_size); - handle = ion_alloc(audio->client, - (config.buffer_size * - config.buffer_count), - SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to alloc I/P buffs\n"); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - break; - } - - audio->input_buff_handle = handle; - - rc = ion_phys(audio->client , - handle, &addr, &len); - if (rc) { - MM_ERR("Invalid phy: %x sz: %x\n", - (unsigned int) addr, - (unsigned int) len); - ion_free(audio->client, handle); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - break; - } else { - MM_INFO("Got valid phy: %x sz: %x\n", - (unsigned int) audio->read_phys, - (unsigned int) len); - } - audio->read_phys = (int32_t)addr; - - rc = ion_handle_get_flags(audio->client, - handle, &ionflag); - if (rc) { - MM_ERR("could not get flags\n"); - ion_free(audio->client, handle); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - break; - } - audio->map_v_read = ion_map_kernel( - audio->client, handle); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("failed to map read buf\n"); - ion_free(audio->client, handle); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - } else { - uint8_t index; - uint32_t offset = 0; - audio->read_data = - audio->map_v_read; - audio->buf_refresh = 0; - audio->pcm_buf_count = - config.buffer_count; - audio->read_next = 0; - audio->fill_next = 0; - - for (index = 0; - index < config.buffer_count; index++) { - audio->in[index].data = - audio->read_data + offset; - audio->in[index].addr = - audio->read_phys + offset; - audio->in[index].size = - config.buffer_size; - audio->in[index].used = 0; - offset += config.buffer_size; - } - MM_DBG("read buf: phy addr 0x%08x \ - kernel addr 0x%08x\n", - audio->read_phys, - (int)audio->read_data); - rc = 0; - } - } else { - rc = 0; - } - break; - } - case AUDIO_PAUSE: - MM_DBG("AUDIO_PAUSE %ld\n", arg); - rc = audpp_pause(audio->dec_id, (int) arg); - break; - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -static int audqcelp_fsync(struct file *file, loff_t a, loff_t b, - int datasync) -{ - struct audio *audio = file->private_data; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - if (!audio->running || audio->pcm_feedback) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush); - - if (audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; -} - -static ssize_t audqcelp_read(struct file *file, char __user *buf, size_t count, - loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - int rc = 0; - - if (!audio->pcm_feedback) - return 0; /* PCM feedback is not enabled. Nothing to read */ - - mutex_lock(&audio->read_lock); - MM_DBG("%d\n", count); - while (count > 0) { - rc = wait_event_interruptible(audio->read_wait, - (audio->in[audio->read_next].used > 0) || - (audio->stopped) || (audio->rflush)); - if (rc < 0) - break; - - if (audio->stopped || audio->rflush) { - rc = -EBUSY; - break; - } - - if (count < audio->in[audio->read_next].used) { - /* Read must happen in frame boundary. Since driver does - not know frame size, read count must be greater or equal - to size of PCM samples */ - MM_DBG("read stop - partial frame\n"); - break; - } else { - MM_DBG("read from in[%d]\n", audio->read_next); - /* order reads from the output buffer */ - rmb(); - if (copy_to_user(buf, - audio->in[audio->read_next].data, - audio->in[audio->read_next].used)) { - MM_ERR("invalid addr %x\n", (unsigned int)buf); - rc = -EFAULT; - break; - } - count -= audio->in[audio->read_next].used; - buf += audio->in[audio->read_next].used; - audio->in[audio->read_next].used = 0; - if ((++audio->read_next) == audio->pcm_buf_count) - audio->read_next = 0; - break; - /* Force to exit while loop - * to prevent output thread - * sleep too long if data is - * not ready at this moment. - */ - } - } - - /* don't feed output buffer to HW decoder during flushing - * buffer refresh command will be sent once flush completes - * send buf refresh command here can confuse HW decoder - */ - if (audio->buf_refresh && !audio->rflush) { - audio->buf_refresh = 0; - MM_DBG("kick start pcm feedback again\n"); - audqcelp_buffer_refresh(audio); - } - - mutex_unlock(&audio->read_lock); - - if (buf > start) - rc = buf - start; - - MM_DBG("read %d bytes\n", rc); - return rc; -} - -static int audqcelp_process_eos(struct audio *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - struct buffer *frame; - int rc = 0; - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - audqcelp_send_data(audio, 0); - -done: - return rc; -} - -static ssize_t audqcelp_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - char *cpy_ptr; - int rc = 0, eos_condition = AUDQCELP_EOS_NONE; - unsigned short mfield_size = 0; - - MM_DBG("cnt=%d\n", count); - - if (count & 1) - return -EINVAL; - - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - cpy_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - MM_DBG("buffer available\n"); - if (rc < 0) - break; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - break; - } - - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - break; - } else if (mfield_size > count) { - rc = -EINVAL; - break; - } - MM_DBG("mf offset_val %x\n", mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - break; - } - /* Check if EOS flag is set and buffer has - * contains just meta field - */ - if (cpy_ptr[AUDQCELP_EOS_FLG_OFFSET] & - AUDQCELP_EOS_FLG_MASK) { - MM_DBG("EOS SET\n"); - eos_condition = AUDQCELP_EOS_SET; - if (mfield_size == count) { - buf += mfield_size; - break; - } else - cpy_ptr[AUDQCELP_EOS_FLG_OFFSET] &= - ~AUDQCELP_EOS_FLG_MASK; - } - cpy_ptr += mfield_size; - count -= mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - - xfer = (count > (frame->size - mfield_size)) ? - (frame->size - mfield_size) : count; - if (copy_from_user(cpy_ptr, buf, xfer)) { - rc = -EFAULT; - break; - } - - frame->used = xfer + mfield_size; - audio->out_head ^= 1; - count -= xfer; - buf += xfer; - audqcelp_send_data(audio, 0); - } - if (eos_condition == AUDQCELP_EOS_SET) - rc = audqcelp_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - if (!rc) { - if (buf > start) - return buf - start; - } - return rc; -} - -static int audqcelp_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_INFO("audio instance 0x%08x freeing\n", (int) audio); - mutex_lock(&audio->lock); - audqcelp_disable(audio); - if (audio->rmt_resource_released == 0) - rmt_put_resource(audio); - audqcelp_flush(audio); - audqcelp_flush_pcm_buf(audio); - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->opened = 0; - audio->event_abort = 1; - wake_up(&audio->event_wait); - audqcelp_reset_event_queue(audio); - ion_unmap_kernel(audio->client, audio->output_buff_handle); - ion_free(audio->client, audio->output_buff_handle); - if (audio->input_buff_handle != NULL) { - ion_unmap_kernel(audio->client, audio->input_buff_handle); - ion_free(audio->client, audio->input_buff_handle); - } - ion_client_destroy(audio->client); - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - kfree(audio); - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audqcelp_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audqcelp_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audqcelp_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audqcelp_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -static void audqcelp_suspend(struct early_suspend *h) -{ - struct audqcelp_suspend_ctl *ctl = - container_of(h, struct audqcelp_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audqcelp_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audqcelp_resume(struct early_suspend *h) -{ - struct audqcelp_suspend_ctl *ctl = - container_of(h, struct audqcelp_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audqcelp_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audqcelp_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audqcelp_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 1024; - static char buffer[1024]; - int n = 0, i; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_feedback %d\n", audio->pcm_feedback); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_buf_sz %d\n", audio->out[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_count %d \n", audio->pcm_buf_count); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_sz %d \n", audio->in[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %x \n", audio->vol_pan.volume); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "rflush %d\n", audio->rflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d \n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d \n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d \n", audio->out_needed); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_head %d \n", audio->out_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_tail %d \n", audio->out_tail); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[0].used %d \n", audio->out[0].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[1].used %d \n", audio->out[1].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "buffer_refresh %d \n", audio->buf_refresh); - n += scnprintf(buffer + n, debug_bufmax - n, - "read_next %d \n", audio->read_next); - n += scnprintf(buffer + n, debug_bufmax - n, - "fill_next %d \n", audio->fill_next); - for (i = 0; i < audio->pcm_buf_count; i++) - n += scnprintf(buffer + n, debug_bufmax - n, - "in[%d].size %d \n", i, audio->in[i].used); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audqcelp_debug_fops = { - .read = audqcelp_debug_read, - .open = audqcelp_debug_open, -}; -#endif - -static int audqcelp_open(struct inode *inode, struct file *file) -{ - struct audio *audio = NULL; - int rc, dec_attrb, decid, i; - struct audqcelp_event *e_node = NULL; - unsigned mem_sz = DMASZ; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - struct ion_client *client = NULL; - int len = 0; -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_qcelp_" + 5]; -#endif - - /* Create audio instance, set to zero */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("no memory to allocate audio instance\n"); - rc = -ENOMEM; - goto done; - } - MM_INFO("audio instance 0x%08x created\n", (int)audio); - - /* Allocate the decoder */ - dec_attrb = AUDDEC_DEC_QCELP; - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_NONTUNNEL; - audio->pcm_feedback = NON_TUNNEL_MODE_PLAYBACK; - } else if ((file->f_mode & FMODE_WRITE) && - !(file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_TUNNEL; - audio->pcm_feedback = TUNNEL_MODE_PLAYBACK; - } else { - kfree(audio); - rc = -EACCES; - goto done; - } - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - if (decid < 0) { - MM_ERR("No free decoder available, freeing instance 0x%08x\n", - (int)audio); - rc = -ENODEV; - kfree(audio); - goto done; - } - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - client = msm_ion_client_create(UINT_MAX, "Audio_QCELP_Client"); - if (IS_ERR_OR_NULL(client)) { - pr_err("Unable to create ION client\n"); - rc = -ENOMEM; - goto client_create_error; - } - audio->client = client; - - handle = ion_alloc(client, mem_sz, SZ_4K, - ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to create allocate O/P buffers\n"); - rc = -ENOMEM; - goto output_buff_alloc_error; - } - audio->output_buff_handle = handle; - - rc = ion_phys(client, handle, &addr, &len); - if (rc) { - MM_ERR("O/P buffers:Invalid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - goto output_buff_get_phys_error; - } else { - MM_INFO("O/P buffers:valid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - } - audio->phys = (int32_t)addr; - - - rc = ion_handle_get_flags(client, handle, &ionflag); - if (rc) { - MM_ERR("could not get flags for the handle\n"); - goto output_buff_get_flags_error; - } - - audio->map_v_write = ion_map_kernel(client, handle); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write buffers\n"); - rc = -ENOMEM; - goto output_buff_map_error; - } - audio->data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->phys, (int)audio->data); - - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) { - rc = audmgr_open(&audio->audmgr); - if (rc) { - MM_ERR("audmgr open failed, freeing instance \ - 0x%08x\n", (int)audio); - goto err; - } - } - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audplay_adsp_ops_qcelp, audio); - if (rc) { - MM_ERR("failed to get %s module, freeing instance 0x%08x\n", - audio->module_name, (int)audio); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_close(&audio->audmgr); - goto err; - } - - rc = rmt_get_resource(audio); - if (rc) { - MM_ERR("ADSP resources are not available for QCELP session \ - 0x%08x on decoder: %d\n", (int)audio, audio->dec_id); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_close(&audio->audmgr); - msm_adsp_put(audio->audplay); - goto err; - } - - audio->input_buff_handle = NULL; - - /* Initialize all locks of audio instance */ - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->read_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - init_waitqueue_head(&audio->write_wait); - init_waitqueue_head(&audio->read_wait); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - spin_lock_init(&audio->event_queue_lock); - - /* Initialize buffer */ - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = BUFSZ; - - audio->out[1].data = audio->data + BUFSZ; - audio->out[1].addr = audio->phys + BUFSZ; - audio->out[1].size = BUFSZ; - - audio->vol_pan.volume = 0x2000; - - audqcelp_flush(audio); - - file->private_data = audio; - audio->opened = 1; -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_qcelp_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, &audqcelp_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audqcelp_resume; - audio->suspend_ctl.node.suspend = audqcelp_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (i = 0; i < AUDQCELP_EVENT_NUM; i++) { - e_node = kmalloc(sizeof(struct audqcelp_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } -done: - return rc; -err: - ion_unmap_kernel(client, audio->output_buff_handle); -output_buff_map_error: -output_buff_get_phys_error: -output_buff_get_flags_error: - ion_free(client, audio->output_buff_handle); -output_buff_alloc_error: - ion_client_destroy(client); -client_create_error: - audpp_adec_free(audio->dec_id); - kfree(audio); - return rc; -} - -static const struct file_operations audio_qcelp_fops = { - .owner = THIS_MODULE, - .open = audqcelp_open, - .release = audqcelp_release, - .read = audqcelp_read, - .write = audqcelp_write, - .unlocked_ioctl = audqcelp_ioctl, - .fsync = audqcelp_fsync, -}; - -struct miscdevice audio_qcelp_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_qcelp", - .fops = &audio_qcelp_fops, -}; - -static int __init audqcelp_init(void) -{ - return misc_register(&audio_qcelp_misc); -} - -static void __exit audqcelp_exit(void) -{ - misc_deregister(&audio_qcelp_misc); -} - -module_init(audqcelp_init); -module_exit(audqcelp_exit); - -MODULE_DESCRIPTION("MSM QCELP 13K driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c b/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c deleted file mode 100644 index 0b1775ed4a9dc8d5d1405d26753382b266b11e86..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c +++ /dev/null @@ -1,1471 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/audio_qcelp_in.c - * - * qcelp audio input device - * - * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. - * - * This code is based in part on arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c, - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include "audmgr.h" - -#include -#include -#include -#include -#include -#include - -#define FRAME_HEADER_SIZE 8 /* 8 bytes frame header */ -#define NT_FRAME_HEADER_SIZE 24 /* 24 bytes frame header */ -/* FRAME_NUM must be a power of two */ -#define FRAME_NUM 8 -#define QCELP_FRAME_SIZE 36 /* 36 bytes data */ -/*Tunnel mode : 36 bytes data + 8 byte header*/ -#define FRAME_SIZE (QCELP_FRAME_SIZE + FRAME_HEADER_SIZE) - /* 36 bytes data + 24 meta field*/ -#define NT_FRAME_SIZE (QCELP_FRAME_SIZE + NT_FRAME_HEADER_SIZE) -#define DMASZ (FRAME_SIZE * FRAME_NUM) -#define NT_DMASZ (NT_FRAME_SIZE * FRAME_NUM) -#define OUT_FRAME_NUM 2 -#define OUT_BUFFER_SIZE (4 * 1024 + NT_FRAME_HEADER_SIZE) -#define BUFFER_SIZE (OUT_BUFFER_SIZE * OUT_FRAME_NUM) - -/* Offset from beginning of buffer*/ -#define AUDPREPROC_QCELP_EOS_FLG_OFFSET 0x0A -#define AUDPREPROC_QCELP_EOS_FLG_MASK 0x01 -#define AUDPREPROC_QCELP_EOS_NONE 0x0 /* No EOS detected */ -#define AUDPREPROC_QCELP_EOS_SET 0x1 /* EOS set in meta field */ - -struct buffer { - void *data; - uint32_t size; - uint32_t read; - uint32_t addr; - uint32_t used; - uint32_t mfield_sz; -}; - -struct audio_qcelp_in { - struct buffer in[FRAME_NUM]; - - spinlock_t dsp_lock; - - atomic_t in_bytes; - atomic_t in_samples; - - struct mutex lock; - struct mutex read_lock; - wait_queue_head_t wait; - wait_queue_head_t wait_enable; - /*write section*/ - struct buffer out[OUT_FRAME_NUM]; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - uint32_t out_count; - - struct mutex write_lock; - wait_queue_head_t write_wait; - int32_t out_phys; /* physical address of write buffer */ - char *out_data; - int mfield; /* meta field embedded in data */ - int wflush; /*write flush */ - int rflush; /*read flush*/ - int out_frame_cnt; - - struct msm_adsp_module *audrec; - struct msm_adsp_module *audpre; - - - /* configuration to use on next enable */ - uint32_t samp_rate; - uint32_t channel_mode; - uint32_t buffer_size; /* Frame size (36 bytes) */ - uint32_t enc_type; /* 11 for QCELP */ - uint32_t mode; /* T or NT Mode*/ - - struct msm_audio_qcelp_enc_config cfg; - - uint32_t dsp_cnt; - uint32_t in_head; /* next buffer dsp will write */ - uint32_t in_tail; /* next buffer read() will read */ - uint32_t in_count; /* number of buffers available to read() */ - - uint32_t eos_ack; - uint32_t flush_ack; - - const char *module_name; - unsigned queue_ids; - uint16_t enc_id; /* Session Id */ - - unsigned short samp_rate_index; - uint32_t audrec_obj_idx ; - - struct audmgr audmgr; - - /* data allocated for various buffers */ - char *data; - dma_addr_t phys; - - void *map_v_read; - void *map_v_write; - - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - struct ion_client *client; - struct ion_handle *input_buff_handle; - struct ion_handle *output_buff_handle; -}; - -struct audio_frame { - uint16_t frame_count_lsw; - uint16_t frame_count_msw; - uint16_t frame_length; - uint16_t erased_pcm; - unsigned char raw_bitstream[]; -} __packed; - -struct audio_frame_nt { - uint16_t metadata_len; - uint16_t frame_count_lsw; - uint16_t frame_count_msw; - uint16_t frame_length; - uint16_t erased_pcm; - uint16_t reserved; - uint16_t time_stamp_dword_lsw; - uint16_t time_stamp_dword_msw; - uint16_t time_stamp_lsw; - uint16_t time_stamp_msw; - uint16_t nflag_lsw; - uint16_t nflag_msw; - unsigned char raw_bitstream[]; /* samples */ -} __packed; - -struct qcelp_encoded_meta_out { - uint16_t metadata_len; - uint16_t time_stamp_dword_lsw; - uint16_t time_stamp_dword_msw; - uint16_t time_stamp_lsw; - uint16_t time_stamp_msw; - uint16_t nflag_lsw; - uint16_t nflag_msw; -}; - -/* Audrec Queue command sent macro's */ -#define audio_send_queue_pre(audio, cmd, len) \ - msm_adsp_write(audio->audpre, QDSP_uPAudPreProcCmdQueue, cmd, len) - -#define audio_send_queue_recbs(audio, cmd, len) \ - msm_adsp_write(audio->audrec, ((audio->queue_ids & 0xFFFF0000) >> 16),\ - cmd, len) -#define audio_send_queue_rec(audio, cmd, len) \ - msm_adsp_write(audio->audrec, (audio->queue_ids & 0x0000FFFF),\ - cmd, len) - -static int audqcelp_in_dsp_enable(struct audio_qcelp_in *audio, int enable); -static int audqcelp_in_encparam_config(struct audio_qcelp_in *audio); -static int audqcelp_in_encmem_config(struct audio_qcelp_in *audio); -static int audqcelp_in_dsp_read_buffer(struct audio_qcelp_in *audio, - uint32_t read_cnt); -static void audqcelp_in_flush(struct audio_qcelp_in *audio); - -static void audqcelp_in_get_dsp_frames(struct audio_qcelp_in *audio); -static int audpcm_config(struct audio_qcelp_in *audio); -static void audqcelp_out_flush(struct audio_qcelp_in *audio); -static int audqcelp_in_routing_mode_config(struct audio_qcelp_in *audio); -static void audrec_pcm_send_data(struct audio_qcelp_in *audio, unsigned needed); -static void audqcelp_nt_in_get_dsp_frames(struct audio_qcelp_in *audio); -static void audqcelp_in_flush(struct audio_qcelp_in *audio); - -static unsigned convert_samp_index(unsigned index) -{ - switch (index) { - case RPC_AUD_DEF_SAMPLE_RATE_48000: return 48000; - case RPC_AUD_DEF_SAMPLE_RATE_44100: return 44100; - case RPC_AUD_DEF_SAMPLE_RATE_32000: return 32000; - case RPC_AUD_DEF_SAMPLE_RATE_24000: return 24000; - case RPC_AUD_DEF_SAMPLE_RATE_22050: return 22050; - case RPC_AUD_DEF_SAMPLE_RATE_16000: return 16000; - case RPC_AUD_DEF_SAMPLE_RATE_12000: return 12000; - case RPC_AUD_DEF_SAMPLE_RATE_11025: return 11025; - case RPC_AUD_DEF_SAMPLE_RATE_8000: return 8000; - default: return 11025; - } -} - -/* must be called with audio->lock held */ -static int audqcelp_in_enable(struct audio_qcelp_in *audio) -{ - struct audmgr_config cfg; - int rc; - - if (audio->enabled) - return 0; - - cfg.tx_rate = audio->samp_rate; - cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; - cfg.def_method = RPC_AUD_DEF_METHOD_RECORD; - cfg.codec = RPC_AUD_DEF_CODEC_13K; - cfg.snd_method = RPC_SND_METHOD_MIDI; - - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - rc = audmgr_enable(&audio->audmgr, &cfg); - if (rc < 0) - return rc; - - if (msm_adsp_enable(audio->audpre)) { - audmgr_disable(&audio->audmgr); - MM_ERR("msm_adsp_enable(audpre) failed\n"); - return -ENODEV; - } - } - if (msm_adsp_enable(audio->audrec)) { - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - audmgr_disable(&audio->audmgr); - msm_adsp_disable(audio->audpre); - } - MM_ERR("msm_adsp_enable(audrec) failed\n"); - return -ENODEV; - } - - audio->enabled = 1; - audqcelp_in_dsp_enable(audio, 1); - - return 0; -} - -/* must be called with audio->lock held */ -static int audqcelp_in_disable(struct audio_qcelp_in *audio) -{ - if (audio->enabled) { - audio->enabled = 0; - - audqcelp_in_dsp_enable(audio, 0); - - wait_event_interruptible_timeout(audio->wait_enable, - audio->running == 0, 1*HZ); - audio->stopped = 1; - wake_up(&audio->wait); - msm_adsp_disable(audio->audrec); - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - msm_adsp_disable(audio->audpre); - audmgr_disable(&audio->audmgr); - } - } - return 0; -} - -/* ------------------- dsp --------------------- */ -static void audpre_dsp_event(void *data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - uint16_t msg[2]; - getevent(msg, sizeof(msg)); - - switch (id) { - case AUDPREPROC_MSG_CMD_CFG_DONE_MSG: - MM_DBG("type %d, status_flag %d\n", msg[0], msg[1]); - break; - case AUDPREPROC_MSG_ERROR_MSG_ID: - MM_ERR("err_index %d\n", msg[0]); - break; - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audpreproctask)\n"); - break; - default: - MM_ERR("unknown event %d\n", id); - } -} - -static void audqcelp_in_get_dsp_frames(struct audio_qcelp_in *audio) -{ - struct audio_frame *frame; - uint32_t index; - unsigned long flags; - - index = audio->in_head; - - frame = (void *) (((char *)audio->in[index].data) - - sizeof(*frame)); - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->in[index].size = frame->frame_length; - - /* statistics of read */ - atomic_add(audio->in[index].size, &audio->in_bytes); - atomic_add(1, &audio->in_samples); - - audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1); - - /* If overflow, move the tail index foward. */ - if (audio->in_head == audio->in_tail) { - MM_ERR("Error! not able to keep up the read\n"); - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - MM_ERR("in_count = %d\n", audio->in_count); - } else - audio->in_count++; - - audqcelp_in_dsp_read_buffer(audio, audio->dsp_cnt++); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - - wake_up(&audio->wait); -} - -static void audqcelp_nt_in_get_dsp_frames(struct audio_qcelp_in *audio) -{ - struct audio_frame_nt *nt_frame; - uint32_t index; - unsigned long flags; - - index = audio->in_head; - nt_frame = (void *) (((char *)audio->in[index].data) - \ - sizeof(struct audio_frame_nt)); - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->in[index].size = nt_frame->frame_length; - /* statistics of read */ - atomic_add(audio->in[index].size, &audio->in_bytes); - atomic_add(1, &audio->in_samples); - - audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1); - - /* If overflow, move the tail index foward. */ - if (audio->in_head == audio->in_tail) - MM_DBG("Error! not able to keep up the read\n"); - else - audio->in_count++; - - spin_unlock_irqrestore(&audio->dsp_lock, flags); - wake_up(&audio->wait); -} - -static int audrec_pcm_buffer_ptr_refresh(struct audio_qcelp_in *audio, - unsigned idx, unsigned len) -{ - struct audrec_cmd_pcm_buffer_ptr_refresh_arm_enc cmd; - - if (len == NT_FRAME_HEADER_SIZE) - len = len / 2; - else - len = (len + NT_FRAME_HEADER_SIZE) / 2; - MM_DBG("len = %d\n", len); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_PCM_BUFFER_PTR_REFRESH_ARM_TO_ENC; - cmd.num_buffers = 1; - if (cmd.num_buffers == 1) { - cmd.buf_address_length[0] = (audio->out[idx].addr & - 0xffff0000) >> 16; - cmd.buf_address_length[1] = (audio->out[idx].addr & - 0x0000ffff); - cmd.buf_address_length[2] = (len & 0xffff0000) >> 16; - cmd.buf_address_length[3] = (len & 0x0000ffff); - } - audio->out_frame_cnt++; - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audpcm_config(struct audio_qcelp_in *audio) -{ - struct audrec_cmd_pcm_cfg_arm_to_enc cmd; - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_PCM_CFG_ARM_TO_ENC; - cmd.config_update_flag = AUDREC_PCM_CONFIG_UPDATE_FLAG_ENABLE; - cmd.enable_flag = AUDREC_ENABLE_FLAG_VALUE; - cmd.sampling_freq = convert_samp_index(audio->samp_rate); - if (!audio->channel_mode) - cmd.channels = 1; - else - cmd.channels = 2; - cmd.frequency_of_intimation = 1; - cmd.max_number_of_buffers = OUT_FRAME_NUM; - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - - -static int audqcelp_in_routing_mode_config(struct audio_qcelp_in *audio) -{ - struct audrec_cmd_routing_mode cmd; - - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_ROUTING_MODE; - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) - cmd.routing_mode = 1; - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static void audrec_dsp_event(void *data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - struct audio_qcelp_in *audio = NULL; - - if (data) - audio = data; - else { - MM_ERR("invalid data for event %x\n", id); - return; - } - - switch (id) { - case AUDREC_MSG_CMD_CFG_DONE_MSG: { - struct audrec_msg_cmd_cfg_done_msg cmd_cfg_done_msg; - getevent(&cmd_cfg_done_msg, AUDREC_MSG_CMD_CFG_DONE_MSG_LEN); - if (cmd_cfg_done_msg.audrec_enc_type & \ - AUDREC_MSG_CFG_DONE_ENC_ENA) { - audio->audrec_obj_idx = cmd_cfg_done_msg.audrec_obj_idx; - MM_DBG("CFG ENABLED\n"); - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) { - MM_DBG("routing command\n"); - audqcelp_in_routing_mode_config(audio); - } else { - audqcelp_in_encmem_config(audio); - } - } else { - MM_DBG("CFG SLEEP\n"); - audio->running = 0; - wake_up(&audio->wait_enable); - } - break; - } - case AUDREC_MSG_CMD_ROUTING_MODE_DONE_MSG: { - struct audrec_msg_cmd_routing_mode_done_msg \ - routing_msg; - getevent(&routing_msg, AUDREC_MSG_CMD_ROUTING_MODE_DONE_MSG); - MM_DBG("AUDREC_MSG_CMD_ROUTING_MODE_DONE_MSG"); - if (routing_msg.configuration == 0) { - MM_ERR("routing configuration failed\n"); - audio->running = 0; - wake_up(&audio->wait_enable); - } else - audqcelp_in_encmem_config(audio); - break; - } - case AUDREC_MSG_CMD_AREC_MEM_CFG_DONE_MSG: { - MM_DBG("AREC_MEM_CFG_DONE_MSG\n"); - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - audqcelp_in_encparam_config(audio); - else - audpcm_config(audio); - break; - } - case AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG: { - MM_DBG("AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG"); - audqcelp_in_encparam_config(audio); - break; - } - case AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG: { - MM_DBG("AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG\n"); - audio->running = 1; - wake_up(&audio->wait_enable); - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) - audrec_pcm_send_data(audio, 1); - break; - } - case AUDREC_CMD_PCM_BUFFER_PTR_UPDATE_ARM_TO_ENC_MSG: { - MM_DBG("ptr_update recieved from DSP\n"); - audrec_pcm_send_data(audio, 1); - break; - } - case AUDREC_MSG_NO_EXT_PKT_AVAILABLE_MSG: { - struct audrec_msg_no_ext_pkt_avail_msg err_msg; - getevent(&err_msg, AUDREC_MSG_NO_EXT_PKT_AVAILABLE_MSG_LEN); - MM_DBG("NO_EXT_PKT_AVAILABLE_MSG %x\n",\ - err_msg.audrec_err_id); - break; - } - case AUDREC_MSG_PACKET_READY_MSG: { - struct audrec_msg_packet_ready_msg pkt_ready_msg; - - getevent(&pkt_ready_msg, AUDREC_MSG_PACKET_READY_MSG_LEN); - MM_DBG("UP_PACKET_READY_MSG: write cnt msw %d \ - write cnt lsw %d read cnt msw %d read cnt lsw %d \n",\ - pkt_ready_msg.pkt_counter_msw, \ - pkt_ready_msg.pkt_counter_lsw, \ - pkt_ready_msg.pkt_read_cnt_msw, \ - pkt_ready_msg.pkt_read_cnt_lsw); - - audqcelp_in_get_dsp_frames(audio); - break; - } - case AUDREC_UP_NT_PACKET_READY_MSG: { - struct audrec_up_nt_packet_ready_msg pkt_ready_msg; - - getevent(&pkt_ready_msg, AUDREC_UP_NT_PACKET_READY_MSG_LEN); - MM_DBG("UP_NT_PACKET_READY_MSG: write cnt lsw %d \ - write cnt msw %d read cnt lsw %d read cnt msw %d \n",\ - pkt_ready_msg.audrec_packetwrite_cnt_lsw, \ - pkt_ready_msg.audrec_packetwrite_cnt_msw, \ - pkt_ready_msg.audrec_upprev_readcount_lsw, \ - pkt_ready_msg.audrec_upprev_readcount_msw); - - audqcelp_nt_in_get_dsp_frames(audio); - break; - } - case AUDREC_CMD_FLUSH_DONE_MSG: { - audio->wflush = 0; - audio->rflush = 0; - audio->flush_ack = 1; - wake_up(&audio->write_wait); - MM_DBG("flush ack recieved\n"); - break; - } - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module \ - enable/disable(audrectask)\n"); - break; - default: - MM_ERR("unknown event %d\n", id); - } -} - -static struct msm_adsp_ops audpre_qcelp_adsp_ops = { - .event = audpre_dsp_event, -}; - -static struct msm_adsp_ops audrec_qcelp_adsp_ops = { - .event = audrec_dsp_event, -}; - -static int audqcelp_in_dsp_enable(struct audio_qcelp_in *audio, int enable) -{ - struct audrec_cmd_enc_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_ENC_CFG; - cmd.audrec_enc_type = (audio->enc_type & 0xFF) | - (enable ? AUDREC_CMD_ENC_ENA : AUDREC_CMD_ENC_DIS); - /* Don't care */ - cmd.audrec_obj_idx = audio->audrec_obj_idx; - - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audqcelp_in_encmem_config(struct audio_qcelp_in *audio) -{ - struct audrec_cmd_arecmem_cfg cmd; - uint16_t *data = (void *) audio->data; - int n; - int header_len = 0; - - memset(&cmd, 0, sizeof(cmd)); - - cmd.cmd_id = AUDREC_CMD_ARECMEM_CFG; - cmd.audrec_obj_idx = audio->audrec_obj_idx; - /* Rate at which packet complete message comes */ - cmd.audrec_up_pkt_intm_cnt = 1; - cmd.audrec_extpkt_buffer_msw = audio->phys >> 16; - cmd.audrec_extpkt_buffer_lsw = audio->phys; - /* Max Buffer no available for frames */ - cmd.audrec_extpkt_buffer_num = FRAME_NUM; - - /* prepare buffer pointers: - * T:36 bytes qcelp packet + 4 halfword header - * NT:36 bytes qcelp packet + 12 halfword header - */ - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - header_len = FRAME_HEADER_SIZE/2; - else - header_len = NT_FRAME_HEADER_SIZE/2; - - for (n = 0; n < FRAME_NUM; n++) { - audio->in[n].data = data + header_len; - data += (QCELP_FRAME_SIZE/2) + header_len; - MM_DBG("0x%8x\n", (int)(audio->in[n].data - header_len*2)); - } - - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audqcelp_in_encparam_config(struct audio_qcelp_in *audio) -{ - struct audrec_cmd_arecparam_qcelp_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDREC_CMD_ARECPARAM_CFG; - cmd.common.audrec_obj_idx = audio->audrec_obj_idx; - cmd.enc_min_rate = audio->cfg.min_bit_rate; - cmd.enc_max_rate = audio->cfg.max_bit_rate; - cmd.rate_modulation_cmd = 0; /* Default set to 0 */ - cmd.reduced_rate_level = 0; /* Default set to 0 */ - - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audqcelp_flush_command(struct audio_qcelp_in *audio) -{ - struct audrec_cmd_flush cmd; - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_FLUSH; - return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); -} - -static int audqcelp_in_dsp_read_buffer(struct audio_qcelp_in *audio, - uint32_t read_cnt) -{ - audrec_cmd_packet_ext_ptr cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_PACKET_EXT_PTR; - cmd.type = audio->audrec_obj_idx; - cmd.curr_rec_count_msw = read_cnt >> 16; - cmd.curr_rec_count_lsw = read_cnt; - - return audio_send_queue_recbs(audio, &cmd, sizeof(cmd)); -} - -/* ------------------- device --------------------- */ - -static void audqcelp_ioport_reset(struct audio_qcelp_in *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->wait); - mutex_lock(&audio->read_lock); - audqcelp_in_flush(audio); - mutex_unlock(&audio->read_lock); - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audqcelp_out_flush(audio); - mutex_unlock(&audio->write_lock); -} - -static void audqcelp_in_flush(struct audio_qcelp_in *audio) -{ - int i; - unsigned long flags; - - audio->eos_ack = 0; - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->dsp_cnt = 0; - audio->in_head = 0; - audio->in_tail = 0; - audio->in_count = 0; - for (i = FRAME_NUM-1; i >= 0; i--) { - audio->in[i].size = 0; - audio->in[i].read = 0; - } - spin_unlock_irqrestore(&audio->dsp_lock, flags); - MM_DBG("in_bytes %d\n", atomic_read(&audio->in_bytes)); - MM_DBG("in_samples %d\n", atomic_read(&audio->in_samples)); - atomic_set(&audio->in_bytes, 0); - atomic_set(&audio->in_samples, 0); -} - -static void audqcelp_out_flush(struct audio_qcelp_in *audio) -{ - int i; - unsigned long flags; - - audio->out_head = 0; - audio->out_count = 0; - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->out_tail = 0; - for (i = OUT_FRAME_NUM-1; i >= 0; i--) { - audio->out[i].size = 0; - audio->out[i].read = 0; - audio->out[i].used = 0; - } - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ -static long audqcelp_in_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct audio_qcelp_in *audio = file->private_data; - int rc = 0; - - MM_DBG("\n"); - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = atomic_read(&audio->in_bytes); - stats.sample_count = atomic_read(&audio->in_samples); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return rc; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: { - rc = audqcelp_in_enable(audio); - if (!rc) { - rc = - wait_event_interruptible_timeout(audio->wait_enable, - audio->running != 0, 1*HZ); - MM_DBG("state %d rc = %d\n", audio->running, rc); - - if (audio->running == 0) - rc = -ENODEV; - else - rc = 0; - } - audio->stopped = 0; - break; - } - case AUDIO_STOP: { - rc = audqcelp_in_disable(audio); - break; - } - case AUDIO_FLUSH: { - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audqcelp_ioport_reset(audio); - if (audio->running) { - audqcelp_flush_command(audio); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config cfg; - memset(&cfg, 0, sizeof(cfg)); - cfg.buffer_size = OUT_BUFFER_SIZE; - cfg.buffer_count = OUT_FRAME_NUM; - cfg.sample_rate = convert_samp_index(audio->samp_rate); - cfg.channel_count = 1; - cfg.type = 0; - cfg.unused[0] = 0; - cfg.unused[1] = 0; - cfg.unused[2] = 0; - if (copy_to_user((void *) arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_GET_STREAM_CONFIG: { - struct msm_audio_stream_config cfg; - memset(&cfg, 0, sizeof(cfg)); - cfg.buffer_size = audio->buffer_size; - cfg.buffer_count = FRAME_NUM; - if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_STREAM_CONFIG: { - struct msm_audio_stream_config cfg; - if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - /* Allow only single frame */ - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - if (cfg.buffer_size != (FRAME_SIZE - 8)) { - rc = -EINVAL; - break; - } - } else { - if (cfg.buffer_size != (QCELP_FRAME_SIZE + 14)) { - rc = -EINVAL; - break; - } - } - audio->buffer_size = cfg.buffer_size; - break; - } - case AUDIO_GET_QCELP_ENC_CONFIG: { - if (copy_to_user((void *) arg, &audio->cfg, sizeof(audio->cfg))) - rc = -EFAULT; - break; - } - case AUDIO_SET_QCELP_ENC_CONFIG: { - struct msm_audio_qcelp_enc_config cfg; - if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - MM_DBG("0X%8x, 0x%8x, 0x%8x\n", cfg.min_bit_rate, - cfg.max_bit_rate, cfg.cdma_rate); - if (cfg.min_bit_rate > CDMA_RATE_FULL || \ - cfg.min_bit_rate < CDMA_RATE_EIGHTH) { - MM_ERR("invalid min bitrate\n"); - rc = -EFAULT; - break; - } - if (cfg.max_bit_rate > CDMA_RATE_FULL || \ - cfg.max_bit_rate < CDMA_RATE_EIGHTH) { - MM_ERR("invalid max bitrate\n"); - rc = -EFAULT; - break; - } - /* Recording Does not support Erase and Blank */ - if (cfg.cdma_rate > CDMA_RATE_FULL || - cfg.cdma_rate < CDMA_RATE_EIGHTH) { - MM_ERR("invalid qcelp cdma rate\n"); - rc = -EFAULT; - break; - } - memcpy(&audio->cfg, &cfg, sizeof(cfg)); - break; - } - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -static ssize_t audqcelp_in_read(struct file *file, - char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_qcelp_in *audio = file->private_data; - unsigned long flags; - const char __user *start = buf; - void *data; - uint32_t index; - uint32_t size; - int rc = 0; - struct qcelp_encoded_meta_out meta_field; - struct audio_frame_nt *nt_frame; - MM_DBG("count = %d\n", count); - mutex_lock(&audio->read_lock); - while (count > 0) { - rc = wait_event_interruptible( - audio->wait, (audio->in_count > 0) || audio->stopped || - audio->rflush); - if (rc < 0) - break; - - if (audio->rflush) { - rc = -EBUSY; - break; - } - if (audio->stopped && !audio->in_count) { - MM_DBG("Driver in stop state, No more buffer to read"); - rc = 0;/* End of File */ - break; - } - - index = audio->in_tail; - data = (uint8_t *) audio->in[index].data; - size = audio->in[index].size; - - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) { - nt_frame = (struct audio_frame_nt *)(data - - sizeof(struct audio_frame_nt)); - memcpy((char *)&meta_field.time_stamp_dword_lsw, - (char *)&nt_frame->time_stamp_dword_lsw, - (sizeof(struct qcelp_encoded_meta_out) - \ - sizeof(uint16_t))); - meta_field.metadata_len = - sizeof(struct qcelp_encoded_meta_out); - if (copy_to_user((char *)start, (char *)&meta_field, - sizeof(struct qcelp_encoded_meta_out))) { - rc = -EFAULT; - break; - } - if (nt_frame->nflag_lsw & 0x0001) { - MM_ERR("recieved EOS in read call\n"); - audio->eos_ack = 1; - } - buf += sizeof(struct qcelp_encoded_meta_out); - count -= sizeof(struct qcelp_encoded_meta_out); - } - if (count >= size) { - /* order the reads on the buffer */ - dma_coherent_post_ops(); - if (copy_to_user(buf, data, size)) { - rc = -EFAULT; - break; - } - spin_lock_irqsave(&audio->dsp_lock, flags); - if (index != audio->in_tail) { - /* overrun -- data is - * invalid and we need to retry */ - spin_unlock_irqrestore(&audio->dsp_lock, flags); - continue; - } - audio->in[index].size = 0; - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - audio->in_count--; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - count -= size; - buf += size; - if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL)) { - if (!audio->eos_ack) { - MM_DBG("sending read ptr command \ - %d %d\n", - audio->dsp_cnt, - audio->in_tail); - audqcelp_in_dsp_read_buffer(audio, - audio->dsp_cnt++); - } - } - } else { - MM_ERR("short read\n"); - break; - } - break; - } - mutex_unlock(&audio->read_lock); - - if (buf > start) - return buf - start; - - return rc; -} - -static void audrec_pcm_send_data(struct audio_qcelp_in *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - MM_DBG("\n"); - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - audrec_pcm_buffer_ptr_refresh(audio, - audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } - done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static int audqcelp_in_fsync(struct file *file, loff_t a, loff_t b, - int datasync) - -{ - struct audio_qcelp_in *audio = file->private_data; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - if (!audio->running || (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - audio->wflush); - MM_DBG("waked on by some event audio->wflush = %d\n", audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; - -} - -int audrec_qcelp_process_eos(struct audio_qcelp_in *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - struct buffer *frame; - int rc = 0; - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - MM_DBG("copying meta_out frame->used = %d\n", frame->used); - audrec_pcm_send_data(audio, 0); -done: - return rc; -} - -static ssize_t audqcelp_in_write(struct file *file, - const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_qcelp_in *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - char *cpy_ptr; - int rc = 0, eos_condition = AUDPREPROC_QCELP_EOS_NONE; - unsigned short mfield_size = 0; - int write_count = 0; - MM_DBG("cnt=%d\n", count); - - if (count & 1) - return -EINVAL; - - if (audio->mode != MSM_AUD_ENC_MODE_NONTUNNEL) - return -EINVAL; - - mutex_lock(&audio->write_lock); - frame = audio->out + audio->out_head; - /* if supplied count is more than driver buffer size - * then only copy driver buffer size - */ - if (count > frame->size) - count = frame->size; - - write_count = count; - cpy_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - goto error; - - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto error; - } - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - goto error; - } else if (mfield_size > count) { - rc = -EINVAL; - goto error; - } - MM_DBG("mf offset_val %x\n", mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - goto error; - } - /* Check if EOS flag is set and buffer has - * contains just meta field - */ - if (cpy_ptr[AUDPREPROC_QCELP_EOS_FLG_OFFSET] & - AUDPREPROC_QCELP_EOS_FLG_MASK) { - eos_condition = AUDPREPROC_QCELP_EOS_SET; - MM_DBG("EOS SET\n"); - if (mfield_size == count) { - buf += mfield_size; - eos_condition = 0; - goto exit; - } else - cpy_ptr[AUDPREPROC_QCELP_EOS_FLG_OFFSET] &= - ~AUDPREPROC_QCELP_EOS_FLG_MASK; - } - cpy_ptr += mfield_size; - count -= mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - MM_DBG("copying the stream count = %d\n", count); - if (copy_from_user(cpy_ptr, buf, count)) { - rc = -EFAULT; - goto error; - } -exit: - frame->used = count; - audio->out_head ^= 1; - if (!audio->flush_ack) - audrec_pcm_send_data(audio, 0); - else { - audrec_pcm_send_data(audio, 1); - audio->flush_ack = 0; - } - if (eos_condition == AUDPREPROC_QCELP_EOS_SET) - rc = audrec_qcelp_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - return write_count; -error: - mutex_unlock(&audio->write_lock); - return rc; -} - -static int audqcelp_in_release(struct inode *inode, struct file *file) -{ - struct audio_qcelp_in *audio = file->private_data; - - mutex_lock(&audio->lock); - audqcelp_in_disable(audio); - audqcelp_in_flush(audio); - msm_adsp_put(audio->audrec); - - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - msm_adsp_put(audio->audpre); - - audpreproc_aenc_free(audio->enc_id); - audio->audrec = NULL; - audio->audpre = NULL; - audio->opened = 0; - - if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) && \ - (audio->out_data)) { - ion_unmap_kernel(audio->client, audio->input_buff_handle); - ion_free(audio->client, audio->input_buff_handle); - audio->out_data = NULL; - } - - if (audio->data) { - ion_unmap_kernel(audio->client, audio->output_buff_handle); - ion_free(audio->client, audio->output_buff_handle); - audio->data = NULL; - } - ion_client_destroy(audio->client); - mutex_unlock(&audio->lock); - return 0; -} - -static struct audio_qcelp_in the_audio_qcelp_in; - -static int audqcelp_in_open(struct inode *inode, struct file *file) -{ - struct audio_qcelp_in *audio = &the_audio_qcelp_in; - int rc; - int encid; - int dma_size = 0; - int len = 0; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - struct ion_client *client = NULL; - - mutex_lock(&audio->lock); - if (audio->opened) { - rc = -EBUSY; - goto done; - } - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - audio->mode = MSM_AUD_ENC_MODE_NONTUNNEL; - dma_size = NT_DMASZ; - MM_DBG("Opened for non tunnel mode encoding\n"); - } else if (!(file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - audio->mode = MSM_AUD_ENC_MODE_TUNNEL; - dma_size = DMASZ; - MM_DBG("Opened for tunnel mode encoding\n"); - } else { - MM_ERR("Invalid mode\n"); - rc = -EACCES; - goto done; - } - - /* Settings will be re-config at AUDIO_SET_CONFIG, - * but at least we need to have initial config - */ - audio->samp_rate = RPC_AUD_DEF_SAMPLE_RATE_8000, - audio->samp_rate_index = AUDREC_CMD_SAMP_RATE_INDX_8000; - audio->channel_mode = AUDREC_CMD_STEREO_MODE_MONO; - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) - audio->buffer_size = (QCELP_FRAME_SIZE + 14); - else - audio->buffer_size = QCELP_FRAME_SIZE; - audio->enc_type = AUDREC_CMD_TYPE_0_INDEX_QCELP | audio->mode; - - audio->cfg.cdma_rate = CDMA_RATE_FULL; - audio->cfg.min_bit_rate = CDMA_RATE_FULL; - audio->cfg.max_bit_rate = CDMA_RATE_FULL; - - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - rc = audmgr_open(&audio->audmgr); - if (rc) - goto done; - } - - encid = audpreproc_aenc_alloc(audio->enc_type, &audio->module_name, - &audio->queue_ids); - if (encid < 0) { - MM_ERR("No free encoder available\n"); - rc = -ENODEV; - goto done; - } - audio->enc_id = encid; - - rc = msm_adsp_get(audio->module_name, &audio->audrec, - &audrec_qcelp_adsp_ops, audio); - if (rc) { - audpreproc_aenc_free(audio->enc_id); - goto done; - } - - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre, - &audpre_qcelp_adsp_ops, audio); - if (rc) { - msm_adsp_put(audio->audrec); - audpreproc_aenc_free(audio->enc_id); - goto done; - } - } - - audio->dsp_cnt = 0; - audio->stopped = 0; - audio->wflush = 0; - audio->rflush = 0; - audio->flush_ack = 0; - - audqcelp_in_flush(audio); - audqcelp_out_flush(audio); - - client = msm_ion_client_create(UINT_MAX, "Audio_QCELP_in_client"); - if (IS_ERR_OR_NULL(client)) { - MM_ERR("Unable to create ION client\n"); - rc = -ENOMEM; - goto client_create_error; - } - audio->client = client; - - MM_DBG("allocating mem sz = %d\n", dma_size); - handle = ion_alloc(client, dma_size, SZ_4K, - ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to create allocate O/P buffers\n"); - rc = -ENOMEM; - goto output_buff_alloc_error; - } - - audio->output_buff_handle = handle; - - rc = ion_phys(client , handle, &addr, &len); - if (rc) { - MM_ERR("O/P buffers:Invalid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - rc = -ENOMEM; - goto output_buff_get_phys_error; - } else { - MM_INFO("O/P buffers:valid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - } - audio->phys = (int32_t)addr; - - rc = ion_handle_get_flags(client, handle, &ionflag); - if (rc) { - MM_ERR("could not get flags for the handle\n"); - rc = -ENOMEM; - goto output_buff_get_flags_error; - } - - audio->map_v_read = ion_map_kernel(client, handle); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("could not map read buffers,freeing instance 0x%08x\n", - (int)audio); - rc = -ENOMEM; - goto output_buff_map_error; - } - audio->data = audio->map_v_read; - MM_DBG("read buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->phys, (int)audio->data); - - audio->out_data = NULL; - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) { - MM_DBG("allocating BUFFER_SIZE %d\n", BUFFER_SIZE); - handle = ion_alloc(client, BUFFER_SIZE, - SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to create allocate I/P buffers\n"); - rc = -ENOMEM; - goto input_buff_alloc_error; - } - - audio->input_buff_handle = handle; - - rc = ion_phys(client , handle, &addr, &len); - if (rc) { - MM_ERR("I/P buffers:Invalid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - rc = -ENOMEM; - goto input_buff_get_phys_error; - } else { - MM_INFO("Got valid phy: %x sz: %x\n", - (unsigned int) addr, - (unsigned int) len); - } - audio->out_phys = (int32_t)addr; - - rc = ion_handle_get_flags(client, - handle, &ionflag); - if (rc) { - MM_ERR("could not get flags for the handle\n"); - rc = -ENOMEM; - goto input_buff_get_flags_error; - } - - audio->map_v_write = ion_map_kernel(client, handle); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write buffers\n"); - rc = -ENOMEM; - goto input_buff_map_error; - } - audio->out_data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n", - (unsigned int)addr, - (unsigned int)audio->out_data); - - /* Initialize buffer */ - audio->out[0].data = audio->out_data + 0; - audio->out[0].addr = audio->out_phys + 0; - audio->out[0].size = OUT_BUFFER_SIZE; - - audio->out[1].data = audio->out_data + OUT_BUFFER_SIZE; - audio->out[1].addr = audio->out_phys + OUT_BUFFER_SIZE; - audio->out[1].size = OUT_BUFFER_SIZE; - - MM_DBG("audio->out[0].data = %d audio->out[1].data = %d", - (unsigned int)audio->out[0].data, - (unsigned int)audio->out[1].data); - audio->mfield = NT_FRAME_HEADER_SIZE; - audio->out_frame_cnt++; - } - file->private_data = audio; - audio->opened = 1; - -done: - mutex_unlock(&audio->lock); - return rc; -input_buff_map_error: -input_buff_get_flags_error: -input_buff_get_phys_error: - ion_free(client, audio->input_buff_handle); -input_buff_alloc_error: - ion_unmap_kernel(client, audio->output_buff_handle); -output_buff_map_error: -output_buff_get_phys_error: -output_buff_get_flags_error: - ion_free(client, audio->output_buff_handle); -output_buff_alloc_error: - ion_client_destroy(client); -client_create_error: - msm_adsp_put(audio->audrec); - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - msm_adsp_put(audio->audpre); - - audpreproc_aenc_free(audio->enc_id); - mutex_unlock(&audio->lock); - return rc; -} - -static const struct file_operations audio_qcelp_in_fops = { - .owner = THIS_MODULE, - .open = audqcelp_in_open, - .release = audqcelp_in_release, - .read = audqcelp_in_read, - .write = audqcelp_in_write, - .fsync = audqcelp_in_fsync, - .unlocked_ioctl = audqcelp_in_ioctl, -}; - -static struct miscdevice audqcelp_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_qcelp_in", - .fops = &audio_qcelp_in_fops, -}; - -static int __init audqcelp_in_init(void) -{ - mutex_init(&the_audio_qcelp_in.lock); - mutex_init(&the_audio_qcelp_in.read_lock); - spin_lock_init(&the_audio_qcelp_in.dsp_lock); - init_waitqueue_head(&the_audio_qcelp_in.wait); - init_waitqueue_head(&the_audio_qcelp_in.wait_enable); - mutex_init(&the_audio_qcelp_in.write_lock); - init_waitqueue_head(&the_audio_qcelp_in.write_wait); - return misc_register(&audqcelp_in_misc); -} -device_initcall(audqcelp_in_init); diff --git a/arch/arm/mach-msm/qdsp5/audio_voice_lb.c b/arch/arm/mach-msm/qdsp5/audio_voice_lb.c deleted file mode 100644 index a73defd988f7367638a3ea4a3340a2dda9d2f540..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_voice_lb.c +++ /dev/null @@ -1,369 +0,0 @@ -/* Copyright (c) 2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "audmgr_new.h" - -#define VOICELOOPBACK_PROG 0x300000B8 -#define VOICELOOP_VERS 0x00010001 - -#define VOICELOOPBACK_START_PROC 2 -#define VOICELOOPBACK_STOP_PROC 3 - -#define RPC_TYPE_REQUEST 0 -#define RPC_TYPE_REPLY 1 - -#define RPC_STATUS_FAILURE 0 -#define RPC_STATUS_SUCCESS 1 -#define RPC_STATUS_REJECT 1 - -#define RPC_COMMON_HDR_SZ (sizeof(uint32_t) * 2) -#define RPC_REQUEST_HDR_SZ (sizeof(struct rpc_request_hdr)) -#define RPC_REPLY_HDR_SZ (sizeof(uint32_t) * 3) - -#define MAX_LEN 32 - -struct audio { - struct msm_rpc_endpoint *rpc_endpt; - uint32_t rpc_prog; - uint32_t rpc_ver; - uint32_t rpc_status; - struct audmgr audmgr; - - struct dentry *dentry; - - struct mutex lock; - - struct task_struct *task; - - wait_queue_head_t wait; - int enabled; - int thread_exit; -}; - -static struct audio the_audio; - -static int audio_voice_loopback_thread(void *data) -{ - struct audio *audio = data; - struct rpc_request_hdr *rpc_hdr = NULL; - int rpc_hdr_len; - - MM_DBG("\n"); - - while (!kthread_should_stop()) { - if (rpc_hdr != NULL) { - kfree(rpc_hdr); - rpc_hdr = NULL; - } - - if (audio->thread_exit) - break; - - rpc_hdr_len = msm_rpc_read(audio->rpc_endpt, - (void **) &rpc_hdr, - -1, - -1); - if (rpc_hdr_len < 0) { - MM_ERR("RPC read failed %d\n", rpc_hdr_len); - break; - } else if (rpc_hdr_len < RPC_COMMON_HDR_SZ) { - continue; - } else { - uint32_t rpc_type = be32_to_cpu(rpc_hdr->type); - if (rpc_type == RPC_TYPE_REPLY) { - struct rpc_reply_hdr *rpc_reply = - (void *) rpc_hdr; - uint32_t reply_status; - - reply_status = - be32_to_cpu(rpc_reply->reply_stat); - - if (reply_status == RPC_ACCEPTSTAT_SUCCESS) - audio->rpc_status = \ - RPC_STATUS_SUCCESS; - else { - audio->rpc_status = \ - RPC_STATUS_REJECT; - MM_ERR("RPC reply status denied\n"); - } - wake_up(&audio->wait); - } else { - MM_ERR("Unexpected RPC type %d\n", rpc_type); - } - } - } - kfree(rpc_hdr); - rpc_hdr = NULL; - - MM_DBG("Audio Voice Looopback thread stopped\n"); - - return 0; -} - -static int audio_voice_loopback_start(struct audio *audio) -{ - int rc = 0; - struct audmgr_config cfg; - struct rpc_request_hdr rpc_hdr; - - MM_DBG("\n"); - - cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_8000; - cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_8000; - cfg.def_method = RPC_AUD_DEF_METHOD_VOICE; - cfg.codec = RPC_AUD_DEF_CODEC_VOC_CDMA; - cfg.snd_method = RPC_SND_METHOD_VOICE; - rc = audmgr_enable(&audio->audmgr, &cfg); - if (rc < 0) { - MM_ERR("audmgr open failed, freeing instance\n"); - rc = -EINVAL; - goto done; - } - - memset(&rpc_hdr, 0, sizeof(rpc_hdr)); - - msm_rpc_setup_req(&rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - VOICELOOPBACK_START_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, - &rpc_hdr, - sizeof(rpc_hdr)); - if (rc >= 0) { - rc = wait_event_timeout(audio->wait, - (audio->rpc_status != RPC_STATUS_FAILURE), - 1 * HZ); - if (rc > 0) { - if (audio->rpc_status != RPC_STATUS_SUCCESS) { - MM_ERR("Start loopback failed %d\n", rc); - rc = -EBUSY; - } else { - rc = 0; - } - } else { - MM_ERR("Wait event for acquire failed %d\n", rc); - rc = -EBUSY; - } - } else { - audmgr_disable(&audio->audmgr); - MM_ERR("RPC write for start loopback failed %d\n", rc); - rc = -EBUSY; - } -done: - return rc; -} - -static int audio_voice_loopback_stop(struct audio *audio) -{ - int rc = 0; - struct rpc_request_hdr rpc_hdr; - - MM_DBG("\n"); - - memset(&rpc_hdr, 0, sizeof(rpc_hdr)); - - msm_rpc_setup_req(&rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - VOICELOOPBACK_STOP_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - audio->thread_exit = 1; - rc = msm_rpc_write(audio->rpc_endpt, - &rpc_hdr, - sizeof(rpc_hdr)); - if (rc >= 0) { - - rc = wait_event_timeout(audio->wait, - (audio->rpc_status != RPC_STATUS_FAILURE), - 1 * HZ); - if (rc > 0) { - MM_DBG("Wait event for release succeeded\n"); - rc = 0; - } else { - MM_ERR("Wait event for release failed %d\n", rc); - } - } else { - MM_ERR("RPC write for release failed %d\n", rc); - } - - audmgr_disable(&audio->audmgr); - - return rc; -} - -static int audio_voice_loopback_open(struct audio *audio_info) -{ - int rc = 0; - - MM_DBG("\n"); - - rc = audmgr_open(&audio_info->audmgr); - if (rc) { - MM_ERR("audmgr open failed, freeing instance\n"); - rc = -EINVAL; - goto done; - } - - audio_info->rpc_endpt = msm_rpc_connect_compatible(VOICELOOPBACK_PROG, - VOICELOOP_VERS, - MSM_RPC_UNINTERRUPTIBLE); - if (IS_ERR(audio_info->rpc_endpt)) { - MM_ERR("VOICE LOOPBACK RPC connect\ - failed ver 0x%x\n", - VOICELOOP_VERS); - rc = PTR_ERR(audio_info->rpc_endpt); - audio_info->rpc_endpt = NULL; - rc = -EINVAL; - } else { - MM_DBG("VOICE LOOPBACK connect succeeded ver 0x%x\n", - VOICELOOP_VERS); - audio_info->thread_exit = 0; - audio_info->task = kthread_run(audio_voice_loopback_thread, - audio_info, - "audio_voice_loopback"); - if (IS_ERR(audio_info->task)) { - MM_ERR("voice loopback thread create failed\n"); - rc = PTR_ERR(audio_info->task); - audio_info->task = NULL; - msm_rpc_close(audio_info->rpc_endpt); - audio_info->rpc_endpt = NULL; - rc = -EINVAL; - } - audio_info->rpc_prog = VOICELOOPBACK_PROG; - audio_info->rpc_ver = VOICELOOP_VERS; - } -done: - return rc; -} - -static int audio_voice_loopback_close(struct audio *audio_info) -{ - MM_DBG("\n"); - msm_rpc_close(audio_info->rpc_endpt); - audio_info->rpc_endpt = NULL; - audmgr_close(&audio_info->audmgr); - audio_info->task = NULL; - return 0; -} - -static ssize_t audio_voice_loopback_debug_write(struct file *file, - const char __user *buf, - size_t cnt, loff_t *ppos) -{ - char lbuf[MAX_LEN]; - int rc = 0; - - if (cnt > (MAX_LEN - 1)) - return -EINVAL; - - memset(&lbuf[0], 0, sizeof(lbuf)); - - rc = copy_from_user(lbuf, buf, cnt); - if (rc) { - MM_ERR("Unable to copy data from user space\n"); - return -EFAULT; - } - - lbuf[cnt] = '\0'; - - if (!strncmp(&lbuf[0], "1", cnt-1)) { - mutex_lock(&the_audio.lock); - if (!the_audio.enabled) { - rc = audio_voice_loopback_open(&the_audio); - if (!rc) { - rc = audio_voice_loopback_start(&the_audio); - if (rc < 0) { - the_audio.enabled = 0; - audio_voice_loopback_close(&the_audio); - } else { - the_audio.enabled = 1; - } - } - } - mutex_unlock(&the_audio.lock); - } else if (!strncmp(lbuf, "0", cnt-1)) { - mutex_lock(&the_audio.lock); - if (the_audio.enabled) { - audio_voice_loopback_stop(&the_audio); - audio_voice_loopback_close(&the_audio); - the_audio.enabled = 0; - } - mutex_unlock(&the_audio.lock); - } else { - rc = -EINVAL; - } - - if (rc == 0) { - rc = cnt; - } else { - MM_INFO("rc = %d\n", rc); - MM_INFO("\nWrong command: Use =>\n"); - MM_INFO("-------------------------\n"); - MM_INFO("To Start Loopback:: echo \"1\">/sys/kernel/debug/\ - voice_loopback\n"); - MM_INFO("To Stop Loopback:: echo \"0\">/sys/kernel/debug/\ - voice_loopback\n"); - MM_INFO("------------------------\n"); - } - - return rc; -} - -static ssize_t audio_voice_loopback_debug_open(struct inode *inode, - struct file *file) -{ - file->private_data = inode->i_private; - MM_DBG("Audio Voiceloop debugfs opened\n"); - return 0; -} - -static const struct file_operations voice_loopback_debug_fops = { - .write = audio_voice_loopback_debug_write, - .open = audio_voice_loopback_debug_open, -}; - -static int __init audio_init(void) -{ - int rc = 0; - memset(&the_audio, 0, sizeof(the_audio)); - - mutex_init(&the_audio.lock); - - init_waitqueue_head(&the_audio.wait); - - the_audio.dentry = debugfs_create_file("voice_loopback", - S_IFREG | S_IRUGO, - NULL, - NULL, &voice_loopback_debug_fops); - if (IS_ERR(the_audio.dentry)) - MM_ERR("debugfs_create_file failed\n"); - - return rc; -} -late_initcall(audio_init); diff --git a/arch/arm/mach-msm/qdsp5/audio_voicememo.c b/arch/arm/mach-msm/qdsp5/audio_voicememo.c deleted file mode 100644 index ae63f0db53289dc8bffff3901b32303d0619097a..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_voicememo.c +++ /dev/null @@ -1,981 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/audio_voicememo.c - * - * Voice Memo device - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. - * - * This code is based in part on arch/arm/mach-msm/qdsp5/audio_mp3.c - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "audmgr.h" - -#define SND_PROG_VERS "rs30000002:0x00020001" -#define SND_PROG 0x30000002 -#define SND_VERS_COMP 0x00020001 -#define SND_VERS2_COMP 0x00030001 - -#define SND_VOC_REC_START_PROC 19 -#define SND_VOC_REC_STOP_PROC 20 -#define SND_VOC_REC_PAUSE_PROC 21 -#define SND_VOC_REC_RESUME_PROC 22 -#define SND_VOC_REC_PUT_BUF_PROC 23 - -#define SND_VOC_REC_AV_SYNC_CB_PTR_PROC 9 -#define SND_VOC_REC_CB_FUNC_TYPE_PROC 10 - -#define REC_CLIENT_DATA 0x11223344 -#define DATA_CB_FUNC_ID 0x12345678 -#define AV_SYNC_CB_FUNC_ID 0x87654321 -#define CLIENT_DATA 0xaabbccdd - -#define RPC_TYPE_REQUEST 0 -#define RPC_TYPE_REPLY 1 - -#define RPC_STATUS_FAILURE 0 -#define RPC_STATUS_SUCCESS 1 - -#define RPC_VERSION 2 - -#define RPC_COMMON_HDR_SZ (sizeof(uint32_t) * 2) -#define RPC_REQUEST_HDR_SZ (sizeof(struct rpc_request_hdr)) -#define RPC_REPLY_HDR_SZ (sizeof(uint32_t) * 3) -#define RPC_REPLY_SZ (sizeof(uint32_t) * 6) - -#define MAX_FRAME_SIZE 36 /* QCELP - 36, AMRNB - 32, EVRC - 24 */ -#define MAX_REC_BUF_COUNT 5 /* Maximum supported voc rec buffers */ -#define MAX_REC_BUF_SIZE (MAX_FRAME_SIZE * 10) -#define MAX_VOICEMEMO_BUF_SIZE \ - ((MAX_REC_BUF_SIZE)*MAX_REC_BUF_COUNT) /* 5 buffers for 200ms frame */ -#define MSM_AUD_BUFFER_UPDATE_WAIT_MS 2000 - -enum rpc_voc_rec_status_type { - RPC_VOC_REC_STAT_SUCCESS = 1, - RPC_VOC_REC_STAT_DONE = 2, - RPC_VOC_REC_STAT_AUTO_STOP = 4, - RPC_VOC_REC_STAT_PAUSED = 8, - RPC_VOC_REC_STAT_RESUMED = 16, - RPC_VOC_REC_STAT_ERROR = 32, - RPC_VOC_REC_STAT_BUFFER_ERROR = 64, - RPC_VOC_REC_STAT_INVALID_PARAM = 128, - RPC_VOC_REC_STAT_INT_TIME = 256, - RPC_VOC_REC_STAT_DATA = 512, - RPC_VOC_REC_STAT_NOT_READY = 1024, - RPC_VOC_REC_STAT_INFORM_EVRC = 2048, - RPC_VOC_REC_STAT_INFORM_13K = 4096, - RPC_VOC_REC_STAT_INFORM_AMR = 8192, - RPC_VOC_REC_STAT_INFORM_MAX = 65535 -}; - -struct rpc_snd_voc_rec_start_args { - uint32_t param_status; /* 1 = valid, 0 = not valid */ - uint32_t rec_type; - uint32_t rec_interval_ms; - uint32_t auto_stop_ms; - uint32_t capability; - uint32_t max_rate; - uint32_t min_rate; - uint32_t frame_format; - uint32_t dtx_enable; - uint32_t data_req_ms; - uint32_t rec_client_data; - - uint32_t cb_func_id; - uint32_t sync_cb_func_id; - uint32_t client_data; -}; - -struct rpc_snd_voc_rec_put_buf_args { - uint32_t buf; - uint32_t num_bytes; -}; - -struct snd_voc_rec_start_msg { - struct rpc_request_hdr hdr; - struct rpc_snd_voc_rec_start_args args; -}; - -struct snd_voc_rec_put_buf_msg { - struct rpc_request_hdr hdr; - struct rpc_snd_voc_rec_put_buf_args args; -}; - -struct snd_voc_rec_av_sync_cb_func_data { - uint32_t sync_cb_func_id; - uint32_t status; /* Pointer status (1 = valid, 0 = invalid) */ - uint32_t num_samples; - uint32_t time_stamp[2]; - uint32_t lost_samples; - uint32_t frame_index; - uint32_t client_data; -}; - -struct snd_voc_rec_cb_func_fw_data { - uint32_t fw_ptr_status; /* FW Pointer status (1=valid,0=invalid) */ - uint32_t rec_buffer_size; - uint32_t data[MAX_REC_BUF_SIZE/4]; - uint32_t rec_buffer_size_copy; - uint32_t rec_num_frames; /* Number of voice frames */ - uint32_t rec_length; /* Valid data in record buffer = - * data_req_ms amount of data */ - uint32_t client_data; /* A11 rec buffer pointer */ - uint32_t rw_ptr_status; /* RW Pointer status (1=valid,0=invalid) */ -}; - -struct snd_voc_rec_cb_func_rw_data { - uint32_t fw_ptr_status; /* FW Pointer status (1=valid,0=invalid) */ - uint32_t rw_ptr_status; /* RW Pointer status (1=valid,0=invalid) */ - uint32_t rec_buffer_size; - uint32_t data[MAX_REC_BUF_SIZE/4]; - uint32_t rec_buffer_size_copy; - uint32_t rec_num_frames; /* Number of voice frames */ - uint32_t rec_length; /* Valid data in record buffer = - * data_req_ms amount of data */ - uint32_t client_data; /* A11 rec buffer pointer */ -}; - -struct snd_voc_rec_data_cb_func_data { - uint32_t cb_func_id; - uint32_t status; /* Pointer status (1 = valid, 0 = invalid) */ - uint32_t rec_status; - - union { - struct snd_voc_rec_cb_func_fw_data fw_data; - struct snd_voc_rec_cb_func_rw_data rw_data; - } pkt; -}; - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Usage actual recorded data */ - unsigned addr; - unsigned numframes; -}; - -struct audio_voicememo { - uint32_t byte_count; /* Pass statistics to user space for - * time stamping */ - uint32_t frame_count; - - int opened; - int enabled; - int running; - int stopped; - int pause_resume; - - uint32_t rpc_prog; - uint32_t rpc_ver; - uint32_t rpc_xid; - uint32_t rpc_status; - - struct mutex lock; - struct mutex read_lock; - struct mutex dsp_lock; - wait_queue_head_t read_wait; - wait_queue_head_t wait; - - struct buffer in[MAX_REC_BUF_COUNT]; - char *rec_buf_ptr; - dma_addr_t phys; - uint32_t rec_buf_size; - uint8_t read_next; /* index to input buffers to be read next */ - uint8_t fill_next; /* index to buffer that should be filled as - * data comes from A9 */ - - struct audmgr audmgr; - - struct msm_audio_voicememo_config voicememo_cfg; - - struct msm_rpc_endpoint *sndept; - struct task_struct *task; -}; - -static struct audio_voicememo the_audio_voicememo; - -static int audvoicememo_validate_usr_config( - struct msm_audio_voicememo_config *config) -{ - int rc = -1; /* error */ - - if (config->rec_type != RPC_VOC_REC_FORWARD && - config->rec_type != RPC_VOC_REC_REVERSE && - config->rec_type != RPC_VOC_REC_BOTH) - goto done; - - /* QCELP, EVRC, AMR-NB only */ - if (config->capability != RPC_VOC_CAP_IS733 && - config->capability != RPC_VOC_CAP_IS127 && - config->capability != RPC_VOC_CAP_AMR) - goto done; - - /* QCP, AMR format supported */ - if ((config->frame_format != RPC_VOC_PB_NATIVE_QCP) && - (config->frame_format != RPC_VOC_PB_AMR)) - goto done; - - if ((config->frame_format == RPC_VOC_PB_AMR) && - (config->capability != RPC_VOC_CAP_AMR)) - goto done; - - /* To make sure, max kernel buf size matches - * with max data request time */ - if (config->data_req_ms > ((MAX_REC_BUF_SIZE/MAX_FRAME_SIZE)*20)) - goto done; - - rc = 0; -done: - return rc; -} - -static void audvoicememo_flush_buf(struct audio_voicememo *audio) -{ - uint8_t index; - - for (index = 0; index < MAX_REC_BUF_COUNT; index++) - audio->in[index].used = 0; - - audio->read_next = 0; - mutex_lock(&audio->dsp_lock); - audio->fill_next = 0; - mutex_unlock(&audio->dsp_lock); -} - -static void audvoicememo_ioport_reset(struct audio_voicememo *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->read_wait); - mutex_lock(&audio->read_lock); - audvoicememo_flush_buf(audio); - mutex_unlock(&audio->read_lock); -} - -/* must be called with audio->lock held */ -static int audvoicememo_enable(struct audio_voicememo *audio) -{ - struct audmgr_config cfg; - struct snd_voc_rec_put_buf_msg bmsg; - struct snd_voc_rec_start_msg msg; - uint8_t index; - uint32_t offset = 0; - int rc; - - if (audio->enabled) - return 0; - - /* Codec / method configure to audmgr client */ - cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_8000; - cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; - cfg.def_method = RPC_AUD_DEF_METHOD_RECORD; - - if (audio->voicememo_cfg.capability == RPC_VOC_CAP_IS733) - cfg.codec = RPC_AUD_DEF_CODEC_VOC_13K; - else if (audio->voicememo_cfg.capability == RPC_VOC_CAP_IS127) - cfg.codec = RPC_AUD_DEF_CODEC_VOC_EVRC; - else - cfg.codec = RPC_AUD_DEF_CODEC_VOC_AMR; /* RPC_VOC_CAP_AMR */ - - cfg.snd_method = RPC_SND_METHOD_VOICE; - rc = audmgr_enable(&audio->audmgr, &cfg); - - if (rc < 0) - return rc; - - /* Configure VOC Rec buffer */ - for (index = 0; index < MAX_REC_BUF_COUNT; index++) { - audio->in[index].data = audio->rec_buf_ptr + offset; - audio->in[index].addr = audio->phys + offset; - audio->in[index].size = audio->rec_buf_size; - audio->in[index].used = 0; - audio->in[index].numframes = 0; - offset += audio->rec_buf_size; - bmsg.args.buf = (uint32_t) audio->in[index].data; - bmsg.args.num_bytes = cpu_to_be32(audio->in[index].size); - MM_DBG("rec_buf_ptr=0x%8x, rec_buf_size = 0x%8x\n", - bmsg.args.buf, bmsg.args.num_bytes); - - msm_rpc_setup_req(&bmsg.hdr, audio->rpc_prog, audio->rpc_ver, - SND_VOC_REC_PUT_BUF_PROC); - audio->rpc_xid = bmsg.hdr.xid; - audio->rpc_status = RPC_STATUS_FAILURE; - msm_rpc_write(audio->sndept, &bmsg, sizeof(bmsg)); - rc = wait_event_timeout(audio->wait, - audio->rpc_status != RPC_STATUS_FAILURE, 1 * HZ); - if (rc == 0) - goto err; - } - - - /* Start Recording */ - msg.args.param_status = cpu_to_be32(0x00000001); - msg.args.rec_type = cpu_to_be32(audio->voicememo_cfg.rec_type); - msg.args.rec_interval_ms = - cpu_to_be32(audio->voicememo_cfg.rec_interval_ms); - msg.args.auto_stop_ms = cpu_to_be32(audio->voicememo_cfg.auto_stop_ms); - msg.args.capability = cpu_to_be32(audio->voicememo_cfg.capability); - msg.args.max_rate = cpu_to_be32(audio->voicememo_cfg.max_rate); - msg.args.min_rate = cpu_to_be32(audio->voicememo_cfg.min_rate); - msg.args.frame_format = cpu_to_be32(audio->voicememo_cfg.frame_format); - msg.args.dtx_enable = cpu_to_be32(audio->voicememo_cfg.dtx_enable); - msg.args.data_req_ms = cpu_to_be32(audio->voicememo_cfg.data_req_ms); - msg.args.rec_client_data = cpu_to_be32(REC_CLIENT_DATA); - msg.args.cb_func_id = cpu_to_be32(DATA_CB_FUNC_ID); - msg.args.sync_cb_func_id = cpu_to_be32(AV_SYNC_CB_FUNC_ID); - msg.args.client_data = cpu_to_be32(CLIENT_DATA); - - msm_rpc_setup_req(&msg.hdr, audio->rpc_prog, audio->rpc_ver, - SND_VOC_REC_START_PROC); - - audio->rpc_xid = msg.hdr.xid; - audio->rpc_status = RPC_STATUS_FAILURE; - msm_rpc_write(audio->sndept, &msg, sizeof(msg)); - rc = wait_event_timeout(audio->wait, - audio->rpc_status != RPC_STATUS_FAILURE, 1 * HZ); - if (rc == 0) - goto err; - - audio->rpc_xid = 0; - audio->enabled = 1; - return 0; - -err: - audio->rpc_xid = 0; - audmgr_disable(&audio->audmgr); - MM_ERR("Fail\n"); - return -1; -} - -/* must be called with audio->lock held */ -static int audvoicememo_disable(struct audio_voicememo *audio) -{ - struct rpc_request_hdr rhdr; - int rc = 0; - if (audio->enabled) { - msm_rpc_setup_req(&rhdr, audio->rpc_prog, audio->rpc_ver, - SND_VOC_REC_STOP_PROC); - rc = msm_rpc_write(audio->sndept, &rhdr, sizeof(rhdr)); - rc = wait_event_timeout(audio->wait, audio->stopped == 1, - 1 * HZ); - if (rc == 0) - audio->stopped = 1; - wake_up(&audio->read_wait); - audmgr_disable(&audio->audmgr); - audio->enabled = 0; - } - return 0; -} - -/* RPC Reply Generator */ -static void rpc_reply(struct msm_rpc_endpoint *ept, uint32_t xid) -{ - int rc = 0; - uint8_t reply_buf[sizeof(struct rpc_reply_hdr)]; - struct rpc_reply_hdr *reply = (struct rpc_reply_hdr *)reply_buf; - - MM_DBG("inside\n"); - reply->xid = cpu_to_be32(xid); - reply->type = cpu_to_be32(RPC_TYPE_REPLY); /* reply */ - reply->reply_stat = cpu_to_be32(RPCMSG_REPLYSTAT_ACCEPTED); - - reply->data.acc_hdr.accept_stat = cpu_to_be32(RPC_ACCEPTSTAT_SUCCESS); - reply->data.acc_hdr.verf_flavor = 0; - reply->data.acc_hdr.verf_length = 0; - - rc = msm_rpc_write(ept, reply_buf, sizeof(reply_buf)); - if (rc < 0) - MM_ERR("could not write RPC response: %d\n", rc); -} - -static void process_rpc_request(uint32_t proc, uint32_t xid, - void *data, int len, void *private) -{ - struct audio_voicememo *audio = private; - - MM_DBG("inside\n"); - /* Sending Ack before processing the request - * to make sure A9 get response immediate - * However, if there is validation of request planned - * may be move this reply Ack at the end */ - rpc_reply(audio->sndept, xid); - switch (proc) { - case SND_VOC_REC_AV_SYNC_CB_PTR_PROC: { - MM_DBG("AV Sync CB:func_id=0x%8x,status=0x%x\n", - be32_to_cpu(( \ - (struct snd_voc_rec_av_sync_cb_func_data *)\ - data)->sync_cb_func_id),\ - be32_to_cpu(( \ - (struct snd_voc_rec_av_sync_cb_func_data *)\ - data)->status)); - break; - } - case SND_VOC_REC_CB_FUNC_TYPE_PROC: { - struct snd_voc_rec_data_cb_func_data *datacb_data - = (void *)(data); - struct snd_voc_rec_put_buf_msg bmsg; - uint32_t rec_status = be32_to_cpu(datacb_data->rec_status); - - MM_DBG("Data CB:func_id=0x%8x,status=0x%x,\ - rec_status=0x%x\n", - be32_to_cpu(datacb_data->cb_func_id),\ - be32_to_cpu(datacb_data->status),\ - be32_to_cpu(datacb_data->rec_status)); - - /* Data recorded */ - if ((rec_status == RPC_VOC_REC_STAT_DATA) || - (rec_status == RPC_VOC_REC_STAT_DONE)) { - if (datacb_data->pkt.fw_data.fw_ptr_status && - be32_to_cpu(datacb_data->pkt.fw_data.rec_length) && - be32_to_cpu(datacb_data->pkt.fw_data.rec_length) - <= MAX_REC_BUF_SIZE) { - - MM_DBG("Copy FW link:rec_buf_size \ - = 0x%08x, rec_length=0x%08x\n", - be32_to_cpu( \ - datacb_data->pkt.fw_data. \ - rec_buffer_size_copy),\ - be32_to_cpu(datacb_data->pkt.fw_data. \ - rec_length)); - - mutex_lock(&audio->dsp_lock); - memcpy(audio->in[audio->fill_next].data, \ - &(datacb_data->pkt.fw_data.data[0]), \ - be32_to_cpu( - datacb_data->pkt.fw_data.rec_length)); - audio->in[audio->fill_next].used = - be32_to_cpu( - datacb_data->pkt.fw_data.rec_length); - audio->in[audio->fill_next].numframes = - be32_to_cpu( - datacb_data->pkt.fw_data.rec_num_frames); - mutex_unlock(&audio->dsp_lock); - } else if (datacb_data->pkt.rw_data.rw_ptr_status && - be32_to_cpu(datacb_data->pkt.rw_data.rec_length) && - be32_to_cpu(datacb_data->pkt.rw_data.rec_length) - <= MAX_REC_BUF_SIZE) { - - MM_DBG("Copy RW link:rec_buf_size \ - =0x%08x, rec_length=0x%08x\n", - be32_to_cpu( \ - datacb_data->pkt.rw_data. \ - rec_buffer_size_copy),\ - be32_to_cpu(datacb_data->pkt.rw_data. \ - rec_length)); - - mutex_lock(&audio->dsp_lock); - memcpy(audio->in[audio->fill_next].data, \ - &(datacb_data->pkt.rw_data.data[0]), \ - be32_to_cpu( - datacb_data->pkt.rw_data.rec_length)); - audio->in[audio->fill_next].used = - be32_to_cpu( - datacb_data->pkt.rw_data.rec_length); - audio->in[audio->fill_next].numframes = - be32_to_cpu( - datacb_data->pkt.rw_data.rec_num_frames); - mutex_unlock(&audio->dsp_lock); - } else { - MM_ERR("FW: ptr_status %d, rec_length=0x%08x," - "RW: ptr_status %d, rec_length=0x%08x\n", - datacb_data->pkt.fw_data.fw_ptr_status, \ - be32_to_cpu( \ - datacb_data->pkt.fw_data.rec_length), \ - datacb_data->pkt.rw_data.rw_ptr_status, \ - be32_to_cpu( \ - datacb_data->pkt.rw_data.rec_length)); - } - if (rec_status != RPC_VOC_REC_STAT_DONE) { - /* Not end of record */ - bmsg.args.buf = \ - (uint32_t) audio->in[audio->fill_next].data; - bmsg.args.num_bytes = \ - be32_to_cpu(audio->in[audio->fill_next].size); - - if (++audio->fill_next == MAX_REC_BUF_COUNT) - audio->fill_next = 0; - - msm_rpc_setup_req(&bmsg.hdr, audio->rpc_prog, - audio->rpc_ver, SND_VOC_REC_PUT_BUF_PROC); - - msm_rpc_write(audio->sndept, &bmsg, - sizeof(bmsg)); - - wake_up(&audio->read_wait); - } else { - /* Indication record stopped gracefully */ - MM_DBG("End Of Voice Record\n"); - audio->stopped = 1; - wake_up(&audio->wait); - } - } else if (rec_status == RPC_VOC_REC_STAT_PAUSED) { - MM_DBG(" Voice Record PAUSED\n"); - audio->pause_resume = 1; - } else if (rec_status == RPC_VOC_REC_STAT_RESUMED) { - MM_DBG(" Voice Record RESUMED\n"); - audio->pause_resume = 0; - } else if ((rec_status == RPC_VOC_REC_STAT_ERROR) || - (rec_status == RPC_VOC_REC_STAT_INVALID_PARAM) || - (rec_status == RPC_VOC_REC_STAT_BUFFER_ERROR)) - MM_ERR("error recording =0x%8x\n", - rec_status); - else if (rec_status == RPC_VOC_REC_STAT_INT_TIME) - MM_DBG("Frames recorded matches interval \ - callback time\n"); - else if (rec_status == RPC_VOC_REC_STAT_AUTO_STOP) { - MM_DBG(" Voice Record AUTO STOP\n"); - mutex_lock(&audio->lock); - audio->stopped = 1; - wake_up(&audio->read_wait); - audmgr_disable(&audio->audmgr); - audvoicememo_ioport_reset(audio); - audio->stopped = 0; - audio->enabled = 0; - mutex_unlock(&audio->lock); - } - break; - } - default: - MM_ERR("UNKNOWN PROC , proc = 0x%8x \n", proc); - } -} - -static int voicememo_rpc_thread(void *data) -{ - struct audio_voicememo *audio = data; - struct rpc_request_hdr *hdr = NULL; - uint32_t type; - int len; - - MM_DBG("start\n"); - - while (!kthread_should_stop()) { - kfree(hdr); - hdr = NULL; - - len = msm_rpc_read(audio->sndept, (void **) &hdr, -1, -1); - MM_DBG("rpc_read len = 0x%x\n", len); - if (len < 0) { - MM_ERR("rpc read failed (%d)\n", len); - break; - } - if (len < RPC_COMMON_HDR_SZ) - continue; - type = be32_to_cpu(hdr->type); - if (type == RPC_TYPE_REPLY) { - struct rpc_reply_hdr *rep = (void *) hdr; - uint32_t status; - if (len < RPC_REPLY_HDR_SZ) - continue; - status = be32_to_cpu(rep->reply_stat); - if (status == RPCMSG_REPLYSTAT_ACCEPTED) { - status = - be32_to_cpu(rep->data.acc_hdr.accept_stat); - - /* Confirm major RPC success during open*/ - if ((audio->enabled == 0) && - (status == RPC_ACCEPTSTAT_SUCCESS) && - (audio->rpc_xid == rep->xid)) { - audio->rpc_status = \ - RPC_STATUS_SUCCESS; - wake_up(&audio->wait); - } - MM_DBG("rpc_reply status 0x%8x\n", status); - } else { - MM_ERR("rpc_reply denied!\n"); - } - /* process reply */ - continue; - } else if (type == RPC_TYPE_REQUEST) { - if (len < RPC_REQUEST_HDR_SZ) - continue; - process_rpc_request(be32_to_cpu(hdr->procedure), - be32_to_cpu(hdr->xid), - (void *) (hdr + 1), - len - sizeof(*hdr), - audio); - } else - MM_ERR("Unexpected type (%d)\n", type); - } - MM_DBG("stop\n"); - kfree(hdr); - hdr = NULL; - - return 0; -} - -/* ------------------- device --------------------- */ -static long audio_voicememo_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct audio_voicememo *audio = file->private_data; - int rc = 0; - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - mutex_lock(&audio->dsp_lock); - stats.byte_count = audio->byte_count; - stats.sample_count = audio->frame_count; - mutex_unlock(&audio->dsp_lock); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: { - MM_DBG("AUDIO_START\n"); - audio->byte_count = 0; - audio->frame_count = 0; - if (audio->voicememo_cfg.rec_type != RPC_VOC_REC_NONE) - rc = audvoicememo_enable(audio); - else - rc = -EINVAL; - MM_DBG("AUDIO_START rc %d\n", rc); - break; - } - case AUDIO_STOP: { - MM_DBG("AUDIO_STOP\n"); - rc = audvoicememo_disable(audio); - audvoicememo_ioport_reset(audio); - audio->stopped = 0; - MM_DBG("AUDIO_STOP rc %d\n", rc); - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config cfg; - MM_DBG("AUDIO_GET_CONFIG\n"); - cfg.buffer_size = audio->rec_buf_size; - cfg.buffer_count = MAX_REC_BUF_COUNT; - cfg.sample_rate = 8000; /* Voice Encoder works on 8k, - * Mono */ - cfg.channel_count = 1; - cfg.type = 0; - cfg.unused[0] = 0; - cfg.unused[1] = 0; - cfg.unused[2] = 0; - if (copy_to_user((void *) arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - else - rc = 0; - MM_DBG("AUDIO_GET_CONFIG rc %d\n", rc); - break; - } - case AUDIO_GET_VOICEMEMO_CONFIG: { - MM_DBG("AUDIO_GET_VOICEMEMO_CONFIG\n"); - if (copy_to_user((void *)arg, &audio->voicememo_cfg, - sizeof(audio->voicememo_cfg))) - rc = -EFAULT; - else - rc = 0; - MM_DBG("AUDIO_GET_VOICEMEMO_CONFIG rc %d\n", rc); - break; - } - case AUDIO_SET_VOICEMEMO_CONFIG: { - struct msm_audio_voicememo_config usr_config; - MM_DBG("AUDIO_SET_VOICEMEMO_CONFIG\n"); - if (copy_from_user - (&usr_config, (void *)arg, - sizeof(usr_config))) { - rc = -EFAULT; - break; - } - if (audvoicememo_validate_usr_config(&usr_config) - == 0) { - audio->voicememo_cfg = usr_config; - rc = 0; - } else - rc = -EINVAL; - MM_DBG("AUDIO_SET_VOICEMEMO_CONFIG rc %d\n", rc); - break; - } - case AUDIO_PAUSE: { - struct rpc_request_hdr rhdr; - MM_DBG("AUDIO_PAUSE\n"); - if (arg == 1) - msm_rpc_setup_req(&rhdr, audio->rpc_prog, - audio->rpc_ver, SND_VOC_REC_PAUSE_PROC); - else - msm_rpc_setup_req(&rhdr, audio->rpc_prog, - audio->rpc_ver, SND_VOC_REC_RESUME_PROC); - - rc = msm_rpc_write(audio->sndept, &rhdr, sizeof(rhdr)); - MM_DBG("AUDIO_PAUSE exit %d\n", rc); - break; - } - default: - MM_ERR("IOCTL %d not supported\n", cmd); - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -static ssize_t audio_voicememo_read(struct file *file, - char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_voicememo *audio = file->private_data; - const char __user *start = buf; - int rc = 0; - - mutex_lock(&audio->read_lock); - - MM_DBG("buff read =0x%8x \n", count); - - while (count > 0) { - rc = wait_event_interruptible_timeout(audio->read_wait, - (audio->in[audio->read_next].used > 0) || - (audio->stopped), - msecs_to_jiffies(MSM_AUD_BUFFER_UPDATE_WAIT_MS)); - - if (rc == 0) { - rc = -ETIMEDOUT; - break; - } else if (rc < 0) - break; - - if (audio->stopped) { - rc = -EBUSY; - break; - } - if (count < audio->in[audio->read_next].used) { - /* Read must happen in frame boundary. Since driver does - * not split frames, read count must be greater or - * equal to size of existing frames to copy - */ - MM_DBG("read not in frame boundary\n"); - break; - } else { - mutex_lock(&audio->dsp_lock); - dma_coherent_post_ops(); - if (copy_to_user - (buf, audio->in[audio->read_next].data, - audio->in[audio->read_next].used)) { - MM_ERR("invalid addr %x \n", (unsigned int)buf); - rc = -EFAULT; - mutex_unlock(&audio->dsp_lock); - break; - } - count -= audio->in[audio->read_next].used; - audio->byte_count += audio->in[audio->read_next].used; - audio->frame_count += - audio->in[audio->read_next].numframes; - buf += audio->in[audio->read_next].used; - audio->in[audio->read_next].used = 0; - mutex_unlock(&audio->dsp_lock); - if ((++audio->read_next) == MAX_REC_BUF_COUNT) - audio->read_next = 0; - if (audio->in[audio->read_next].used == 0) - break; /* No data ready at this moment - * Exit while loop to prevent - * output thread sleep too long - */ - } - } - mutex_unlock(&audio->read_lock); - if (buf > start) - rc = buf - start; - MM_DBG("exit return =0x%8x\n", rc); - return rc; -} - -static ssize_t audio_voicememo_write(struct file *file, - const char __user *buf, - size_t count, loff_t *pos) -{ - return -EINVAL; -} - -static int audio_voicememo_release(struct inode *inode, struct file *file) -{ - struct audio_voicememo *audio = file->private_data; - - mutex_lock(&audio->lock); - audvoicememo_disable(audio); - audvoicememo_flush_buf(audio); - audio->opened = 0; - mutex_unlock(&audio->lock); - return 0; -} - -static int audio_voicememo_open(struct inode *inode, struct file *file) -{ - struct audio_voicememo *audio = &the_audio_voicememo; - int rc; - - mutex_lock(&audio->lock); - if (audio->opened) { - rc = -EBUSY; - goto done; - } - - rc = audmgr_open(&audio->audmgr); - - if (rc) - goto done; - - /*Set default param to None*/ - memset(&audio->voicememo_cfg, 0, sizeof(audio->voicememo_cfg)); - - file->private_data = audio; - audio->opened = 1; - audio->stopped = 0; - rc = 0; -done: - mutex_unlock(&audio->lock); - return rc; -} - -static const struct file_operations audio_fops = { - .owner = THIS_MODULE, - .open = audio_voicememo_open, - .release = audio_voicememo_release, - .read = audio_voicememo_read, - .write = audio_voicememo_write, - .unlocked_ioctl = audio_voicememo_ioctl, -}; - -struct miscdevice audio_voicememo_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_voicememo", - .fops = &audio_fops, -}; - -static int audio_voicememo_probe(struct platform_device *pdev) -{ - int rc; - - if ((pdev->id != (SND_VERS_COMP & RPC_VERSION_MAJOR_MASK)) && - (pdev->id != (SND_VERS2_COMP & RPC_VERSION_MAJOR_MASK))) - return -EINVAL; - - mutex_init(&the_audio_voicememo.lock); - mutex_init(&the_audio_voicememo.read_lock); - mutex_init(&the_audio_voicememo.dsp_lock); - init_waitqueue_head(&the_audio_voicememo.read_wait); - init_waitqueue_head(&the_audio_voicememo.wait); - - the_audio_voicememo.rec_buf_ptr = dma_alloc_coherent(NULL, - MAX_VOICEMEMO_BUF_SIZE, - &the_audio_voicememo.phys, GFP_KERNEL); - if (the_audio_voicememo.rec_buf_ptr == NULL) { - MM_ERR("error allocating memory\n"); - rc = -ENOMEM; - return rc; - } - the_audio_voicememo.rec_buf_size = MAX_REC_BUF_SIZE; - MM_DBG("rec_buf_ptr = 0x%8x, phys = 0x%8x \n", - (uint32_t) the_audio_voicememo.rec_buf_ptr, \ - the_audio_voicememo.phys); - - the_audio_voicememo.sndept = msm_rpc_connect_compatible(SND_PROG, - SND_VERS_COMP, MSM_RPC_UNINTERRUPTIBLE); - if (IS_ERR(the_audio_voicememo.sndept)) { - MM_DBG("connect failed with VERS \ - = %x, trying again with another API\n", - SND_VERS_COMP); - the_audio_voicememo.sndept = msm_rpc_connect_compatible( - SND_PROG, SND_VERS2_COMP, - MSM_RPC_UNINTERRUPTIBLE); - if (IS_ERR(the_audio_voicememo.sndept)) { - rc = PTR_ERR(the_audio_voicememo.sndept); - the_audio_voicememo.sndept = NULL; - MM_ERR("Failed to connect to snd svc\n"); - goto err; - } - the_audio_voicememo.rpc_ver = SND_VERS2_COMP; - } else - the_audio_voicememo.rpc_ver = SND_VERS_COMP; - - the_audio_voicememo.task = kthread_run(voicememo_rpc_thread, - &the_audio_voicememo, "voicememo_rpc"); - if (IS_ERR(the_audio_voicememo.task)) { - rc = PTR_ERR(the_audio_voicememo.task); - the_audio_voicememo.task = NULL; - msm_rpc_close(the_audio_voicememo.sndept); - the_audio_voicememo.sndept = NULL; - MM_ERR("Failed to create voicememo_rpc task\n"); - goto err; - } - the_audio_voicememo.rpc_prog = SND_PROG; - - return misc_register(&audio_voicememo_misc); -err: - dma_free_coherent(NULL, MAX_VOICEMEMO_BUF_SIZE, - the_audio_voicememo.rec_buf_ptr, - the_audio_voicememo.phys); - the_audio_voicememo.rec_buf_ptr = NULL; - return rc; -} - -static void __exit audio_voicememo_exit(void) -{ - /* Close the RPC connection to make thread to comeout */ - msm_rpc_close(the_audio_voicememo.sndept); - the_audio_voicememo.sndept = NULL; - kthread_stop(the_audio_voicememo.task); - the_audio_voicememo.task = NULL; - if (the_audio_voicememo.rec_buf_ptr) - dma_free_coherent(NULL, MAX_VOICEMEMO_BUF_SIZE, - the_audio_voicememo.rec_buf_ptr, - the_audio_voicememo.phys); - the_audio_voicememo.rec_buf_ptr = NULL; - misc_deregister(&audio_voicememo_misc); -} - -static char audio_voicememo_rpc_name[] = "rs00000000"; - -static struct platform_driver audio_voicememo_driver = { - .probe = audio_voicememo_probe, - .driver = { - .owner = THIS_MODULE, - }, - }; - -static int __init audio_voicememo_init(void) -{ - snprintf(audio_voicememo_rpc_name, sizeof(audio_voicememo_rpc_name), - "rs%08x", SND_PROG); - audio_voicememo_driver.driver.name = audio_voicememo_rpc_name; - return platform_driver_register(&audio_voicememo_driver); -} - -module_init(audio_voicememo_init); -module_exit(audio_voicememo_exit); - -MODULE_DESCRIPTION("MSM Voice Memo driver"); -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("QUALCOMM"); diff --git a/arch/arm/mach-msm/qdsp5/audio_wma.c b/arch/arm/mach-msm/qdsp5/audio_wma.c deleted file mode 100644 index d99995351a1e204f97b2a8a0215416d7962507d4..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_wma.c +++ /dev/null @@ -1,1845 +0,0 @@ -/* audio_wma.c - wma audio decoder driver - * - * Copyright (c) 2009, 2011-2012, The Linux Foundation. All rights reserved. - * - * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * - * All source code in this file is licensed under the following license except - * where indicated. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "audmgr.h" - -/* Size must be power of 2 */ -#define BUFSZ_MAX 2062 /* Includes meta in size */ -#define BUFSZ_MIN 1038 /* Includes meta in size */ -#define DMASZ_MAX (BUFSZ_MAX * 2) -#define DMASZ_MIN (BUFSZ_MIN * 2) - -#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF -#define AUDDEC_DEC_WMA 4 - -#define PCM_BUFSZ_MIN 8216 /* Hold one stereo WMA frame and meta out*/ -#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most - but support 2 buffers currently */ -#define ROUTING_MODE_FTRT 1 -#define ROUTING_MODE_RT 2 -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDWMA_METAFIELD_MASK 0xFFFF0000 -#define AUDWMA_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */ -#define AUDWMA_EOS_FLG_MASK 0x01 -#define AUDWMA_EOS_NONE 0x0 /* No EOS detected */ -#define AUDWMA_EOS_SET 0x1 /* EOS set in meta field */ - -#define AUDWMA_EVENT_NUM 10 /* Default number of pre-allocated event packets */ - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; - unsigned short mfield_sz; /*only useful for data has meta field */ -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audwma_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct audwma_event{ - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audio { - struct buffer out[2]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - unsigned out_dma_sz; - - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - /* Host PCM section */ - struct buffer in[PCM_BUF_MAX_COUNT]; - struct mutex read_lock; - wait_queue_head_t read_wait; /* Wait queue for read */ - char *read_data; /* pointer to reader buffer */ - int32_t read_phys; /* physical address of reader buffer */ - uint8_t read_next; /* index to input buffers to be read next */ - uint8_t fill_next; /* index to buffer that DSP should be filling */ - uint8_t pcm_buf_count; /* number of pcm buffer allocated */ - /* ---- End of Host PCM section */ - - struct msm_adsp_module *audplay; - - /* configuration to use on next enable */ - uint32_t out_sample_rate; - uint32_t out_channel_mode; - - struct msm_audio_wma_config wma_config; - struct audmgr audmgr; - - /* data allocated for various buffers */ - char *data; - int32_t phys; /* physical address of write buffer */ - void *map_v_read; - void *map_v_write; - - int mfield; /* meta field embedded in data */ - int rflush; /* Read flush */ - int wflush; /* Write flush */ - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - int pcm_feedback; - int buf_refresh; - int rmt_resource_released; - int teos; /* valid only if tunnel mode & no data left for decoder */ - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - int reserved; /* A byte is being reserved */ - char rsv_byte; /* Handle odd length user data */ - - const char *module_name; - unsigned queue_id; - uint16_t dec_id; - uint32_t read_ptr_offset; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audwma_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - - int eq_enable; - int eq_needs_commit; - audpp_cmd_cfg_object_params_eqalizer eq; - audpp_cmd_cfg_object_params_volume vol_pan; - struct ion_client *client; - struct ion_handle *input_buff_handle; - struct ion_handle *output_buff_handle; -}; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audpp_cmd_cfg_adec_params(struct audio *audio); -static void audpp_cmd_cfg_routing_mode(struct audio *audio); -static void audplay_send_data(struct audio *audio, unsigned needed); -static void audplay_config_hostpcm(struct audio *audio); -static void audplay_buffer_refresh(struct audio *audio); -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg); -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audwma_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); -#endif - -static int rmt_put_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_DISABLE; - cmd.dec_type = AUDDEC_DEC_WMA; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - - return put_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -static int rmt_get_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_ENABLE; - cmd.dec_type = AUDDEC_DEC_WMA; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - - return get_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -/* must be called with audio->lock held */ -static int audio_enable(struct audio *audio) -{ - struct audmgr_config cfg; - int rc; - - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) - return 0; - - if (audio->rmt_resource_released == 1) { - audio->rmt_resource_released = 0; - rc = rmt_get_resource(audio); - if (rc) { - MM_ERR("ADSP resources are not available for WMA \ - session 0x%08x on decoder: %d\n Ignoring \ - error and going ahead with the playback\n", - (int)audio, audio->dec_id); - } - } - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_tail = 0; - audio->out_needed = 0; - - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) { - cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; - cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000; - cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK; - cfg.codec = RPC_AUD_DEF_CODEC_WMA; - cfg.snd_method = RPC_SND_METHOD_MIDI; - - rc = audmgr_enable(&audio->audmgr, &cfg); - if (rc < 0) - return rc; - } - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - - audio->enabled = 1; - return 0; -} - -/* must be called with audio->lock held */ -static int audio_disable(struct audio *audio) -{ - int rc = 0; - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - audio->stopped = 1; - wake_up(&audio->write_wait); - wake_up(&audio->read_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_disable(&audio->audmgr); - audio->out_needed = 0; - rmt_put_resource(audio); - audio->rmt_resource_released = 1; - } - return rc; -} - -/* ------------------- dsp --------------------- */ -static void audio_update_pcm_buf_entry(struct audio *audio, - uint32_t *payload) -{ - uint8_t index; - unsigned long flags; - - if (audio->rflush) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < payload[1]; index++) { - if (audio->in[audio->fill_next].addr == - payload[2 + index * 2]) { - MM_DBG("audio_update_pcm_buf_entry: \ - in[%d] ready\n", audio->fill_next); - audio->in[audio->fill_next].used = - payload[3 + index * 2]; - if ((++audio->fill_next) == audio->pcm_buf_count) - audio->fill_next = 0; - } else { - MM_ERR("audio_update_pcm_buf_entry: \ - expected=%x ret=%x\n", - audio->in[audio->fill_next].addr, - payload[1 + index * 2]); - break; - } - } - if (audio->in[audio->fill_next].used == 0) { - audplay_buffer_refresh(audio); - } else { - MM_DBG("read cannot keep up\n"); - audio->buf_refresh = 1; - } - wake_up(&audio->read_wait); - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - - getevent(msg, sizeof(msg)); - - MM_DBG("msg_id=%x\n", id); - - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audplay_send_data(audio, 1); - break; - - case AUDPLAY_MSG_BUFFER_UPDATE: - audio_update_pcm_buf_entry(audio, msg); - break; - - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audplaytask)\n"); - break; - - default: - MM_ERR("unexpected message from decoder \n"); - break; - } -} - -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status:sleep reason = \ - 0x%04x\n", reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init\n"); - if (audio->pcm_feedback) - audpp_cmd_cfg_routing_mode(audio); - else - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg\n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play\n"); - if (audio->pcm_feedback) { - audplay_config_hostpcm(audio); - audplay_buffer_refresh(audio); - } - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - default: - MM_ERR("unknown decoder status\n"); - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - audpp_dsp_set_eq(audio->dec_id, audio->eq_enable, - &audio->eq); - audpp_avsync(audio->dec_id, 22050); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audpp_avsync(audio->dec_id, 0); - audio->running = 0; - } else { - MM_DBG("CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_ROUTING_ACK: - MM_DBG("ROUTING_ACK mode=%d\n", msg[1]); - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - audio->rflush = 0; - wake_up(&audio->write_wait); - if (audio->pcm_feedback) - audplay_buffer_refresh(audio); - break; - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - - default: - MM_ERR("UNKNOWN (%d)\n", id); - } - -} - -static struct msm_adsp_ops audplay_adsp_ops_wma = { - .event = audplay_dsp_event, -}; - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id, \ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - u16 cfg_dec_cmd[AUDPP_CMD_CFG_DEC_TYPE_LEN / sizeof(unsigned short)]; - - memset(cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - cfg_dec_cmd[0] = AUDPP_CMD_CFG_DEC_TYPE; - if (enable) - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_WMA; - else - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} - -static void audpp_cmd_cfg_adec_params(struct audio *audio) -{ - struct audpp_cmd_cfg_adec_params_wma cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_WMA_LEN; - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = audio->out_sample_rate; - - /* - * Test done for sample with the following configuration - * armdatareqthr = 1262 - * channelsdecoded = 1(MONO)/2(STEREO) - * wmabytespersec = Tested with 6003 Bytes per sec - * wmasamplingfreq = 44100 - * wmaencoderopts = 31 - */ - - cmd.armdatareqthr = audio->wma_config.armdatareqthr; - cmd.channelsdecoded = audio->wma_config.channelsdecoded; - cmd.wmabytespersec = audio->wma_config.wmabytespersec; - cmd.wmasamplingfreq = audio->wma_config.wmasamplingfreq; - cmd.wmaencoderopts = audio->wma_config.wmaencoderopts; - - audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static void audpp_cmd_cfg_routing_mode(struct audio *audio) -{ - struct audpp_cmd_routing_mode cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; - cmd.object_number = audio->dec_id; - if (audio->pcm_feedback) - cmd.routing_mode = ROUTING_MODE_FTRT; - else - cmd.routing_mode = ROUTING_MODE_RT; - - audpp_send_queue1(&cmd, sizeof(cmd)); -} - -static void audplay_buffer_refresh(struct audio *audio) -{ - struct audplay_cmd_buffer_refresh refresh_cmd; - - refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; - refresh_cmd.num_buffers = 1; - refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; - refresh_cmd.buf0_length = audio->in[audio->fill_next].size; - refresh_cmd.buf_read_count = 0; - - MM_DBG("buf0_addr=%x buf0_len=%d\n", - refresh_cmd.buf0_address, - refresh_cmd.buf0_length); - - (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); -} - -static void audplay_config_hostpcm(struct audio *audio) -{ - struct audplay_cmd_hpcm_buf_cfg cfg_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; - cfg_cmd.max_buffers = audio->pcm_buf_count; - cfg_cmd.byte_swap = 0; - cfg_cmd.hostpcm_config = (0x8000) | (0x4000); - cfg_cmd.feedback_frequency = 1; - cfg_cmd.partition_number = 0; - - (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); -} - - -static int audplay_dsp_send_data_avail(struct audio *audio, - unsigned idx, unsigned len) -{ - struct audplay_cmd_bitstream_data_avail_nt2 cmd; - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2; - if (audio->mfield) - cmd.decoder_id = AUDWMA_METAFIELD_MASK | - (audio->out[idx].mfield_sz >> 1); - else - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = audio->out[idx].addr; - cmd.buf_size = len/2; - cmd.partition_number = 0; - /* complete writes to the input buffer */ - wmb(); - return audplay_send_queue0(audio, &cmd, sizeof(cmd)); -} - -static void audplay_send_data(struct audio *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (audio->wflush) { - audio->out_needed = 1; - goto done; - } - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - MM_DBG("\n"); /* Macro prints the file name and function */ - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - MM_DBG("frame %d busy\n", audio->out_tail); - audplay_dsp_send_data_avail(audio, audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } -done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ - -static void audio_flush(struct audio *audio) -{ - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->reserved = 0; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - atomic_set(&audio->out_bytes, 0); -} - -static void audio_flush_pcm_buf(struct audio *audio) -{ - uint8_t index; - - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < PCM_BUF_MAX_COUNT; index++) - audio->in[index].used = 0; - audio->buf_refresh = 0; - audio->read_next = 0; - audio->fill_next = 0; - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audio_ioport_reset(struct audio *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audio_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->read_wait); - mutex_lock(&audio->read_lock); - audio_flush_pcm_buf(audio); - mutex_unlock(&audio->read_lock); -} - -static int audwma_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audwma_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audwma_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audwma_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audwma_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - -static long audwma_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audwma_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - audio->event_wait, audwma_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audwma_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - rc = 0; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audwma_event, list); - list_del(&drv_evt->list); - } - - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audio_enable_eq(struct audio *audio, int enable) -{ - if (audio->eq_enable == enable && !audio->eq_needs_commit) - return 0; - - audio->eq_enable = enable; - - if (audio->running) { - audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq); - audio->eq_needs_commit = 0; - } - return 0; -} - -static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - unsigned long flags = 0; - uint16_t enable_mask; - int enable; - int prev_state; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - int len = 0; - - MM_DBG("cmd = %d\n", cmd); - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = audpp_avsync_byte_count(audio->dec_id); - stats.sample_count = audpp_avsync_sample_count(audio->dec_id); - if (copy_to_user((void *)arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - switch (cmd) { - case AUDIO_ENABLE_AUDPP: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - spin_lock_irqsave(&audio->dsp_lock, flags); - enable = (enable_mask & EQ_ENABLE) ? 1 : 0; - audio_enable_eq(audio, enable); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - case AUDIO_SET_VOLUME: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.volume = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_PAN: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.pan = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_EQ: - prev_state = audio->eq_enable; - audio->eq_enable = 0; - if (copy_from_user(&audio->eq.num_bands, (void *) arg, - sizeof(audio->eq) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) { - rc = -EFAULT; - break; - } - audio->eq_enable = prev_state; - audio->eq_needs_commit = 1; - rc = 0; - break; - } - - if (-EINVAL != rc) - return rc; - - if (cmd == AUDIO_GET_EVENT) { - MM_DBG("AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audwma_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audio_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) - rc = -ENODEV; - else - rc = 0; - } - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audio_disable(audio); - audio_ioport_reset(audio); - audio->stopped = 0; - break; - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audio_ioport_reset(audio); - if (audio->running) { - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - case AUDIO_SET_CONFIG: { - struct msm_audio_config config; - if (copy_from_user(&config, (void *) arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.channel_count == 1) { - config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V; - } else if (config.channel_count == 2) { - config.channel_count = AUDPP_CMD_PCM_INTF_STEREO_V; - } else { - rc = -EINVAL; - break; - } - audio->mfield = config.meta_field; - audio->out_sample_rate = config.sample_rate; - audio->out_channel_mode = config.channel_count; - rc = 0; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config config; - config.buffer_size = (audio->out_dma_sz >> 1); - config.buffer_count = 2; - config.sample_rate = audio->out_sample_rate; - if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) - config.channel_count = 1; - else - config.channel_count = 2; - config.meta_field = 0; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *) arg, &config, sizeof(config))) - rc = -EFAULT; - else - rc = 0; - - break; - } - case AUDIO_GET_WMA_CONFIG:{ - if (copy_to_user((void *)arg, &audio->wma_config, - sizeof(audio->wma_config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_WMA_CONFIG:{ - struct msm_audio_wma_config usr_config; - - if (copy_from_user - (&usr_config, (void *)arg, - sizeof(usr_config))) { - rc = -EFAULT; - break; - } - - audio->wma_config = usr_config; - rc = 0; - break; - } - case AUDIO_GET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - config.pcm_feedback = audio->pcm_feedback; - config.buffer_count = PCM_BUF_MAX_COUNT; - config.buffer_size = PCM_BUFSZ_MIN; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.pcm_feedback != audio->pcm_feedback) { - MM_ERR("Not sufficient permission to" - "change the playback mode\n"); - rc = -EACCES; - break; - } - if ((config.buffer_count > PCM_BUF_MAX_COUNT) || - (config.buffer_count == 1)) - config.buffer_count = PCM_BUF_MAX_COUNT; - - if (config.buffer_size < PCM_BUFSZ_MIN) - config.buffer_size = PCM_BUFSZ_MIN; - - /* Check if pcm feedback is required */ - if ((config.pcm_feedback) && (!audio->read_data)) { - MM_DBG("allocate PCM buffer %d\n", - config.buffer_count * - config.buffer_size); - handle = ion_alloc(audio->client, - (config.buffer_size * - config.buffer_count), - SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to alloc I/P buffs\n"); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - break; - } - - audio->input_buff_handle = handle; - - rc = ion_phys(audio->client , - handle, &addr, &len); - if (rc) { - MM_ERR("Invalid phy: %x sz: %x\n", - (unsigned int) addr, - (unsigned int) len); - ion_free(audio->client, handle); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - break; - } else { - MM_INFO("Got valid phy: %x sz: %x\n", - (unsigned int) audio->read_phys, - (unsigned int) len); - } - audio->read_phys = (int32_t)addr; - - rc = ion_handle_get_flags(audio->client, - handle, &ionflag); - if (rc) { - MM_ERR("could not get flags\n"); - ion_free(audio->client, handle); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - break; - } - - audio->map_v_read = ion_map_kernel( - audio->client, handle); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("map of read buf failed\n"); - ion_free(audio->client, handle); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - } else { - uint8_t index; - uint32_t offset = 0; - audio->read_data = - audio->map_v_read; - audio->buf_refresh = 0; - audio->pcm_buf_count = - config.buffer_count; - audio->read_next = 0; - audio->fill_next = 0; - - for (index = 0; - index < config.buffer_count; - index++) { - audio->in[index].data = - audio->read_data + offset; - audio->in[index].addr = - audio->read_phys + offset; - audio->in[index].size = - config.buffer_size; - audio->in[index].used = 0; - offset += config.buffer_size; - } - MM_DBG("read buf: phy addr \ - 0x%08x kernel addr 0x%08x\n", - audio->read_phys, - (int)audio->read_data); - rc = 0; - } - } else { - rc = 0; - } - break; - } - case AUDIO_PAUSE: - MM_DBG("AUDIO_PAUSE %ld\n", arg); - rc = audpp_pause(audio->dec_id, (int) arg); - break; - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -static int audio_fsync(struct file *file, loff_t a, loff_t b, - int datasync) -{ - struct audio *audio = file->private_data; - struct buffer *frame; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (!audio->running || audio->pcm_feedback) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (audio->reserved) { - MM_DBG("send reserved byte\n"); - frame = audio->out + audio->out_tail; - ((char *) frame->data)[0] = audio->rsv_byte; - ((char *) frame->data)[1] = 0; - frame->used = 2; - audplay_send_data(audio, 0); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - } - - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush); - - if (audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; -} - -static ssize_t audio_read(struct file *file, char __user *buf, size_t count, - loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - int rc = 0; - - if (!audio->pcm_feedback) - return 0; /* PCM feedback is not enabled. Nothing to read */ - - mutex_lock(&audio->read_lock); - MM_DBG("%d \n", count); - while (count > 0) { - rc = wait_event_interruptible(audio->read_wait, - (audio->in[audio->read_next].used > 0) || - (audio->stopped) || (audio->rflush)); - - if (rc < 0) - break; - - if (audio->stopped || audio->rflush) { - rc = -EBUSY; - break; - } - - if (count < audio->in[audio->read_next].used) { - /* Read must happen in frame boundary. Since driver - does not know frame size, read count must be greater - or equal to size of PCM samples */ - MM_DBG("audio_read: no partial frame done reading\n"); - break; - } else { - MM_DBG("audio_read: read from in[%d]\n", - audio->read_next); - /* order reads from the output buffer */ - rmb(); - if (copy_to_user - (buf, audio->in[audio->read_next].data, - audio->in[audio->read_next].used)) { - MM_ERR("invalid addr %x \n", (unsigned int)buf); - rc = -EFAULT; - break; - } - count -= audio->in[audio->read_next].used; - buf += audio->in[audio->read_next].used; - audio->in[audio->read_next].used = 0; - if ((++audio->read_next) == audio->pcm_buf_count) - audio->read_next = 0; - break; /* Force to exit while loop - * to prevent output thread - * sleep too long if data is - * not ready at this moment. - */ - } - } - - /* don't feed output buffer to HW decoder during flushing - * buffer refresh command will be sent once flush completes - * send buf refresh command here can confuse HW decoder - */ - if (audio->buf_refresh && !audio->rflush) { - audio->buf_refresh = 0; - MM_DBG("kick start pcm feedback again\n"); - audplay_buffer_refresh(audio); - } - - mutex_unlock(&audio->read_lock); - - if (buf > start) - rc = buf - start; - - MM_DBG("read %d bytes\n", rc); - return rc; -} - -static int audwma_process_eos(struct audio *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - int rc = 0; - struct buffer *frame; - char *buf_ptr; - - if (audio->reserved) { - MM_DBG("flush reserve byte\n"); - frame = audio->out + audio->out_head; - buf_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - buf_ptr[0] = audio->rsv_byte; - buf_ptr[1] = 0; - audio->out_head ^= 1; - frame->mfield_sz = 0; - frame->used = 2; - audio->reserved = 0; - audplay_send_data(audio, 0); - } - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - audplay_send_data(audio, 0); -done: - return rc; -} - -static ssize_t audio_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - char *cpy_ptr; - int rc = 0, eos_condition = AUDWMA_EOS_NONE; - unsigned dsize; - unsigned short mfield_size = 0; - - MM_DBG("cnt=%d\n", count); - - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - cpy_ptr = frame->data; - dsize = 0; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - break; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - break; - } - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - break; - } else if (mfield_size > count) { - rc = -EINVAL; - break; - } - MM_DBG("audio_write: mf offset_val %x\n", - mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - break; - } - /* Check if EOS flag is set and buffer has - * contains just meta field - */ - if (cpy_ptr[AUDWMA_EOS_FLG_OFFSET] & - AUDWMA_EOS_FLG_MASK) { - MM_DBG("audio_write: EOS SET\n"); - eos_condition = AUDWMA_EOS_SET; - if (mfield_size == count) { - buf += mfield_size; - break; - } else - cpy_ptr[AUDWMA_EOS_FLG_OFFSET] - &= ~AUDWMA_EOS_FLG_MASK; - } - cpy_ptr += mfield_size; - count -= mfield_size; - dsize += mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("audio_write: continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - - if (audio->reserved) { - MM_DBG("append reserved byte %x\n", audio->rsv_byte); - *cpy_ptr = audio->rsv_byte; - xfer = (count > ((frame->size - mfield_size) - 1)) ? - (frame->size - mfield_size) - 1 : count; - cpy_ptr++; - dsize += 1; - audio->reserved = 0; - } else - xfer = (count > (frame->size - mfield_size)) ? - (frame->size - mfield_size) : count; - - if (copy_from_user(cpy_ptr, buf, xfer)) { - rc = -EFAULT; - break; - } - - dsize += xfer; - if (dsize & 1) { - audio->rsv_byte = ((char *) frame->data)[dsize - 1]; - MM_DBG("odd length buf reserve last byte %x\n", - audio->rsv_byte); - audio->reserved = 1; - dsize--; - } - count -= xfer; - buf += xfer; - - if (dsize > 0) { - audio->out_head ^= 1; - frame->used = dsize; - audplay_send_data(audio, 0); - } - } - if (eos_condition == AUDWMA_EOS_SET) - rc = audwma_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - if (!rc) { - if (buf > start) - return buf - start; - } - return rc; -} - -static int audio_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_INFO("audio instance 0x%08x freeing\n", (int)audio); - mutex_lock(&audio->lock); - audio_disable(audio); - if (audio->rmt_resource_released == 0) - rmt_put_resource(audio); - audio_flush(audio); - audio_flush_pcm_buf(audio); - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->event_abort = 1; - wake_up(&audio->event_wait); - audwma_reset_event_queue(audio); - ion_unmap_kernel(audio->client, audio->output_buff_handle); - ion_free(audio->client, audio->output_buff_handle); - if (audio->input_buff_handle != NULL) { - ion_unmap_kernel(audio->client, audio->input_buff_handle); - ion_free(audio->client, audio->input_buff_handle); - } - ion_client_destroy(audio->client); - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - kfree(audio); - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audwma_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audwma_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audwma_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audwma_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -static void audwma_suspend(struct early_suspend *h) -{ - struct audwma_suspend_ctl *ctl = - container_of(h, struct audwma_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audwma_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audwma_resume(struct early_suspend *h) -{ - struct audwma_suspend_ctl *ctl = - container_of(h, struct audwma_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audwma_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audwma_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audwma_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 4096; - static char buffer[4096]; - int n = 0, i; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_feedback %d\n", audio->pcm_feedback); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_buf_sz %d\n", audio->out[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_count %d \n", audio->pcm_buf_count); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_sz %d \n", audio->in[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %x \n", audio->vol_pan.volume); - n += scnprintf(buffer + n, debug_bufmax - n, - "sample rate %d \n", audio->out_sample_rate); - n += scnprintf(buffer + n, debug_bufmax - n, - "channel mode %d \n", audio->out_channel_mode); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "rflush %d\n", audio->rflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d \n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d \n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d \n", audio->out_needed); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_head %d \n", audio->out_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_tail %d \n", audio->out_tail); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[0].used %d \n", audio->out[0].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[1].used %d \n", audio->out[1].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "buffer_refresh %d \n", audio->buf_refresh); - n += scnprintf(buffer + n, debug_bufmax - n, - "read_next %d \n", audio->read_next); - n += scnprintf(buffer + n, debug_bufmax - n, - "fill_next %d \n", audio->fill_next); - for (i = 0; i < audio->pcm_buf_count; i++) - n += scnprintf(buffer + n, debug_bufmax - n, - "in[%d].size %d \n", i, audio->in[i].used); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audwma_debug_fops = { - .read = audwma_debug_read, - .open = audwma_debug_open, -}; -#endif - -static int audio_open(struct inode *inode, struct file *file) -{ - struct audio *audio = NULL; - int rc, dec_attrb, decid, i; - unsigned mem_sz = DMASZ_MAX; - struct audwma_event *e_node = NULL; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - struct ion_client *client = NULL; - int len = 0; -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_wma_" + 5]; -#endif - - /* Allocate Mem for audio instance */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("no memory to allocate audio instance \n"); - rc = -ENOMEM; - goto done; - } - MM_INFO("audio instance 0x%08x created\n", (int)audio); - - /* Allocate the decoder */ - dec_attrb = AUDDEC_DEC_WMA; - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_NONTUNNEL; - audio->pcm_feedback = NON_TUNNEL_MODE_PLAYBACK; - } else if ((file->f_mode & FMODE_WRITE) && - !(file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_TUNNEL; - audio->pcm_feedback = TUNNEL_MODE_PLAYBACK; - } else { - kfree(audio); - rc = -EACCES; - goto done; - } - - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - - if (decid < 0) { - MM_ERR("No free decoder available, freeing instance 0x%08x\n", - (int)audio); - rc = -ENODEV; - kfree(audio); - goto done; - } - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - client = msm_ion_client_create(UINT_MAX, "Audio_WMA_Client"); - if (IS_ERR_OR_NULL(client)) { - pr_err("Unable to create ION client\n"); - rc = -ENOMEM; - goto client_create_error; - } - audio->client = client; - - handle = ion_alloc(client, mem_sz, SZ_4K, - ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to create allocate O/P buffers\n"); - rc = -ENOMEM; - goto output_buff_alloc_error; - } - audio->output_buff_handle = handle; - - rc = ion_phys(client, handle, &addr, &len); - if (rc) { - MM_ERR("O/P buffers:Invalid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - goto output_buff_get_phys_error; - } else { - MM_INFO("O/P buffers:valid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - } - audio->phys = (int32_t)addr; - - - rc = ion_handle_get_flags(client, handle, &ionflag); - if (rc) { - MM_ERR("could not get flags for the handle\n"); - goto output_buff_get_flags_error; - } - - audio->map_v_write = ion_map_kernel(client, handle); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write buffers\n"); - rc = -ENOMEM; - goto output_buff_map_error; - } - audio->data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->phys, (int)audio->data); - - audio->out_dma_sz = mem_sz; - - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) { - rc = audmgr_open(&audio->audmgr); - if (rc) { - MM_ERR("audmgr open failed, freeing instance \ - 0x%08x\n", (int)audio); - goto err; - } - } - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audplay_adsp_ops_wma, audio); - if (rc) { - MM_ERR("failed to get %s module, freeing instance 0x%08x\n", - audio->module_name, (int)audio); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_close(&audio->audmgr); - goto err; - } - - rc = rmt_get_resource(audio); - if (rc) { - MM_ERR("ADSP resources are not available for WMA session \ - 0x%08x on decoder: %d\n", (int)audio, audio->dec_id); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_close(&audio->audmgr); - msm_adsp_put(audio->audplay); - goto err; - } - - audio->input_buff_handle = NULL; - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->read_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - init_waitqueue_head(&audio->write_wait); - init_waitqueue_head(&audio->read_wait); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - spin_lock_init(&audio->event_queue_lock); - - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = audio->out_dma_sz >> 1; - - audio->out[1].data = audio->data + audio->out[0].size; - audio->out[1].addr = audio->phys + audio->out[0].size; - audio->out[1].size = audio->out[0].size; - - audio->wma_config.armdatareqthr = 1262; - audio->wma_config.channelsdecoded = 2; - audio->wma_config.wmabytespersec = 6003; - audio->wma_config.wmasamplingfreq = 44100; - audio->wma_config.wmaencoderopts = 31; - - audio->out_sample_rate = 44100; - audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V; - - audio->vol_pan.volume = 0x2000; - - audio_flush(audio); - - file->private_data = audio; - audio->opened = 1; -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_wma_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, - &audwma_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audwma_resume; - audio->suspend_ctl.node.suspend = audwma_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (i = 0; i < AUDWMA_EVENT_NUM; i++) { - e_node = kmalloc(sizeof(struct audwma_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } -done: - return rc; -err: - ion_unmap_kernel(client, audio->output_buff_handle); -output_buff_map_error: -output_buff_get_phys_error: -output_buff_get_flags_error: - ion_free(client, audio->output_buff_handle); -output_buff_alloc_error: - ion_client_destroy(client); -client_create_error: - audpp_adec_free(audio->dec_id); - kfree(audio); - return rc; -} - -static const struct file_operations audio_wma_fops = { - .owner = THIS_MODULE, - .open = audio_open, - .release = audio_release, - .read = audio_read, - .write = audio_write, - .unlocked_ioctl = audio_ioctl, - .fsync = audio_fsync, -}; - -struct miscdevice audio_wma_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_wma", - .fops = &audio_wma_fops, -}; - -static int __init audio_init(void) -{ - return misc_register(&audio_wma_misc); -} - -device_initcall(audio_init); diff --git a/arch/arm/mach-msm/qdsp5/audio_wmapro.c b/arch/arm/mach-msm/qdsp5/audio_wmapro.c deleted file mode 100644 index 4480bc09e44c6dfb100a016b0607eb6eea7ce256..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audio_wmapro.c +++ /dev/null @@ -1,1831 +0,0 @@ -/* audio_wmapro.c - wmapro audio decoder driver - * - * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. - * - * All source code in this file is licensed under the following license except - * where indicated. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "audmgr.h" - -/* Size must be power of 2 */ -#define BUFSZ_MAX 8206 /* Includes meta in size */ -#define BUFSZ_MIN 2062 /* Includes meta in size */ -#define DMASZ_MAX (BUFSZ_MAX * 2) -#define DMASZ_MIN (BUFSZ_MIN * 2) - -#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF -#define AUDDEC_DEC_WMAPRO 13 - -#define PCM_BUFSZ_MIN 8216 /* Hold one stereo WMAPRO frame and meta out*/ -#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most - but support 2 buffers currently */ -#define ROUTING_MODE_FTRT 1 -#define ROUTING_MODE_RT 2 -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDWMAPRO_METAFIELD_MASK 0xFFFF0000 -#define AUDWMAPRO_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */ -#define AUDWMAPRO_EOS_FLG_MASK 0x01 -#define AUDWMAPRO_EOS_NONE 0x0 /* No EOS detected */ -#define AUDWMAPRO_EOS_SET 0x1 /* EOS set in meta field */ - -#define AUDWMAPRO_EVENT_NUM 10 /* Default no. of pre-allocated event packets */ - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; - unsigned short mfield_sz; /*only useful for data has meta field */ -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audwmapro_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct audwmapro_event{ - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audio { - struct buffer out[2]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - unsigned out_dma_sz; - - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - /* Host PCM section */ - struct buffer in[PCM_BUF_MAX_COUNT]; - struct mutex read_lock; - wait_queue_head_t read_wait; /* Wait queue for read */ - char *read_data; /* pointer to reader buffer */ - int32_t read_phys; /* physical address of reader buffer */ - uint8_t read_next; /* index to input buffers to be read next */ - uint8_t fill_next; /* index to buffer that DSP should be filling */ - uint8_t pcm_buf_count; /* number of pcm buffer allocated */ - /* ---- End of Host PCM section */ - - struct msm_adsp_module *audplay; - - /* configuration to use on next enable */ - uint32_t out_sample_rate; - uint32_t out_channel_mode; - - struct msm_audio_wmapro_config wmapro_config; - struct audmgr audmgr; - - /* data allocated for various buffers */ - char *data; - int32_t phys; /* physical address of write buffer */ - void *map_v_read; - void *map_v_write; - - int mfield; /* meta field embedded in data */ - int rflush; /* Read flush */ - int wflush; /* Write flush */ - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - int pcm_feedback; - int buf_refresh; - int rmt_resource_released; - int teos; /* valid only if tunnel mode & no data left for decoder */ - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - int reserved; /* A byte is being reserved */ - char rsv_byte; /* Handle odd length user data */ - - const char *module_name; - unsigned queue_id; - uint16_t dec_id; - uint32_t read_ptr_offset; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audwmapro_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - - int eq_enable; - int eq_needs_commit; - audpp_cmd_cfg_object_params_eqalizer eq; - audpp_cmd_cfg_object_params_volume vol_pan; - struct ion_client *client; - struct ion_handle *input_buff_handle; - struct ion_handle *output_buff_handle; -}; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audpp_cmd_cfg_adec_params(struct audio *audio); -static void audpp_cmd_cfg_routing_mode(struct audio *audio); -static void audplay_send_data(struct audio *audio, unsigned needed); -static void audplay_config_hostpcm(struct audio *audio); -static void audplay_buffer_refresh(struct audio *audio); -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg); -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audwmapro_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); -#endif - -static int rmt_put_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_DISABLE; - cmd.dec_type = AUDDEC_DEC_WMAPRO; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - - return put_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -static int rmt_get_resource(struct audio *audio) -{ - struct aud_codec_config_cmd cmd; - unsigned short client_idx; - - cmd.cmd_id = RM_CMD_AUD_CODEC_CFG; - cmd.client_id = RM_AUD_CLIENT_ID; - cmd.task_id = audio->dec_id; - cmd.enable = RMT_ENABLE; - cmd.dec_type = AUDDEC_DEC_WMAPRO; - client_idx = ((cmd.client_id << 8) | cmd.task_id); - - return get_adsp_resource(client_idx, &cmd, sizeof(cmd)); -} - -/* must be called with audio->lock held */ -static int audio_enable(struct audio *audio) -{ - struct audmgr_config cfg; - int rc; - - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) - return 0; - - if (audio->rmt_resource_released == 1) { - audio->rmt_resource_released = 0; - rc = rmt_get_resource(audio); - if (rc) { - MM_ERR("ADSP resources are not available for WMAPRO \ - session 0x%08x on decoder: %d\n Ignoring \ - error and going ahead with the playback\n", - (int)audio, audio->dec_id); - } - } - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_tail = 0; - audio->out_needed = 0; - - cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; - cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000; - cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK; - cfg.codec = RPC_AUD_DEF_CODEC_WMA; - cfg.snd_method = RPC_SND_METHOD_MIDI; - - rc = audmgr_enable(&audio->audmgr, &cfg); - if (rc < 0) - return rc; - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - audmgr_disable(&audio->audmgr); - return -ENODEV; - } - - audio->enabled = 1; - return 0; -} - -/* must be called with audio->lock held */ -static int audio_disable(struct audio *audio) -{ - int rc = 0; - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - audio->stopped = 1; - wake_up(&audio->write_wait); - wake_up(&audio->read_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - audmgr_disable(&audio->audmgr); - audio->out_needed = 0; - rmt_put_resource(audio); - audio->rmt_resource_released = 1; - } - return rc; -} - -/* ------------------- dsp --------------------- */ -static void audio_update_pcm_buf_entry(struct audio *audio, - uint32_t *payload) -{ - uint8_t index; - unsigned long flags; - - if (audio->rflush) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < payload[1]; index++) { - if (audio->in[audio->fill_next].addr == - payload[2 + index * 2]) { - MM_DBG("audio_update_pcm_buf_entry: \ - in[%d] ready\n", audio->fill_next); - audio->in[audio->fill_next].used = - payload[3 + index * 2]; - if ((++audio->fill_next) == audio->pcm_buf_count) - audio->fill_next = 0; - } else { - MM_ERR("audio_update_pcm_buf_entry: \ - expected=%x ret=%x\n", - audio->in[audio->fill_next].addr, - payload[1 + index * 2]); - break; - } - } - if (audio->in[audio->fill_next].used == 0) { - audplay_buffer_refresh(audio); - } else { - MM_DBG("read cannot keep up\n"); - audio->buf_refresh = 1; - } - wake_up(&audio->read_wait); - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - - getevent(msg, sizeof(msg)); - - MM_DBG("msg_id=%x\n", id); - - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audplay_send_data(audio, 1); - break; - - case AUDPLAY_MSG_BUFFER_UPDATE: - audio_update_pcm_buf_entry(audio, msg); - break; - - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audplaytask)\n"); - break; - - default: - MM_ERR("unexpected message from decoder \n"); - break; - } -} - -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status:sleep reason = \ - 0x%04x\n", reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init\n"); - if (audio->pcm_feedback) - audpp_cmd_cfg_routing_mode(audio); - else - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg\n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play\n"); - if (audio->pcm_feedback) { - audplay_config_hostpcm(audio); - audplay_buffer_refresh(audio); - } - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - default: - MM_ERR("unknown decoder status\n"); - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - audpp_dsp_set_eq(audio->dec_id, audio->eq_enable, - &audio->eq); - audpp_avsync(audio->dec_id, 22050); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audpp_avsync(audio->dec_id, 0); - audio->running = 0; - } else { - MM_DBG("CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_ROUTING_ACK: - MM_DBG("ROUTING_ACK mode=%d\n", msg[1]); - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - audio->rflush = 0; - wake_up(&audio->write_wait); - if (audio->pcm_feedback) - audplay_buffer_refresh(audio); - break; - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - - default: - MM_ERR("UNKNOWN (%d)\n", id); - } - -} - -static struct msm_adsp_ops audplay_adsp_ops_wmapro = { - .event = audplay_dsp_event, -}; - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id, \ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - u16 cfg_dec_cmd[AUDPP_CMD_CFG_DEC_TYPE_LEN / sizeof(unsigned short)]; - - memset(cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - cfg_dec_cmd[0] = AUDPP_CMD_CFG_DEC_TYPE; - if (enable) - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_WMAPRO; - else - cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} - -static void audpp_cmd_cfg_adec_params(struct audio *audio) -{ - struct audpp_cmd_cfg_adec_params_wmapro cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_WMAPRO_LEN; - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = audio->out_sample_rate; - - cmd.armdatareqthr = audio->wmapro_config.armdatareqthr; - cmd.numchannels = audio->wmapro_config.numchannels; - cmd.validbitspersample = audio->wmapro_config.validbitspersample; - cmd.formattag = audio->wmapro_config.formattag; - cmd.samplingrate = audio->wmapro_config.samplingrate; - cmd.avgbytespersecond = audio->wmapro_config.avgbytespersecond; - cmd.asfpacketlength = audio->wmapro_config.asfpacketlength; - cmd.channelmask = audio->wmapro_config.channelmask; - cmd.encodeopt = audio->wmapro_config.encodeopt; - cmd.advancedencodeopt = audio->wmapro_config.advancedencodeopt; - cmd.advancedencodeopt2 = audio->wmapro_config.advancedencodeopt2; - - audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static void audpp_cmd_cfg_routing_mode(struct audio *audio) -{ - struct audpp_cmd_routing_mode cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; - cmd.object_number = audio->dec_id; - if (audio->pcm_feedback) - cmd.routing_mode = ROUTING_MODE_FTRT; - else - cmd.routing_mode = ROUTING_MODE_RT; - - audpp_send_queue1(&cmd, sizeof(cmd)); -} - -static void audplay_buffer_refresh(struct audio *audio) -{ - struct audplay_cmd_buffer_refresh refresh_cmd; - - refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; - refresh_cmd.num_buffers = 1; - refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; - refresh_cmd.buf0_length = audio->in[audio->fill_next].size; - refresh_cmd.buf_read_count = 0; - - MM_DBG("buf0_addr=%x buf0_len=%d\n", - refresh_cmd.buf0_address, - refresh_cmd.buf0_length); - - (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); -} - -static void audplay_config_hostpcm(struct audio *audio) -{ - struct audplay_cmd_hpcm_buf_cfg cfg_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; - cfg_cmd.max_buffers = audio->pcm_buf_count; - cfg_cmd.byte_swap = 0; - cfg_cmd.hostpcm_config = (0x8000) | (0x4000); - cfg_cmd.feedback_frequency = 1; - cfg_cmd.partition_number = 0; - - (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); -} - - -static int audplay_dsp_send_data_avail(struct audio *audio, - unsigned idx, unsigned len) -{ - struct audplay_cmd_bitstream_data_avail_nt2 cmd; - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2; - if (audio->mfield) - cmd.decoder_id = AUDWMAPRO_METAFIELD_MASK | - (audio->out[idx].mfield_sz >> 1); - else - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = audio->out[idx].addr; - cmd.buf_size = len/2; - cmd.partition_number = 0; - return audplay_send_queue0(audio, &cmd, sizeof(cmd)); -} - -static void audplay_send_data(struct audio *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (audio->wflush) { - audio->out_needed = 1; - goto done; - } - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - MM_DBG("\n"); /* Macro prints the file name and function */ - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - MM_DBG("frame %d busy\n", audio->out_tail); - audplay_dsp_send_data_avail(audio, audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } -done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ - -static void audio_flush(struct audio *audio) -{ - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->reserved = 0; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - atomic_set(&audio->out_bytes, 0); -} - -static void audio_flush_pcm_buf(struct audio *audio) -{ - uint8_t index; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < PCM_BUF_MAX_COUNT; index++) - audio->in[index].used = 0; - audio->buf_refresh = 0; - audio->read_next = 0; - audio->fill_next = 0; - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audio_ioport_reset(struct audio *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audio_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->read_wait); - mutex_lock(&audio->read_lock); - audio_flush_pcm_buf(audio); - mutex_unlock(&audio->read_lock); -} - -static int audwmapro_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audwmapro_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audwmapro_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audwmapro_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audwmapro_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - -static long audwmapro_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audwmapro_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout(audio->event_wait, - audwmapro_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audwmapro_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - rc = 0; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audwmapro_event, list); - list_del(&drv_evt->list); - } - - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audio_enable_eq(struct audio *audio, int enable) -{ - if (audio->eq_enable == enable && !audio->eq_needs_commit) - return 0; - - audio->eq_enable = enable; - - if (audio->running) { - audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq); - audio->eq_needs_commit = 0; - } - return 0; -} - -static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - unsigned long flags = 0; - uint16_t enable_mask; - int enable; - int prev_state; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - int len = 0; - - MM_DBG("cmd = %d\n", cmd); - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = audpp_avsync_byte_count(audio->dec_id); - stats.sample_count = audpp_avsync_sample_count(audio->dec_id); - if (copy_to_user((void *)arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - switch (cmd) { - case AUDIO_ENABLE_AUDPP: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - spin_lock_irqsave(&audio->dsp_lock, flags); - enable = (enable_mask & EQ_ENABLE) ? 1 : 0; - audio_enable_eq(audio, enable); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - case AUDIO_SET_VOLUME: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.volume = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_PAN: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.pan = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_EQ: - prev_state = audio->eq_enable; - audio->eq_enable = 0; - if (copy_from_user(&audio->eq.num_bands, (void *) arg, - sizeof(audio->eq) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) { - rc = -EFAULT; - break; - } - audio->eq_enable = prev_state; - audio->eq_needs_commit = 1; - rc = 0; - break; - } - - if (-EINVAL != rc) - return rc; - - if (cmd == AUDIO_GET_EVENT) { - MM_DBG("AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audwmapro_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audio_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) - rc = -ENODEV; - else - rc = 0; - } - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audio_disable(audio); - audio_ioport_reset(audio); - audio->stopped = 0; - break; - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audio_ioport_reset(audio); - if (audio->running) { - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - case AUDIO_SET_CONFIG: { - struct msm_audio_config config; - if (copy_from_user(&config, (void *) arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.channel_count == 1) { - config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V; - } else if (config.channel_count == 2) { - config.channel_count = AUDPP_CMD_PCM_INTF_STEREO_V; - } else { - rc = -EINVAL; - break; - } - audio->mfield = config.meta_field; - audio->out_sample_rate = config.sample_rate; - audio->out_channel_mode = config.channel_count; - rc = 0; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config config; - config.buffer_size = (audio->out_dma_sz >> 1); - config.buffer_count = 2; - config.sample_rate = audio->out_sample_rate; - if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) - config.channel_count = 1; - else - config.channel_count = 2; - config.meta_field = 0; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *) arg, &config, sizeof(config))) - rc = -EFAULT; - else - rc = 0; - - break; - } - case AUDIO_GET_WMAPRO_CONFIG:{ - if (copy_to_user((void *)arg, &audio->wmapro_config, - sizeof(audio->wmapro_config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_WMAPRO_CONFIG:{ - struct msm_audio_wmapro_config usr_config; - - if (copy_from_user - (&usr_config, (void *)arg, - sizeof(usr_config))) { - rc = -EFAULT; - break; - } - - audio->wmapro_config = usr_config; - - /* Need to swap the first and last words of advancedencodeopt2 - * as DSP cannot read 32-bit variable at a time. Need to be - * split into two 16-bit and swap them as required by DSP */ - - audio->wmapro_config.advancedencodeopt2 = - ((audio->wmapro_config.advancedencodeopt2 & 0xFFFF0000) - >> 16) | ((audio->wmapro_config.advancedencodeopt2 - << 16) & 0xFFFF0000); - rc = 0; - break; - } - case AUDIO_GET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - config.pcm_feedback = audio->pcm_feedback; - config.buffer_count = PCM_BUF_MAX_COUNT; - config.buffer_size = PCM_BUFSZ_MIN; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.pcm_feedback != audio->pcm_feedback) { - MM_ERR("Not sufficient permission to" - "change the playback mode\n"); - rc = -EACCES; - break; - } - if ((config.buffer_count > PCM_BUF_MAX_COUNT) || - (config.buffer_count == 1)) - config.buffer_count = PCM_BUF_MAX_COUNT; - - if (config.buffer_size < PCM_BUFSZ_MIN) - config.buffer_size = PCM_BUFSZ_MIN; - - /* Check if pcm feedback is required */ - if ((config.pcm_feedback) && (!audio->read_data)) { - MM_DBG("allocate PCM buffer %d\n", - config.buffer_count * - config.buffer_size); - handle = ion_alloc(audio->client, - (config.buffer_size * - config.buffer_count), - SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to alloc I/P buffs\n"); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - break; - } - - audio->input_buff_handle = handle; - - rc = ion_phys(audio->client , - handle, &addr, &len); - if (rc) { - MM_ERR("Invalid phy: %x sz: %x\n", - (unsigned int) addr, - (unsigned int) len); - ion_free(audio->client, handle); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - break; - } else { - MM_INFO("Got valid phy: %x sz: %x\n", - (unsigned int) audio->read_phys, - (unsigned int) len); - } - audio->read_phys = (int32_t)addr; - - rc = ion_handle_get_flags(audio->client, - handle, &ionflag); - if (rc) { - MM_ERR("could not get flags\n"); - ion_free(audio->client, handle); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - break; - } - - audio->map_v_read = ion_map_kernel( - audio->client, handle); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("map of read buf failed\n"); - ion_free(audio->client, handle); - audio->input_buff_handle = NULL; - rc = -ENOMEM; - } else { - uint8_t index; - uint32_t offset = 0; - audio->read_data = audio->map_v_read; - audio->pcm_feedback = 1; - audio->buf_refresh = 0; - audio->pcm_buf_count = - config.buffer_count; - audio->read_next = 0; - audio->fill_next = 0; - - for (index = 0; - index < config.buffer_count; - index++) { - audio->in[index].data = - audio->read_data + offset; - audio->in[index].addr = - audio->read_phys + offset; - audio->in[index].size = - config.buffer_size; - audio->in[index].used = 0; - offset += config.buffer_size; - } - MM_DBG("read buf: phy addr \ - 0x%08x kernel addr 0x%08x\n", - audio->read_phys, - (int)audio->read_data); - rc = 0; - } - } else { - rc = 0; - } - break; - } - case AUDIO_PAUSE: - MM_DBG("AUDIO_PAUSE %ld\n", arg); - rc = audpp_pause(audio->dec_id, (int) arg); - break; - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -static int audio_fsync(struct file *file, loff_t a, loff_t b, - int datasync) -{ - struct audio *audio = file->private_data; - struct buffer *frame; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (!audio->running || audio->pcm_feedback) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (audio->reserved) { - MM_DBG("send reserved byte\n"); - frame = audio->out + audio->out_tail; - ((char *) frame->data)[0] = audio->rsv_byte; - ((char *) frame->data)[1] = 0; - frame->used = 2; - audplay_send_data(audio, 0); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - } - - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush); - - if (audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; -} - -static ssize_t audio_read(struct file *file, char __user *buf, size_t count, - loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - int rc = 0; - - if (!audio->pcm_feedback) - return 0; /* PCM feedback is not enabled. Nothing to read */ - - mutex_lock(&audio->read_lock); - MM_DBG("%d \n", count); - while (count > 0) { - rc = wait_event_interruptible(audio->read_wait, - (audio->in[audio->read_next].used > 0) || - (audio->stopped) || (audio->rflush)); - - if (rc < 0) - break; - - if (audio->stopped || audio->rflush) { - rc = -EBUSY; - break; - } - - if (count < audio->in[audio->read_next].used) { - /* Read must happen in frame boundary. Since driver - does not know frame size, read count must be greater - or equal to size of PCM samples */ - MM_DBG("audio_read: no partial frame done reading\n"); - break; - } else { - MM_DBG("audio_read: read from in[%d]\n", - audio->read_next); - if (copy_to_user - (buf, audio->in[audio->read_next].data, - audio->in[audio->read_next].used)) { - MM_ERR("invalid addr %x \n", (unsigned int)buf); - rc = -EFAULT; - break; - } - count -= audio->in[audio->read_next].used; - buf += audio->in[audio->read_next].used; - audio->in[audio->read_next].used = 0; - if ((++audio->read_next) == audio->pcm_buf_count) - audio->read_next = 0; - break; /* Force to exit while loop - * to prevent output thread - * sleep too long if data is - * not ready at this moment. - */ - } - } - - /* don't feed output buffer to HW decoder during flushing - * buffer refresh command will be sent once flush completes - * send buf refresh command here can confuse HW decoder - */ - if (audio->buf_refresh && !audio->rflush) { - audio->buf_refresh = 0; - MM_DBG("kick start pcm feedback again\n"); - audplay_buffer_refresh(audio); - } - - mutex_unlock(&audio->read_lock); - - if (buf > start) - rc = buf - start; - - MM_DBG("read %d bytes\n", rc); - return rc; -} - -static int audwmapro_process_eos(struct audio *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - int rc = 0; - struct buffer *frame; - char *buf_ptr; - - if (audio->reserved) { - MM_DBG("flush reserve byte\n"); - frame = audio->out + audio->out_head; - buf_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - buf_ptr[0] = audio->rsv_byte; - buf_ptr[1] = 0; - audio->out_head ^= 1; - frame->mfield_sz = 0; - frame->used = 2; - audio->reserved = 0; - audplay_send_data(audio, 0); - } - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - audplay_send_data(audio, 0); -done: - return rc; -} - -static ssize_t audio_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - char *cpy_ptr; - int rc = 0, eos_condition = AUDWMAPRO_EOS_NONE; - unsigned dsize; - unsigned short mfield_size = 0; - - MM_DBG("cnt=%d\n", count); - - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - cpy_ptr = frame->data; - dsize = 0; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - break; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - break; - } - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - break; - } else if (mfield_size > count) { - rc = -EINVAL; - break; - } - MM_DBG("audio_write: mf offset_val %x\n", - mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - break; - } - /* Check if EOS flag is set and buffer has - * contains just meta field - */ - if (cpy_ptr[AUDWMAPRO_EOS_FLG_OFFSET] & - AUDWMAPRO_EOS_FLG_MASK) { - MM_DBG("audio_write: EOS SET\n"); - eos_condition = AUDWMAPRO_EOS_SET; - if (mfield_size == count) { - buf += mfield_size; - break; - } else - cpy_ptr[AUDWMAPRO_EOS_FLG_OFFSET] - &= ~AUDWMAPRO_EOS_FLG_MASK; - } - cpy_ptr += mfield_size; - count -= mfield_size; - dsize += mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("audio_write: continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - - if (audio->reserved) { - MM_DBG("append reserved byte %x\n", audio->rsv_byte); - *cpy_ptr = audio->rsv_byte; - xfer = (count > ((frame->size - mfield_size) - 1)) ? - (frame->size - mfield_size) - 1 : count; - cpy_ptr++; - dsize += 1; - audio->reserved = 0; - } else - xfer = (count > (frame->size - mfield_size)) ? - (frame->size - mfield_size) : count; - - if (copy_from_user(cpy_ptr, buf, xfer)) { - rc = -EFAULT; - break; - } - - dsize += xfer; - if (dsize & 1) { - audio->rsv_byte = ((char *) frame->data)[dsize - 1]; - MM_DBG("odd length buf reserve last byte %x\n", - audio->rsv_byte); - audio->reserved = 1; - dsize--; - } - count -= xfer; - buf += xfer; - - if (dsize > 0) { - audio->out_head ^= 1; - frame->used = dsize; - audplay_send_data(audio, 0); - } - } - if (eos_condition == AUDWMAPRO_EOS_SET) - rc = audwmapro_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - if (!rc) { - if (buf > start) - return buf - start; - } - return rc; -} - -static int audio_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_INFO("audio instance 0x%08x freeing\n", (int)audio); - mutex_lock(&audio->lock); - audio_disable(audio); - if (audio->rmt_resource_released == 0) - rmt_put_resource(audio); - audio_flush(audio); - audio_flush_pcm_buf(audio); - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->event_abort = 1; - wake_up(&audio->event_wait); - audwmapro_reset_event_queue(audio); - ion_unmap_kernel(audio->client, audio->output_buff_handle); - ion_free(audio->client, audio->output_buff_handle); - if (audio->input_buff_handle != NULL) { - ion_unmap_kernel(audio->client, audio->input_buff_handle); - ion_free(audio->client, audio->input_buff_handle); - } - ion_client_destroy(audio->client); - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - kfree(audio); - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audwmapro_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audwmapro_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audwmapro_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audwmapro_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -static void audwmapro_suspend(struct early_suspend *h) -{ - struct audwmapro_suspend_ctl *ctl = - container_of(h, struct audwmapro_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audwmapro_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audwmapro_resume(struct early_suspend *h) -{ - struct audwmapro_suspend_ctl *ctl = - container_of(h, struct audwmapro_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audwmapro_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audwmapro_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audwmapro_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 4096; - static char buffer[4096]; - int n = 0, i; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_feedback %d\n", audio->pcm_feedback); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_buf_sz %d\n", audio->out[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_count %d \n", audio->pcm_buf_count); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_sz %d \n", audio->in[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %x \n", audio->vol_pan.volume); - n += scnprintf(buffer + n, debug_bufmax - n, - "sample rate %d \n", audio->out_sample_rate); - n += scnprintf(buffer + n, debug_bufmax - n, - "channel mode %d \n", audio->out_channel_mode); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "rflush %d\n", audio->rflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d \n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d \n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d \n", audio->out_needed); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_head %d \n", audio->out_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_tail %d \n", audio->out_tail); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[0].used %d \n", audio->out[0].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[1].used %d \n", audio->out[1].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "buffer_refresh %d \n", audio->buf_refresh); - n += scnprintf(buffer + n, debug_bufmax - n, - "read_next %d \n", audio->read_next); - n += scnprintf(buffer + n, debug_bufmax - n, - "fill_next %d \n", audio->fill_next); - for (i = 0; i < audio->pcm_buf_count; i++) - n += scnprintf(buffer + n, debug_bufmax - n, - "in[%d].size %d \n", i, audio->in[i].used); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audwmapro_debug_fops = { - .read = audwmapro_debug_read, - .open = audwmapro_debug_open, -}; -#endif - -static int audio_open(struct inode *inode, struct file *file) -{ - struct audio *audio = NULL; - int rc, dec_attrb, decid, i; - unsigned mem_sz = DMASZ_MAX; - struct audwmapro_event *e_node = NULL; - unsigned long ionflag = 0; - ion_phys_addr_t addr = 0; - struct ion_handle *handle = NULL; - struct ion_client *client = NULL; - int len = 0; -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_wmapro_" + 5]; -#endif - - /* Allocate Mem for audio instance */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("no memory to allocate audio instance \n"); - rc = -ENOMEM; - goto done; - } - MM_INFO("audio instance 0x%08x created\n", (int)audio); - - /* Allocate the decoder */ - dec_attrb = AUDDEC_DEC_WMAPRO; - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_NONTUNNEL; - audio->pcm_feedback = NON_TUNNEL_MODE_PLAYBACK; - } else if ((file->f_mode & FMODE_WRITE) && - !(file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_TUNNEL; - audio->pcm_feedback = TUNNEL_MODE_PLAYBACK; - } else { - kfree(audio); - rc = -EACCES; - goto done; - } - - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - - if (decid < 0) { - MM_ERR("No free decoder available, freeing instance 0x%08x\n", - (int)audio); - rc = -ENODEV; - kfree(audio); - goto done; - } - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - client = msm_ion_client_create(UINT_MAX, "Audio_WMA_PRO_Client"); - if (IS_ERR_OR_NULL(client)) { - pr_err("Unable to create ION client\n"); - rc = -ENOMEM; - goto client_create_error; - } - audio->client = client; - - handle = ion_alloc(client, mem_sz, SZ_4K, - ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL(handle)) { - MM_ERR("Unable to create allocate O/P buffers\n"); - rc = -ENOMEM; - goto output_buff_alloc_error; - } - audio->output_buff_handle = handle; - - rc = ion_phys(client, handle, &addr, &len); - if (rc) { - MM_ERR("O/P buffers:Invalid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - goto output_buff_get_phys_error; - } else { - MM_INFO("O/P buffers:valid phy: %x sz: %x\n", - (unsigned int) addr, (unsigned int) len); - } - audio->phys = (int32_t)addr; - - - rc = ion_handle_get_flags(client, handle, &ionflag); - if (rc) { - MM_ERR("could not get flags for the handle\n"); - goto output_buff_get_flags_error; - } - - audio->map_v_write = ion_map_kernel(client, handle); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write buffers\n"); - rc = -ENOMEM; - goto output_buff_map_error; - } - audio->data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->phys, (int)audio->data); - - audio->out_dma_sz = mem_sz; - - rc = audmgr_open(&audio->audmgr); - if (rc) { - MM_ERR("audmgr open failed, freeing instance 0x%08x\n", - (int)audio); - goto err; - } - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audplay_adsp_ops_wmapro, audio); - if (rc) { - MM_ERR("failed to get %s module, freeing instance 0x%08x\n", - audio->module_name, (int)audio); - audmgr_close(&audio->audmgr); - goto err; - } - - rc = rmt_get_resource(audio); - if (rc) { - MM_ERR("ADSP resources are not available for WMAPRO session \ - 0x%08x on decoder: %d\n", (int)audio, audio->dec_id); - if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) - audmgr_close(&audio->audmgr); - msm_adsp_put(audio->audplay); - goto err; - } - - audio->input_buff_handle = NULL; - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->read_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - init_waitqueue_head(&audio->write_wait); - init_waitqueue_head(&audio->read_wait); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - spin_lock_init(&audio->event_queue_lock); - - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = audio->out_dma_sz >> 1; - - audio->out[1].data = audio->data + audio->out[0].size; - audio->out[1].addr = audio->phys + audio->out[0].size; - audio->out[1].size = audio->out[0].size; - - audio->out_sample_rate = 44100; - audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V; - - audio->vol_pan.volume = 0x2000; - - audio_flush(audio); - - file->private_data = audio; - audio->opened = 1; -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_wmapro_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, - &audwmapro_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audwmapro_resume; - audio->suspend_ctl.node.suspend = audwmapro_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (i = 0; i < AUDWMAPRO_EVENT_NUM; i++) { - e_node = kmalloc(sizeof(struct audwmapro_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } -done: - return rc; -err: - ion_unmap_kernel(client, audio->output_buff_handle); -output_buff_map_error: -output_buff_get_phys_error: -output_buff_get_flags_error: - ion_free(client, audio->output_buff_handle); -output_buff_alloc_error: - ion_client_destroy(client); -client_create_error: - audpp_adec_free(audio->dec_id); - kfree(audio); - return rc; -} - -static const struct file_operations audio_wmapro_fops = { - .owner = THIS_MODULE, - .open = audio_open, - .release = audio_release, - .read = audio_read, - .write = audio_write, - .unlocked_ioctl = audio_ioctl, - .fsync = audio_fsync, -}; - -struct miscdevice audio_wmapro_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_wmapro", - .fops = &audio_wmapro_fops, -}; - -static int __init audio_init(void) -{ - return misc_register(&audio_wmapro_misc); -} - -device_initcall(audio_init); diff --git a/arch/arm/mach-msm/qdsp5/audmgr.c b/arch/arm/mach-msm/qdsp5/audmgr.c deleted file mode 100644 index f7fb8833971276357523914031a6e4eb27a603c2..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audmgr.c +++ /dev/null @@ -1,365 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/audmgr.c - * - * interface to "audmgr" service on the baseband cpu - * - * Copyright (C) 2008 Google, Inc. - * Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "audmgr.h" -#include - -#define STATE_CLOSED 0 -#define STATE_DISABLED 1 -#define STATE_ENABLING 2 -#define STATE_ENABLED 3 -#define STATE_DISABLING 4 -#define STATE_ERROR 5 - -/* store information used across complete audmgr sessions */ -struct audmgr_global { - struct mutex *lock; - struct msm_rpc_endpoint *ept; - struct task_struct *task; - uint32_t rpc_version; -}; -static DEFINE_MUTEX(audmgr_lock); - -static struct audmgr_global the_audmgr_state = { - .lock = &audmgr_lock, -}; - -static void rpc_ack(struct msm_rpc_endpoint *ept, uint32_t xid) -{ - uint32_t rep[6]; - - rep[0] = cpu_to_be32(xid); - rep[1] = cpu_to_be32(1); - rep[2] = cpu_to_be32(RPCMSG_REPLYSTAT_ACCEPTED); - rep[3] = cpu_to_be32(RPC_ACCEPTSTAT_SUCCESS); - rep[4] = 0; - rep[5] = 0; - - msm_rpc_write(ept, rep, sizeof(rep)); -} - -static void process_audmgr_callback(struct audmgr_global *amg, - struct rpc_audmgr_cb_func_ptr *args, - int len) -{ - struct audmgr *am; - - /* Allow only if complete arguments recevied */ - if (len < (sizeof(struct rpc_audmgr_cb_func_ptr))) - return; - - /* Allow only if valid argument */ - if (be32_to_cpu(args->set_to_one) != 1) - return; - - am = (struct audmgr *) be32_to_cpu(args->client_data); - - if (!am) - return; - - switch (be32_to_cpu(args->status)) { - case RPC_AUDMGR_STATUS_READY: - am->handle = be32_to_cpu(args->u.handle); - MM_INFO("rpc READY handle=0x%08x\n", am->handle); - break; - case RPC_AUDMGR_STATUS_CODEC_CONFIG: { - uint32_t volume; - volume = be32_to_cpu(args->u.volume); - MM_INFO("rpc CODEC_CONFIG volume=0x%08x\n", volume); - am->state = STATE_ENABLED; - wake_up(&am->wait); - break; - } - case RPC_AUDMGR_STATUS_PENDING: - MM_ERR("PENDING?\n"); - break; - case RPC_AUDMGR_STATUS_SUSPEND: - MM_ERR("SUSPEND?\n"); - break; - case RPC_AUDMGR_STATUS_FAILURE: - MM_ERR("FAILURE\n"); - break; - case RPC_AUDMGR_STATUS_VOLUME_CHANGE: - MM_ERR("VOLUME_CHANGE?\n"); - break; - case RPC_AUDMGR_STATUS_DISABLED: - MM_ERR("DISABLED\n"); - am->state = STATE_DISABLED; - wake_up(&am->wait); - break; - case RPC_AUDMGR_STATUS_ERROR: - MM_ERR("ERROR?\n"); - am->state = STATE_ERROR; - wake_up(&am->wait); - break; - default: - break; - } -} - -static void process_rpc_request(uint32_t proc, uint32_t xid, - void *data, int len, void *private) -{ - struct audmgr_global *amg = private; - - if (proc == AUDMGR_CB_FUNC_PTR) - process_audmgr_callback(amg, data, len); - else - MM_ERR("unknown rpc proc %d\n", proc); - rpc_ack(amg->ept, xid); -} - -#define RPC_TYPE_REQUEST 0 -#define RPC_TYPE_REPLY 1 - -#define RPC_VERSION 2 - -#define RPC_COMMON_HDR_SZ (sizeof(uint32_t) * 2) -#define RPC_REQUEST_HDR_SZ (sizeof(struct rpc_request_hdr)) -#define RPC_REPLY_HDR_SZ (sizeof(uint32_t) * 3) -#define RPC_REPLY_SZ (sizeof(uint32_t) * 6) - -static int audmgr_rpc_thread(void *data) -{ - struct audmgr_global *amg = data; - struct rpc_request_hdr *hdr = NULL; - uint32_t type; - int len; - - MM_INFO("start\n"); - - while (!kthread_should_stop()) { - if (hdr) { - kfree(hdr); - hdr = NULL; - } - len = msm_rpc_read(amg->ept, (void **) &hdr, -1, -1); - if (len < 0) { - MM_ERR("rpc read failed (%d)\n", len); - break; - } - if (len < RPC_COMMON_HDR_SZ) - continue; - - type = be32_to_cpu(hdr->type); - if (type == RPC_TYPE_REPLY) { - struct rpc_reply_hdr *rep = (void *) hdr; - uint32_t status; - if (len < RPC_REPLY_HDR_SZ) - continue; - status = be32_to_cpu(rep->reply_stat); - if (status == RPCMSG_REPLYSTAT_ACCEPTED) { - status = be32_to_cpu(rep->data.acc_hdr.accept_stat); - MM_INFO("rpc_reply status %d\n", status); - } else { - MM_INFO("rpc_reply denied!\n"); - } - /* process reply */ - continue; - } - - if (len < RPC_REQUEST_HDR_SZ) - continue; - - process_rpc_request(be32_to_cpu(hdr->procedure), - be32_to_cpu(hdr->xid), - (void *) (hdr + 1), - len - sizeof(*hdr), - data); - } - MM_INFO("exit\n"); - if (hdr) { - kfree(hdr); - hdr = NULL; - } - amg->task = NULL; - return 0; -} - -struct audmgr_enable_msg { - struct rpc_request_hdr hdr; - struct rpc_audmgr_enable_client_args args; -}; - -struct audmgr_disable_msg { - struct rpc_request_hdr hdr; - uint32_t handle; -}; - -int audmgr_open(struct audmgr *am) -{ - struct audmgr_global *amg = &the_audmgr_state; - int rc; - - if (am->state != STATE_CLOSED) - return 0; - - mutex_lock(amg->lock); - - /* connect to audmgr end point and polling thread only once */ - if (amg->ept == NULL) { - amg->ept = msm_rpc_connect_compatible(AUDMGR_PROG, - AUDMGR_VERS_COMP_VER3, - MSM_RPC_UNINTERRUPTIBLE); - if (IS_ERR(amg->ept)) { - MM_ERR("connect failed with current VERS \ - = %x, trying again with another API\n", - AUDMGR_VERS_COMP_VER3); - amg->ept = msm_rpc_connect_compatible(AUDMGR_PROG, - AUDMGR_VERS_COMP_VER2, - MSM_RPC_UNINTERRUPTIBLE); - if (IS_ERR(amg->ept)) { - MM_ERR("connect failed with current VERS \ - = %x, trying again with another API\n", - AUDMGR_VERS_COMP_VER2); - amg->ept = msm_rpc_connect_compatible( - AUDMGR_PROG, - AUDMGR_VERS_COMP, - MSM_RPC_UNINTERRUPTIBLE); - if (IS_ERR(amg->ept)) { - MM_ERR("connect failed with current \ - VERS=%x, trying again with another \ - API\n", AUDMGR_VERS_COMP); - amg->ept = msm_rpc_connect(AUDMGR_PROG, - AUDMGR_VERS, - MSM_RPC_UNINTERRUPTIBLE); - amg->rpc_version = AUDMGR_VERS; - } else - amg->rpc_version = AUDMGR_VERS_COMP; - } else - amg->rpc_version = AUDMGR_VERS_COMP_VER2; - } else - amg->rpc_version = AUDMGR_VERS_COMP_VER3; - - if (IS_ERR(amg->ept)) { - rc = PTR_ERR(amg->ept); - amg->ept = NULL; - MM_ERR("failed to connect to audmgr svc\n"); - goto done; - } - - amg->task = kthread_run(audmgr_rpc_thread, amg, "audmgr_rpc"); - if (IS_ERR(amg->task)) { - rc = PTR_ERR(amg->task); - amg->task = NULL; - msm_rpc_close(amg->ept); - amg->ept = NULL; - goto done; - } - } - - /* Initialize session parameters */ - init_waitqueue_head(&am->wait); - am->state = STATE_DISABLED; - rc = 0; -done: - mutex_unlock(amg->lock); - return rc; -} -EXPORT_SYMBOL(audmgr_open); - -int audmgr_close(struct audmgr *am) -{ - return -EBUSY; -} -EXPORT_SYMBOL(audmgr_close); - -int audmgr_enable(struct audmgr *am, struct audmgr_config *cfg) -{ - struct audmgr_global *amg = &the_audmgr_state; - struct audmgr_enable_msg msg; - int rc; - - if (am->state == STATE_ENABLED) - return 0; - - if (am->state == STATE_DISABLING) - MM_ERR("state is DISABLING in enable?\n"); - am->state = STATE_ENABLING; - - MM_INFO("session 0x%08x\n", (int) am); - msg.args.set_to_one = cpu_to_be32(1); - msg.args.tx_sample_rate = cpu_to_be32(cfg->tx_rate); - msg.args.rx_sample_rate = cpu_to_be32(cfg->rx_rate); - msg.args.def_method = cpu_to_be32(cfg->def_method); - msg.args.codec_type = cpu_to_be32(cfg->codec); - msg.args.snd_method = cpu_to_be32(cfg->snd_method); - msg.args.cb_func = cpu_to_be32(0x11111111); - msg.args.client_data = cpu_to_be32((int)am); - - msm_rpc_setup_req(&msg.hdr, AUDMGR_PROG, amg->rpc_version, - AUDMGR_ENABLE_CLIENT); - - rc = msm_rpc_write(amg->ept, &msg, sizeof(msg)); - if (rc < 0) - return rc; - - rc = wait_event_timeout(am->wait, am->state != STATE_ENABLING, 15 * HZ); - if (rc == 0) { - MM_ERR("ARM9 did not reply to RPC am->state = %d\n", am->state); - } - if (am->state == STATE_ENABLED) - return 0; - - MM_ERR("unexpected state %d while enabling?!\n", am->state); - return -ENODEV; -} -EXPORT_SYMBOL(audmgr_enable); - -int audmgr_disable(struct audmgr *am) -{ - struct audmgr_global *amg = &the_audmgr_state; - struct audmgr_disable_msg msg; - int rc; - - if (am->state == STATE_DISABLED) - return 0; - - MM_INFO("session 0x%08x\n", (int) am); - msg.handle = cpu_to_be32(am->handle); - msm_rpc_setup_req(&msg.hdr, AUDMGR_PROG, amg->rpc_version, - AUDMGR_DISABLE_CLIENT); - - am->state = STATE_DISABLING; - - rc = msm_rpc_write(amg->ept, &msg, sizeof(msg)); - if (rc < 0) - return rc; - - rc = wait_event_timeout(am->wait, am->state != STATE_DISABLING, 15 * HZ); - if (rc == 0) { - MM_ERR("ARM9 did not reply to RPC am->state = %d\n", am->state); - } - - if (am->state == STATE_DISABLED) - return 0; - - MM_ERR("unexpected state %d while disabling?!\n", am->state); - return -ENODEV; -} -EXPORT_SYMBOL(audmgr_disable); diff --git a/arch/arm/mach-msm/qdsp5/audmgr.h b/arch/arm/mach-msm/qdsp5/audmgr.h deleted file mode 100644 index 472394b01bee43d94030e29f3717cf07c023f466..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audmgr.h +++ /dev/null @@ -1,281 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/audmgr.h - * - * Copyright (C) 2008 Google, Inc. - * Copyright (c) 2008-2009, 2012 The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _AUDIO_RPC_H_ -#define _AUDIO_RPC_H_ - -#include - -enum rpc_aud_def_sample_rate_type { - RPC_AUD_DEF_SAMPLE_RATE_NONE, - RPC_AUD_DEF_SAMPLE_RATE_8000, - RPC_AUD_DEF_SAMPLE_RATE_11025, - RPC_AUD_DEF_SAMPLE_RATE_12000, - RPC_AUD_DEF_SAMPLE_RATE_16000, - RPC_AUD_DEF_SAMPLE_RATE_22050, - RPC_AUD_DEF_SAMPLE_RATE_24000, - RPC_AUD_DEF_SAMPLE_RATE_32000, - RPC_AUD_DEF_SAMPLE_RATE_44100, - RPC_AUD_DEF_SAMPLE_RATE_48000, - RPC_AUD_DEF_SAMPLE_RATE_MAX, -}; - -enum rpc_aud_def_method_type { - RPC_AUD_DEF_METHOD_NONE, - RPC_AUD_DEF_METHOD_KEY_BEEP, - RPC_AUD_DEF_METHOD_PLAYBACK, - RPC_AUD_DEF_METHOD_VOICE, - RPC_AUD_DEF_METHOD_RECORD, - RPC_AUD_DEF_METHOD_HOST_PCM, - RPC_AUD_DEF_METHOD_MIDI_OUT, - RPC_AUD_DEF_METHOD_RECORD_SBC, - RPC_AUD_DEF_METHOD_DTMF_RINGER, - RPC_AUD_DEF_METHOD_MAX, -}; - -enum rpc_aud_def_codec_type { - RPC_AUD_DEF_CODEC_NONE, - RPC_AUD_DEF_CODEC_DTMF, - RPC_AUD_DEF_CODEC_MIDI, - RPC_AUD_DEF_CODEC_MP3, - RPC_AUD_DEF_CODEC_PCM, - RPC_AUD_DEF_CODEC_AAC, - RPC_AUD_DEF_CODEC_WMA, - RPC_AUD_DEF_CODEC_RA, - RPC_AUD_DEF_CODEC_ADPCM, - RPC_AUD_DEF_CODEC_GAUDIO, - RPC_AUD_DEF_CODEC_VOC_EVRC, - RPC_AUD_DEF_CODEC_VOC_13K, - RPC_AUD_DEF_CODEC_VOC_4GV_NB, - RPC_AUD_DEF_CODEC_VOC_AMR, - RPC_AUD_DEF_CODEC_VOC_EFR, - RPC_AUD_DEF_CODEC_VOC_FR, - RPC_AUD_DEF_CODEC_VOC_HR, - RPC_AUD_DEF_CODEC_VOC_CDMA, - RPC_AUD_DEF_CODEC_VOC_CDMA_WB, - RPC_AUD_DEF_CODEC_VOC_UMTS, - RPC_AUD_DEF_CODEC_VOC_UMTS_WB, - RPC_AUD_DEF_CODEC_SBC, - RPC_AUD_DEF_CODEC_VOC_PCM, - RPC_AUD_DEF_CODEC_AMR_WB, - RPC_AUD_DEF_CODEC_AMR_WB_PLUS, - RPC_AUD_DEF_CODEC_AAC_BSAC, - RPC_AUD_DEF_CODEC_MAX, - RPC_AUD_DEF_CODEC_AMR_NB, - RPC_AUD_DEF_CODEC_13K, - RPC_AUD_DEF_CODEC_EVRC, - RPC_AUD_DEF_CODEC_AC3, - RPC_AUD_DEF_CODEC_MAX_002, -}; - -enum rpc_snd_method_type { - RPC_SND_METHOD_VOICE = 0, - RPC_SND_METHOD_KEY_BEEP, - RPC_SND_METHOD_MESSAGE, - RPC_SND_METHOD_RING, - RPC_SND_METHOD_MIDI, - RPC_SND_METHOD_AUX, - RPC_SND_METHOD_MAX, -}; - -enum rpc_voc_codec_type { - RPC_VOC_CODEC_DEFAULT, - RPC_VOC_CODEC_ON_CHIP_0 = RPC_VOC_CODEC_DEFAULT, - RPC_VOC_CODEC_ON_CHIP_1, - RPC_VOC_CODEC_STEREO_HEADSET, - RPC_VOC_CODEC_ON_CHIP_AUX, - RPC_VOC_CODEC_BT_OFF_BOARD, - RPC_VOC_CODEC_BT_A2DP, - RPC_VOC_CODEC_OFF_BOARD, - RPC_VOC_CODEC_SDAC, - RPC_VOC_CODEC_RX_EXT_SDAC_TX_INTERNAL, - RPC_VOC_CODEC_IN_STEREO_SADC_OUT_MONO_HANDSET, - RPC_VOC_CODEC_IN_STEREO_SADC_OUT_STEREO_HEADSET, - RPC_VOC_CODEC_TX_INT_SADC_RX_EXT_AUXPCM, - RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_MONO_HANDSET, - RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_STEREO_HEADSET, - RPC_VOC_CODEC_TTY_ON_CHIP_1, - RPC_VOC_CODEC_TTY_OFF_BOARD, - RPC_VOC_CODEC_TTY_VCO, - RPC_VOC_CODEC_TTY_HCO, - RPC_VOC_CODEC_ON_CHIP_0_DUAL_MIC, - RPC_VOC_CODEC_MAX, - RPC_VOC_CODEC_NONE, -}; - -enum rpc_audmgr_status_type { - RPC_AUDMGR_STATUS_READY, - RPC_AUDMGR_STATUS_CODEC_CONFIG, - RPC_AUDMGR_STATUS_PENDING, - RPC_AUDMGR_STATUS_SUSPEND, - RPC_AUDMGR_STATUS_FAILURE, - RPC_AUDMGR_STATUS_VOLUME_CHANGE, - RPC_AUDMGR_STATUS_DISABLED, - RPC_AUDMGR_STATUS_ERROR, -}; - -struct rpc_audmgr_enable_client_args { - uint32_t set_to_one; - uint32_t tx_sample_rate; - uint32_t rx_sample_rate; - uint32_t def_method; - uint32_t codec_type; - uint32_t snd_method; - - uint32_t cb_func; - uint32_t client_data; -}; - -#define AUDMGR_ENABLE_CLIENT 2 -#define AUDMGR_DISABLE_CLIENT 3 -#define AUDMGR_SUSPEND_EVENT_RSP 4 -#define AUDMGR_REGISTER_OPERATION_LISTENER 5 -#define AUDMGR_UNREGISTER_OPERATION_LISTENER 6 -#define AUDMGR_REGISTER_CODEC_LISTENER 7 -#define AUDMGR_GET_RX_SAMPLE_RATE 8 -#define AUDMGR_GET_TX_SAMPLE_RATE 9 -#define AUDMGR_SET_DEVICE_MODE 10 - -#define AUDMGR_PROG_VERS "rs30000013:0x7feccbff" -#define AUDMGR_PROG 0x30000013 -#define AUDMGR_VERS 0x7feccbff -#define AUDMGR_VERS_COMP 0x00010001 -#define AUDMGR_VERS_COMP_VER2 0x00020001 -#define AUDMGR_VERS_COMP_VER3 0x00030001 - -struct rpc_audmgr_cb_func_ptr { - uint32_t cb_id; /* cb_func */ - uint32_t status; /* Audmgr status */ - uint32_t set_to_one; /* Pointer status (1 = valid, 0 = invalid) */ - uint32_t disc; - /* disc = AUDMGR_STATUS_READY => data=handle - disc = AUDMGR_STATUS_CODEC_CONFIG => data = volume - disc = AUDMGR_STATUS_DISABLED => data =status_disabled - disc = AUDMGR_STATUS_VOLUME_CHANGE => data = volume_change */ - union { - uint32_t handle; - uint32_t volume; - uint32_t status_disabled; - uint32_t volume_change; - } u; - uint32_t client_data; -}; - -#define AUDMGR_CB_FUNC_PTR 1 -#define AUDMGR_OPR_LSTNR_CB_FUNC_PTR 2 -#define AUDMGR_CODEC_LSTR_FUNC_PTR 3 - -#define AUDMGR_CB_PROG_VERS "rs31000013:0xf8e3e2d9" -#define AUDMGR_CB_PROG 0x31000013 -#define AUDMGR_CB_VERS 0xf8e3e2d9 - -struct audmgr { - wait_queue_head_t wait; - uint32_t handle; - int state; -}; - -struct audmgr_config { - uint32_t tx_rate; - uint32_t rx_rate; - uint32_t def_method; - uint32_t codec; - uint32_t snd_method; -}; - -int audmgr_open(struct audmgr *am); -int audmgr_close(struct audmgr *am); -int audmgr_enable(struct audmgr *am, struct audmgr_config *cfg); -int audmgr_disable(struct audmgr *am); - -typedef void (*audpp_event_func)(void *private, unsigned id, uint16_t *msg); -typedef void (*audrec_event_func)(void *private, unsigned id, uint16_t *msg); - -/* worst case delay of 1sec for response */ -#define MSM_AUD_DECODER_WAIT_MS 1000 -#define MSM_AUD_MODE_TUNNEL 0x00000100 -#define MSM_AUD_MODE_NONTUNNEL 0x00000200 -#define MSM_AUD_DECODER_MASK 0x0000FFFF -#define MSM_AUD_OP_MASK 0xFFFF0000 - -/*Playback mode*/ -#define NON_TUNNEL_MODE_PLAYBACK 1 -#define TUNNEL_MODE_PLAYBACK 0 - -enum msm_aud_decoder_state { - MSM_AUD_DECODER_STATE_NONE = 0, - MSM_AUD_DECODER_STATE_FAILURE = 1, - MSM_AUD_DECODER_STATE_SUCCESS = 2, - MSM_AUD_DECODER_STATE_CLOSE = 3, -}; - -int audpp_adec_alloc(unsigned dec_attrb, const char **module_name, - unsigned *queueid); -void audpp_adec_free(int decid); - -struct audpp_event_callback { - audpp_event_func fn; - void *private; -}; - -int audpp_register_event_callback(struct audpp_event_callback *eh); -int audpp_unregister_event_callback(struct audpp_event_callback *eh); -int is_audpp_enable(void); - -int audpp_enable(int id, audpp_event_func func, void *private); -void audpp_disable(int id, void *private); - -int audpp_send_queue1(void *cmd, unsigned len); -int audpp_send_queue2(void *cmd, unsigned len); -int audpp_send_queue3(void *cmd, unsigned len); - -int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan); -int audpp_pause(unsigned id, int pause); -int audpp_flush(unsigned id); -void audpp_avsync(int id, unsigned rate); -unsigned audpp_avsync_sample_count(int id); -unsigned audpp_avsync_byte_count(int id); -int audpp_dsp_set_mbadrc(unsigned id, unsigned enable, - audpp_cmd_cfg_object_params_mbadrc *mbadrc); -int audpp_dsp_set_eq(unsigned id, unsigned enable, - audpp_cmd_cfg_object_params_eqalizer *eq); -int audpp_dsp_set_rx_iir(unsigned id, unsigned enable, - audpp_cmd_cfg_object_params_pcm *iir); - -int audpp_dsp_set_rx_srs_trumedia_g - (struct audpp_cmd_cfg_object_params_srstm_g *srstm); -int audpp_dsp_set_rx_srs_trumedia_w - (struct audpp_cmd_cfg_object_params_srstm_w *srstm); -int audpp_dsp_set_rx_srs_trumedia_c - (struct audpp_cmd_cfg_object_params_srstm_c *srstm); -int audpp_dsp_set_rx_srs_trumedia_h - (struct audpp_cmd_cfg_object_params_srstm_h *srstm); -int audpp_dsp_set_rx_srs_trumedia_p - (struct audpp_cmd_cfg_object_params_srstm_p *srstm); -int audpp_dsp_set_rx_srs_trumedia_l - (struct audpp_cmd_cfg_object_params_srstm_l *srstm); - -int audpp_dsp_set_vol_pan(unsigned id, - audpp_cmd_cfg_object_params_volume *vol_pan); -int audpp_dsp_set_qconcert_plus(unsigned id, unsigned enable, - audpp_cmd_cfg_object_params_qconcert *qconcert_plus); -int audrectask_enable(unsigned enc_type, audrec_event_func func, void *private); -void audrectask_disable(unsigned enc_type, void *private); - -int audrectask_send_cmdqueue(void *cmd, unsigned len); -int audrectask_send_bitstreamqueue(void *cmd, unsigned len); - -#endif diff --git a/arch/arm/mach-msm/qdsp5/audmgr_new.h b/arch/arm/mach-msm/qdsp5/audmgr_new.h deleted file mode 100644 index a5188dc17196ce279baeddc3adae3dfdd8cbe091..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audmgr_new.h +++ /dev/null @@ -1,214 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/audmgr.h - * - * Copyright 2008 (c) The Linux Foundation. All rights reserved. - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _ARCH_ARM_MACH_MSM_AUDMGR_NEW_H -#define _ARCH_ARM_MACH_MSM_AUDMGR_NEW_H - -enum rpc_aud_def_sample_rate_type { - RPC_AUD_DEF_SAMPLE_RATE_NONE, - RPC_AUD_DEF_SAMPLE_RATE_8000, - RPC_AUD_DEF_SAMPLE_RATE_11025, - RPC_AUD_DEF_SAMPLE_RATE_12000, - RPC_AUD_DEF_SAMPLE_RATE_16000, - RPC_AUD_DEF_SAMPLE_RATE_22050, - RPC_AUD_DEF_SAMPLE_RATE_24000, - RPC_AUD_DEF_SAMPLE_RATE_32000, - RPC_AUD_DEF_SAMPLE_RATE_44100, - RPC_AUD_DEF_SAMPLE_RATE_48000, - RPC_AUD_DEF_SAMPLE_RATE_MAX, -}; - -enum rpc_aud_def_method_type { - RPC_AUD_DEF_METHOD_NONE, - RPC_AUD_DEF_METHOD_KEY_BEEP, - RPC_AUD_DEF_METHOD_PLAYBACK, - RPC_AUD_DEF_METHOD_VOICE, - RPC_AUD_DEF_METHOD_RECORD, - RPC_AUD_DEF_METHOD_HOST_PCM, - RPC_AUD_DEF_METHOD_MIDI_OUT, - RPC_AUD_DEF_METHOD_RECORD_SBC, - RPC_AUD_DEF_METHOD_DTMF_RINGER, - RPC_AUD_DEF_METHOD_MAX, -}; - -enum rpc_aud_def_codec_type { - RPC_AUD_DEF_CODEC_NONE, - RPC_AUD_DEF_CODEC_DTMF, - RPC_AUD_DEF_CODEC_MIDI, - RPC_AUD_DEF_CODEC_MP3, - RPC_AUD_DEF_CODEC_PCM, - RPC_AUD_DEF_CODEC_AAC, - RPC_AUD_DEF_CODEC_WMA, - RPC_AUD_DEF_CODEC_RA, - RPC_AUD_DEF_CODEC_ADPCM, - RPC_AUD_DEF_CODEC_GAUDIO, - RPC_AUD_DEF_CODEC_VOC_EVRC, - RPC_AUD_DEF_CODEC_VOC_13K, - RPC_AUD_DEF_CODEC_VOC_4GV_NB, - RPC_AUD_DEF_CODEC_VOC_AMR, - RPC_AUD_DEF_CODEC_VOC_EFR, - RPC_AUD_DEF_CODEC_VOC_FR, - RPC_AUD_DEF_CODEC_VOC_HR, - RPC_AUD_DEF_CODEC_VOC_CDMA, - RPC_AUD_DEF_CODEC_VOC_CDMA_WB, - RPC_AUD_DEF_CODEC_VOC_UMTS, - RPC_AUD_DEF_CODEC_VOC_UMTS_WB, - RPC_AUD_DEF_CODEC_SBC, - RPC_AUD_DEF_CODEC_VOC_PCM, - RPC_AUD_DEF_CODEC_AMR_WB, - RPC_AUD_DEF_CODEC_AMR_WB_PLUS, - RPC_AUD_DEF_CODEC_AAC_BSAC, - RPC_AUD_DEF_CODEC_MAX, - RPC_AUD_DEF_CODEC_AMR_NB, - RPC_AUD_DEF_CODEC_13K, - RPC_AUD_DEF_CODEC_EVRC, - RPC_AUD_DEF_CODEC_AC3, - RPC_AUD_DEF_CODEC_MAX_002, -}; - -enum rpc_snd_method_type { - RPC_SND_METHOD_VOICE = 0, - RPC_SND_METHOD_KEY_BEEP, - RPC_SND_METHOD_MESSAGE, - RPC_SND_METHOD_RING, - RPC_SND_METHOD_MIDI, - RPC_SND_METHOD_AUX, - RPC_SND_METHOD_MAX, -}; - -enum rpc_voc_codec_type { - RPC_VOC_CODEC_DEFAULT, - RPC_VOC_CODEC_ON_CHIP_0 = RPC_VOC_CODEC_DEFAULT, - RPC_VOC_CODEC_ON_CHIP_1, - RPC_VOC_CODEC_STEREO_HEADSET, - RPC_VOC_CODEC_ON_CHIP_AUX, - RPC_VOC_CODEC_BT_OFF_BOARD, - RPC_VOC_CODEC_BT_A2DP, - RPC_VOC_CODEC_OFF_BOARD, - RPC_VOC_CODEC_SDAC, - RPC_VOC_CODEC_RX_EXT_SDAC_TX_INTERNAL, - RPC_VOC_CODEC_IN_STEREO_SADC_OUT_MONO_HANDSET, - RPC_VOC_CODEC_IN_STEREO_SADC_OUT_STEREO_HEADSET, - RPC_VOC_CODEC_TX_INT_SADC_RX_EXT_AUXPCM, - RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_MONO_HANDSET, - RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_STEREO_HEADSET, - RPC_VOC_CODEC_TTY_ON_CHIP_1, - RPC_VOC_CODEC_TTY_OFF_BOARD, - RPC_VOC_CODEC_TTY_VCO, - RPC_VOC_CODEC_TTY_HCO, - RPC_VOC_CODEC_ON_CHIP_0_DUAL_MIC, - RPC_VOC_CODEC_MAX, - RPC_VOC_CODEC_NONE, -}; - -enum rpc_audmgr_status_type { - RPC_AUDMGR_STATUS_READY, - RPC_AUDMGR_STATUS_CODEC_CONFIG, - RPC_AUDMGR_STATUS_PENDING, - RPC_AUDMGR_STATUS_SUSPEND, - RPC_AUDMGR_STATUS_FAILURE, - RPC_AUDMGR_STATUS_VOLUME_CHANGE, - RPC_AUDMGR_STATUS_DISABLED, - RPC_AUDMGR_STATUS_ERROR, -}; - -struct rpc_audmgr_enable_client_args { - uint32_t set_to_one; - uint32_t tx_sample_rate; - uint32_t rx_sample_rate; - uint32_t def_method; - uint32_t codec_type; - uint32_t snd_method; - - uint32_t cb_func; - uint32_t client_data; -}; - -#define AUDMGR_ENABLE_CLIENT 2 -#define AUDMGR_DISABLE_CLIENT 3 -#define AUDMGR_SUSPEND_EVENT_RSP 4 -#define AUDMGR_REGISTER_OPERATION_LISTENER 5 -#define AUDMGR_UNREGISTER_OPERATION_LISTENER 6 -#define AUDMGR_REGISTER_CODEC_LISTENER 7 -#define AUDMGR_GET_RX_SAMPLE_RATE 8 -#define AUDMGR_GET_TX_SAMPLE_RATE 9 -#define AUDMGR_SET_DEVICE_MODE 10 - -#define AUDMGR_PROG 0x30000013 -#define AUDMGR_VERS MSM_RPC_VERS(1,0) - -struct rpc_audmgr_cb_func_ptr { - uint32_t cb_id; - uint32_t status; /* Audmgr status */ - uint32_t set_to_one; /* Pointer status (1 = valid, 0 = invalid) */ - uint32_t disc; - /* disc = AUDMGR_STATUS_READY => data=handle - disc = AUDMGR_STATUS_CODEC_CONFIG => data = handle - disc = AUDMGR_STATUS_DISABLED => data =status_disabled - disc = AUDMGR_STATUS_VOLUME_CHANGE => data = volume-change */ - union { - uint32_t handle; - uint32_t volume; - uint32_t status_disabled; - uint32_t volume_change; - } u; -}; - -#define AUDMGR_CB_FUNC_PTR 1 -#define AUDMGR_OPR_LSTNR_CB_FUNC_PTR 2 -#define AUDMGR_CODEC_LSTR_FUNC_PTR 3 - -#define AUDMGR_CB_PROG 0x31000013 -#define AUDMGR_CB_VERS 0xf8e3e2d9 - -struct audmgr { - wait_queue_head_t wait; - uint32_t handle; - struct msm_rpc_endpoint *ept; - struct task_struct *task; - int state; -}; - -struct audmgr_config { - uint32_t tx_rate; - uint32_t rx_rate; - uint32_t def_method; - uint32_t codec; - uint32_t snd_method; -}; - -int audmgr_open(struct audmgr *am); -int audmgr_close(struct audmgr *am); -int audmgr_enable(struct audmgr *am, struct audmgr_config *cfg); -int audmgr_disable(struct audmgr *am); - -typedef void (*audpp_event_func)(void *private, unsigned id, uint16_t *msg); - -int audpp_enable(int id, audpp_event_func func, void *private); -void audpp_disable(int id, void *private); - -int audpp_send_queue1(void *cmd, unsigned len); -int audpp_send_queue2(void *cmd, unsigned len); -int audpp_send_queue3(void *cmd, unsigned len); - -int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan); -int audpp_pause(unsigned id, int pause); -int audpp_flush(unsigned id); -void audpp_avsync(int id, unsigned rate); -unsigned audpp_avsync_sample_count(int id); -unsigned audpp_avsync_byte_count(int id); - -#endif diff --git a/arch/arm/mach-msm/qdsp5/audpp.c b/arch/arm/mach-msm/qdsp5/audpp.c deleted file mode 100644 index b7812862320a9f03ddfb92e680ee4458da8b5051..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audpp.c +++ /dev/null @@ -1,1014 +0,0 @@ - -/* arch/arm/mach-msm/qdsp5/audpp.c - * - * common code to deal with the AUDPP dsp task (audio postproc) - * - * Copyright (C) 2008 Google, Inc. - * Copyright (c) 2009-2010, 2012 The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "audmgr.h" - -#include -#include -#include - -#include "evlog.h" - -enum { - EV_NULL, - EV_ENABLE, - EV_DISABLE, - EV_EVENT, - EV_DATA, -}; - -static const char *dsp_log_strings[] = { - "NULL", - "ENABLE", - "DISABLE", - "EVENT", - "DATA", -}; - -DECLARE_LOG(dsp_log, 64, dsp_log_strings); - -static int __init _dsp_log_init(void) -{ - return ev_log_init(&dsp_log); -} - -module_init(_dsp_log_init); -#define LOG(id,arg) ev_log_write(&dsp_log, id, arg) - -static DEFINE_MUTEX(audpp_lock); -static DEFINE_MUTEX(audpp_dec_lock); - -#define CH_COUNT 5 -#define AUDPP_CLNT_MAX_COUNT 6 -#define AUDPP_AVSYNC_INFO_SIZE 7 - -#define AUDPP_SRS_PARAMS 2 -#define AUDPP_SRS_PARAMS_G 0 -#define AUDPP_SRS_PARAMS_W 1 -#define AUDPP_SRS_PARAMS_C 2 -#define AUDPP_SRS_PARAMS_H 3 -#define AUDPP_SRS_PARAMS_P 4 -#define AUDPP_SRS_PARAMS_L 5 - -#define AUDPP_CMD_CFG_OBJ_UPDATE 0x8000 -#define AUDPP_CMD_EQ_FLAG_DIS 0x0000 -#define AUDPP_CMD_EQ_FLAG_ENA -1 -#define AUDPP_CMD_IIR_FLAG_DIS 0x0000 -#define AUDPP_CMD_IIR_FLAG_ENA -1 - -#define AUDPP_CMD_VOLUME_PAN 0 -#define AUDPP_CMD_IIR_TUNING_FILTER 1 -#define AUDPP_CMD_EQUALIZER 2 -#define AUDPP_CMD_ADRC 3 -#define AUDPP_CMD_SPECTROGRAM 4 -#define AUDPP_CMD_QCONCERT 5 -#define AUDPP_CMD_SIDECHAIN_TUNING_FILTER 6 -#define AUDPP_CMD_SAMPLING_FREQUENCY 7 -#define AUDPP_CMD_QAFX 8 -#define AUDPP_CMD_QRUMBLE 9 -#define AUDPP_CMD_MBADRC 10 - -#define MAX_EVENT_CALLBACK_CLIENTS 1 - -#define AUDPP_CONCURRENCY_DEFAULT 6 /* All non tunnel mode */ -#define AUDPP_MAX_DECODER_CNT 5 -#define AUDPP_CODEC_MASK 0x000000FF -#define AUDPP_MODE_MASK 0x00000F00 -#define AUDPP_OP_MASK 0xF0000000 - -struct audpp_decoder_info { - unsigned int codec; - pid_t pid; -}; - -struct audpp_state { - struct msm_adsp_module *mod; - audpp_event_func func[AUDPP_CLNT_MAX_COUNT]; - void *private[AUDPP_CLNT_MAX_COUNT]; - struct mutex *lock; - unsigned open_count; - unsigned enabled; - - /* Related to decoder allocation */ - struct mutex *lock_dec; - struct msm_adspdec_database *dec_database; - struct audpp_decoder_info dec_info_table[AUDPP_MAX_DECODER_CNT]; - unsigned dec_inuse; - unsigned long concurrency; - - /* which channels are actually enabled */ - unsigned avsync_mask; - - /* flags, 48 bits sample/bytes counter per channel */ - uint16_t avsync[CH_COUNT * AUDPP_CLNT_MAX_COUNT + 1]; - struct audpp_event_callback *cb_tbl[MAX_EVENT_CALLBACK_CLIENTS]; - - spinlock_t avsync_lock; - - wait_queue_head_t event_wait; -}; - -struct audpp_state the_audpp_state = { - .lock = &audpp_lock, - .lock_dec = &audpp_dec_lock, -}; - -int audpp_send_queue1(void *cmd, unsigned len) -{ - return msm_adsp_write(the_audpp_state.mod, - QDSP_uPAudPPCmd1Queue, cmd, len); -} -EXPORT_SYMBOL(audpp_send_queue1); - -int audpp_send_queue2(void *cmd, unsigned len) -{ - return msm_adsp_write(the_audpp_state.mod, - QDSP_uPAudPPCmd2Queue, cmd, len); -} -EXPORT_SYMBOL(audpp_send_queue2); - -int audpp_send_queue3(void *cmd, unsigned len) -{ - return msm_adsp_write(the_audpp_state.mod, - QDSP_uPAudPPCmd3Queue, cmd, len); -} -EXPORT_SYMBOL(audpp_send_queue3); - -static int audpp_dsp_config(int enable) -{ - audpp_cmd_cfg cmd; - - cmd.cmd_id = AUDPP_CMD_CFG; - cmd.cfg = enable ? AUDPP_CMD_CFG_ENABLE : AUDPP_CMD_CFG_SLEEP; - - return audpp_send_queue1(&cmd, sizeof(cmd)); -} - -int is_audpp_enable(void) -{ - struct audpp_state *audpp = &the_audpp_state; - - return audpp->enabled; -} -EXPORT_SYMBOL(is_audpp_enable); - -int audpp_register_event_callback(struct audpp_event_callback *ecb) -{ - struct audpp_state *audpp = &the_audpp_state; - int i; - - for (i = 0; i < MAX_EVENT_CALLBACK_CLIENTS; ++i) { - if (NULL == audpp->cb_tbl[i]) { - audpp->cb_tbl[i] = ecb; - return 0; - } - } - return -1; -} -EXPORT_SYMBOL(audpp_register_event_callback); - -int audpp_unregister_event_callback(struct audpp_event_callback *ecb) -{ - struct audpp_state *audpp = &the_audpp_state; - int i; - - for (i = 0; i < MAX_EVENT_CALLBACK_CLIENTS; ++i) { - if (ecb == audpp->cb_tbl[i]) { - audpp->cb_tbl[i] = NULL; - return 0; - } - } - return -1; -} -EXPORT_SYMBOL(audpp_unregister_event_callback); - -static void audpp_broadcast(struct audpp_state *audpp, unsigned id, - uint16_t *msg) -{ - unsigned n; - for (n = 0; n < AUDPP_CLNT_MAX_COUNT; n++) { - if (audpp->func[n]) - audpp->func[n] (audpp->private[n], id, msg); - } - - for (n = 0; n < MAX_EVENT_CALLBACK_CLIENTS; ++n) - if (audpp->cb_tbl[n] && audpp->cb_tbl[n]->fn) - audpp->cb_tbl[n]->fn(audpp->cb_tbl[n]->private, id, - msg); -} - -static void audpp_notify_clnt(struct audpp_state *audpp, unsigned clnt_id, - unsigned id, uint16_t *msg) -{ - if (clnt_id < AUDPP_CLNT_MAX_COUNT && audpp->func[clnt_id]) - audpp->func[clnt_id] (audpp->private[clnt_id], id, msg); -} - -static void audpp_handle_pcmdmamiss(struct audpp_state *audpp, - uint16_t bit_mask) -{ - uint8_t b_index; - - for (b_index = 0; b_index < AUDPP_CLNT_MAX_COUNT; b_index++) { - if (bit_mask & (0x1 << b_index)) - if (audpp->func[b_index]) - audpp->func[b_index] (audpp->private[b_index], - AUDPP_MSG_PCMDMAMISSED, - &bit_mask); - } -} - -static void audpp_fake_event(struct audpp_state *audpp, int id, - unsigned event, unsigned arg) -{ - uint16_t msg[1]; - msg[0] = arg; - audpp->func[id] (audpp->private[id], event, msg); -} - -static void audpp_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audpp_state *audpp = data; - unsigned long flags; - uint16_t msg[8]; - int cid = 0; - - if (id == AUDPP_MSG_AVSYNC_MSG) { - spin_lock_irqsave(&audpp->avsync_lock, flags); - getevent(audpp->avsync, sizeof(audpp->avsync)); - - /* mask off any channels we're not watching to avoid - * cases where we might get one last update after - * disabling avsync and end up in an odd state when - * we next read... - */ - audpp->avsync[0] &= audpp->avsync_mask; - spin_unlock_irqrestore(&audpp->avsync_lock, flags); - return; - } - - getevent(msg, sizeof(msg)); - - LOG(EV_EVENT, (id << 16) | msg[0]); - LOG(EV_DATA, (msg[1] << 16) | msg[2]); - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned cid = msg[0]; - MM_DBG("status %d %d %d\n", cid, msg[1], msg[2]); - if ((cid < 5) && audpp->func[cid]) - audpp->func[cid] (audpp->private[cid], id, msg); - break; - } - case AUDPP_MSG_HOST_PCM_INTF_MSG: - if (audpp->func[5]) - audpp->func[5] (audpp->private[5], id, msg); - break; - case AUDPP_MSG_PCMDMAMISSED: - audpp_handle_pcmdmamiss(audpp, msg[0]); - break; - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_INFO("ENABLE\n"); - if (!audpp->enabled) { - audpp->enabled = 1; - audpp_broadcast(audpp, id, msg); - } else { - cid = msg[1]; - audpp_fake_event(audpp, cid, - id, AUDPP_MSG_ENA_ENA); - } - - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - if (audpp->open_count == 0) { - MM_INFO("DISABLE\n"); - audpp->enabled = 0; - wake_up(&audpp->event_wait); - audpp_broadcast(audpp, id, msg); - } else { - cid = msg[1]; - audpp_fake_event(audpp, cid, - id, AUDPP_MSG_ENA_DIS); - audpp->func[cid] = NULL; - audpp->private[cid] = NULL; - } - } else { - MM_ERR("invalid config msg %d\n", msg[0]); - } - break; - case AUDPP_MSG_ROUTING_ACK: - audpp_notify_clnt(audpp, msg[0], id, msg); - break; - case AUDPP_MSG_FLUSH_ACK: - audpp_notify_clnt(audpp, msg[0], id, msg); - break; - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable/disable(audpptask)"); - break; - default: - MM_ERR("unhandled msg id %x\n", id); - } -} - -static struct msm_adsp_ops adsp_ops = { - .event = audpp_dsp_event, -}; - -int audpp_enable(int id, audpp_event_func func, void *private) -{ - struct audpp_state *audpp = &the_audpp_state; - uint16_t msg[8]; - int res = 0; - - if (id < -1 || id > 4) - return -EINVAL; - - if (id == -1) - id = 5; - - mutex_lock(audpp->lock); - if (audpp->func[id]) { - res = -EBUSY; - goto out; - } - - audpp->func[id] = func; - audpp->private[id] = private; - - LOG(EV_ENABLE, 1); - if (audpp->open_count++ == 0) { - MM_DBG("enable\n"); - res = msm_adsp_get("AUDPPTASK", &audpp->mod, &adsp_ops, audpp); - if (res < 0) { - MM_ERR("cannot open AUDPPTASK\n"); - audpp->open_count = 0; - audpp->func[id] = NULL; - audpp->private[id] = NULL; - goto out; - } - LOG(EV_ENABLE, 2); - msm_adsp_enable(audpp->mod); - audpp_dsp_config(1); - } else { - if (audpp->enabled) { - msg[0] = AUDPP_MSG_ENA_ENA; - msg[1] = id; - res = msm_adsp_generate_event(audpp, audpp->mod, - AUDPP_MSG_CFG_MSG, sizeof(msg), - sizeof(uint16_t), (void *)msg); - if (res < 0) - goto out; - } - } - - res = 0; -out: - mutex_unlock(audpp->lock); - return res; -} -EXPORT_SYMBOL(audpp_enable); - -void audpp_disable(int id, void *private) -{ - struct audpp_state *audpp = &the_audpp_state; - uint16_t msg[8]; - int rc; - - if (id < -1 || id > 4) - return; - - if (id == -1) - id = 5; - - mutex_lock(audpp->lock); - LOG(EV_DISABLE, 1); - if (!audpp->func[id]) - goto out; - if (audpp->private[id] != private) - goto out; - - msg[0] = AUDPP_MSG_ENA_DIS; - msg[1] = id; - rc = msm_adsp_generate_event(audpp, audpp->mod, - AUDPP_MSG_CFG_MSG, sizeof(msg), - sizeof(uint16_t), (void *)msg); - if (rc < 0) - goto out; - - if (--audpp->open_count == 0) { - MM_DBG("disable\n"); - LOG(EV_DISABLE, 2); - audpp_dsp_config(0); - rc = wait_event_interruptible(audpp->event_wait, - (audpp->enabled == 0)); - if (audpp->enabled == 0) - MM_INFO("Received CFG_MSG_DISABLE from ADSP\n"); - else - MM_ERR("Didn't receive CFG_MSG DISABLE \ - message from ADSP\n"); - msm_adsp_disable(audpp->mod); - msm_adsp_put(audpp->mod); - audpp->mod = NULL; - } -out: - mutex_unlock(audpp->lock); -} -EXPORT_SYMBOL(audpp_disable); - -#define BAD_ID(id) ((id < 0) || (id >= CH_COUNT)) - -void audpp_avsync(int id, unsigned rate) -{ - unsigned long flags; - audpp_cmd_avsync cmd; - - if (BAD_ID(id)) - return; - - spin_lock_irqsave(&the_audpp_state.avsync_lock, flags); - if (rate) - the_audpp_state.avsync_mask |= (1 << id); - else - the_audpp_state.avsync_mask &= (~(1 << id)); - the_audpp_state.avsync[0] &= the_audpp_state.avsync_mask; - spin_unlock_irqrestore(&the_audpp_state.avsync_lock, flags); - - cmd.cmd_id = AUDPP_CMD_AVSYNC; - cmd.object_number = id; - cmd.interrupt_interval_lsw = rate; - cmd.interrupt_interval_msw = rate >> 16; - audpp_send_queue1(&cmd, sizeof(cmd)); -} -EXPORT_SYMBOL(audpp_avsync); - -unsigned audpp_avsync_sample_count(int id) -{ - struct audpp_state *audpp = &the_audpp_state; - uint16_t *avsync = audpp->avsync; - unsigned val; - unsigned long flags; - unsigned mask; - - if (BAD_ID(id)) - return 0; - - mask = 1 << id; - id = id * AUDPP_AVSYNC_INFO_SIZE + 2; - spin_lock_irqsave(&audpp->avsync_lock, flags); - if (avsync[0] & mask) - val = (avsync[id] << 16) | avsync[id + 1]; - else - val = 0; - spin_unlock_irqrestore(&audpp->avsync_lock, flags); - - return val; -} -EXPORT_SYMBOL(audpp_avsync_sample_count); - -unsigned audpp_avsync_byte_count(int id) -{ - struct audpp_state *audpp = &the_audpp_state; - uint16_t *avsync = audpp->avsync; - unsigned val; - unsigned long flags; - unsigned mask; - - if (BAD_ID(id)) - return 0; - - mask = 1 << id; - id = id * AUDPP_AVSYNC_INFO_SIZE + 5; - spin_lock_irqsave(&audpp->avsync_lock, flags); - if (avsync[0] & mask) - val = (avsync[id] << 16) | avsync[id + 1]; - else - val = 0; - spin_unlock_irqrestore(&audpp->avsync_lock, flags); - - return val; -} -EXPORT_SYMBOL(audpp_avsync_byte_count); - -int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan) -{ - /* cmd, obj_cfg[7], cmd_type, volume, pan */ - uint16_t cmd[11]; - - if (id > 6) - return -EINVAL; - - memset(cmd, 0, sizeof(cmd)); - cmd[0] = AUDPP_CMD_CFG_OBJECT_PARAMS; - cmd[1 + id] = AUDPP_CMD_CFG_OBJ_UPDATE; - cmd[8] = AUDPP_CMD_VOLUME_PAN; - cmd[9] = volume; - cmd[10] = pan; - - return audpp_send_queue3(cmd, sizeof(cmd)); -} -EXPORT_SYMBOL(audpp_set_volume_and_pan); - -/* Implementation of COPP features */ -int audpp_dsp_set_mbadrc(unsigned id, unsigned enable, - audpp_cmd_cfg_object_params_mbadrc *mbadrc) -{ - audpp_cmd_cfg_object_params_mbadrc cmd; - - if (id != 6) - return -EINVAL; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE; - cmd.common.command_type = AUDPP_CMD_MBADRC; - - if (enable) { - memcpy(&cmd.num_bands, &mbadrc->num_bands, - sizeof(*mbadrc) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2)); - cmd.enable = AUDPP_CMD_ADRC_FLAG_ENA; - } else - cmd.enable = AUDPP_CMD_ADRC_FLAG_DIS; - - /*order the writes to mbadrc */ - dma_coherent_pre_ops(); - return audpp_send_queue3(&cmd, sizeof(cmd)); -} -EXPORT_SYMBOL(audpp_dsp_set_mbadrc); - -int audpp_dsp_set_qconcert_plus(unsigned id, unsigned enable, - audpp_cmd_cfg_object_params_qconcert * - qconcert_plus) -{ - audpp_cmd_cfg_object_params_qconcert cmd; - if (id != 6) - return -EINVAL; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE; - cmd.common.command_type = AUDPP_CMD_QCONCERT; - - if (enable) { - memcpy(&cmd.op_mode, &qconcert_plus->op_mode, - sizeof(audpp_cmd_cfg_object_params_qconcert) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2)); - cmd.enable_flag = AUDPP_CMD_ADRC_FLAG_ENA; - } else - cmd.enable_flag = AUDPP_CMD_ADRC_FLAG_DIS; - - return audpp_send_queue3(&cmd, sizeof(cmd)); -} - -int audpp_dsp_set_rx_iir(unsigned id, unsigned enable, - audpp_cmd_cfg_object_params_pcm *iir) -{ - audpp_cmd_cfg_object_params_pcm cmd; - - if (id != 6) - return -EINVAL; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE; - cmd.common.command_type = AUDPP_CMD_IIR_TUNING_FILTER; - - if (enable) { - cmd.active_flag = AUDPP_CMD_IIR_FLAG_ENA; - cmd.num_bands = iir->num_bands; - memcpy(&cmd.params_filter, &iir->params_filter, - sizeof(iir->params_filter)); - } else - cmd.active_flag = AUDPP_CMD_IIR_FLAG_DIS; - - return audpp_send_queue3(&cmd, sizeof(cmd)); -} -EXPORT_SYMBOL(audpp_dsp_set_rx_iir); - -int audpp_dsp_set_rx_srs_trumedia_g( - struct audpp_cmd_cfg_object_params_srstm_g *srstm) -{ - struct audpp_cmd_cfg_object_params_srstm_g cmd; - - MM_DBG("%s\n", __func__); - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_SRS_PARAMS; - cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE; - cmd.common.command_type = AUDPP_SRS_PARAMS_G; - - memcpy(cmd.v, srstm->v, sizeof(srstm->v)); - - return audpp_send_queue3(&cmd, sizeof(cmd)); -} -EXPORT_SYMBOL(audpp_dsp_set_rx_srs_trumedia_g); - -int audpp_dsp_set_rx_srs_trumedia_w( - struct audpp_cmd_cfg_object_params_srstm_w *srstm) -{ - struct audpp_cmd_cfg_object_params_srstm_w cmd; - - MM_DBG("%s\n", __func__); - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_SRS_PARAMS; - cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE; - cmd.common.command_type = AUDPP_SRS_PARAMS_W; - - memcpy(cmd.v, srstm->v, sizeof(srstm->v)); - - return audpp_send_queue3(&cmd, sizeof(cmd)); -} -EXPORT_SYMBOL(audpp_dsp_set_rx_srs_trumedia_w); - -int audpp_dsp_set_rx_srs_trumedia_c( - struct audpp_cmd_cfg_object_params_srstm_c *srstm) -{ - struct audpp_cmd_cfg_object_params_srstm_c cmd; - - MM_DBG("%s\n", __func__); - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_SRS_PARAMS; - cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE; - cmd.common.command_type = AUDPP_SRS_PARAMS_C; - - memcpy(cmd.v, srstm->v, sizeof(srstm->v)); - - return audpp_send_queue3(&cmd, sizeof(cmd)); -} -EXPORT_SYMBOL(audpp_dsp_set_rx_srs_trumedia_c); - -int audpp_dsp_set_rx_srs_trumedia_h( - struct audpp_cmd_cfg_object_params_srstm_h *srstm) -{ - struct audpp_cmd_cfg_object_params_srstm_h cmd; - - MM_DBG("%s\n", __func__); - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_SRS_PARAMS; - cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE; - cmd.common.command_type = AUDPP_SRS_PARAMS_H; - - memcpy(cmd.v, srstm->v, sizeof(srstm->v)); - - return audpp_send_queue3(&cmd, sizeof(cmd)); -} -EXPORT_SYMBOL(audpp_dsp_set_rx_srs_trumedia_h); - -int audpp_dsp_set_rx_srs_trumedia_p( - struct audpp_cmd_cfg_object_params_srstm_p *srstm) -{ - struct audpp_cmd_cfg_object_params_srstm_p cmd; - - MM_DBG("%s\n", __func__); - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_SRS_PARAMS; - cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE; - cmd.common.command_type = AUDPP_SRS_PARAMS_P; - - memcpy(cmd.v, srstm->v, sizeof(srstm->v)); - - return audpp_send_queue3(&cmd, sizeof(cmd)); -} -EXPORT_SYMBOL(audpp_dsp_set_rx_srs_trumedia_p); - -int audpp_dsp_set_rx_srs_trumedia_l( - struct audpp_cmd_cfg_object_params_srstm_l *srstm) -{ - struct audpp_cmd_cfg_object_params_srstm_l cmd; - - MM_DBG("%s\n", __func__); - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_SRS_PARAMS; - cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE; - cmd.common.command_type = AUDPP_SRS_PARAMS_L; - - memcpy(cmd.v, srstm->v, sizeof(srstm->v)); - - return audpp_send_queue3(&cmd, sizeof(cmd)); -} -EXPORT_SYMBOL(audpp_dsp_set_rx_srs_trumedia_l); - -/* Implementation Of COPP + POPP */ -int audpp_dsp_set_eq(unsigned id, unsigned enable, - audpp_cmd_cfg_object_params_eqalizer *eq) -{ - audpp_cmd_cfg_object_params_eqalizer cmd; - unsigned short *id_ptr = (unsigned short *)&cmd; - - if (id > 6 || id == 5) - return -EINVAL; - - memset(&cmd, 0, sizeof(cmd)); - id_ptr[1 + id] = AUDPP_CMD_CFG_OBJ_UPDATE; - cmd.common.command_type = AUDPP_CMD_EQUALIZER; - - if (enable) { - cmd.eq_flag = AUDPP_CMD_EQ_FLAG_ENA; - cmd.num_bands = eq->num_bands; - memcpy(&cmd.eq_coeff, &eq->eq_coeff, sizeof(eq->eq_coeff)); - } else - cmd.eq_flag = AUDPP_CMD_EQ_FLAG_DIS; - - return audpp_send_queue3(&cmd, sizeof(cmd)); -} -EXPORT_SYMBOL(audpp_dsp_set_eq); - -int audpp_dsp_set_vol_pan(unsigned id, - audpp_cmd_cfg_object_params_volume *vol_pan) -{ - audpp_cmd_cfg_object_params_volume cmd; - unsigned short *id_ptr = (unsigned short *)&cmd; - - if (id > 6) - return -EINVAL; - - memset(&cmd, 0, sizeof(cmd)); - id_ptr[1 + id] = AUDPP_CMD_CFG_OBJ_UPDATE; - cmd.common.command_type = AUDPP_CMD_VOLUME_PAN; - - cmd.volume = vol_pan->volume; - cmd.pan = vol_pan->pan; - - return audpp_send_queue3(&cmd, sizeof(cmd)); -} -EXPORT_SYMBOL(audpp_dsp_set_vol_pan); - -int audpp_pause(unsigned id, int pause) -{ - /* pause 1 = pause 0 = resume */ - u16 pause_cmd[AUDPP_CMD_DEC_CTRL_LEN / sizeof(unsigned short)]; - - if (id >= CH_COUNT) - return -EINVAL; - - memset(pause_cmd, 0, sizeof(pause_cmd)); - - pause_cmd[0] = AUDPP_CMD_DEC_CTRL; - if (pause == 1) - pause_cmd[1 + id] = AUDPP_CMD_UPDATE_V | AUDPP_CMD_PAUSE_V; - else if (pause == 0) - pause_cmd[1 + id] = AUDPP_CMD_UPDATE_V | AUDPP_CMD_RESUME_V; - else - return -EINVAL; - - return audpp_send_queue1(pause_cmd, sizeof(pause_cmd)); -} -EXPORT_SYMBOL(audpp_pause); - -int audpp_flush(unsigned id) -{ - u16 flush_cmd[AUDPP_CMD_DEC_CTRL_LEN / sizeof(unsigned short)]; - - if (id >= CH_COUNT) - return -EINVAL; - - memset(flush_cmd, 0, sizeof(flush_cmd)); - - flush_cmd[0] = AUDPP_CMD_DEC_CTRL; - flush_cmd[1 + id] = AUDPP_CMD_UPDATE_V | AUDPP_CMD_FLUSH_V; - - return audpp_send_queue1(flush_cmd, sizeof(flush_cmd)); -} -EXPORT_SYMBOL(audpp_flush); - -/* dec_attrb = 7:0, 0 - No Decoder, else supported decoder * - * like mp3, aac, wma etc ... * - * = 15:8, bit[8] = 1 - Tunnel, bit[9] = 1 - NonTunnel * - * = 31:16, reserved */ -int audpp_adec_alloc(unsigned dec_attrb, const char **module_name, - unsigned *queueid) -{ - struct audpp_state *audpp = &the_audpp_state; - int decid = -1, idx, lidx, mode, codec; - int codecs_supported, min_codecs_supported; - unsigned int *concurrency_entry; - mutex_lock(audpp->lock_dec); - /* Represents in bit mask */ - mode = ((dec_attrb & AUDPP_MODE_MASK) << 16); - codec = (1 << (dec_attrb & AUDPP_CODEC_MASK)); - /* Point to Last entry of the row */ - concurrency_entry = ((audpp->dec_database->dec_concurrency_table + - ((audpp->concurrency + 1) * - (audpp->dec_database->num_dec))) - 1); - - lidx = audpp->dec_database->num_dec; - min_codecs_supported = sizeof(unsigned int) * 8; - - MM_DBG("mode = 0x%08x codec = 0x%08x\n", mode, codec); - - for (idx = lidx; idx > 0; idx--, concurrency_entry--) { - if (!(audpp->dec_inuse & (1 << (idx - 1)))) { - if ((mode & *concurrency_entry) && - (codec & *concurrency_entry)) { - /* Check supports minimum number codecs */ - codecs_supported = - audpp->dec_database->dec_info_list[idx - - 1]. - nr_codec_support; - if (codecs_supported < min_codecs_supported) { - lidx = idx - 1; - min_codecs_supported = codecs_supported; - } - } - } - } - - if (lidx < audpp->dec_database->num_dec) { - audpp->dec_inuse |= (1 << lidx); - *module_name = - audpp->dec_database->dec_info_list[lidx].module_name; - *queueid = - audpp->dec_database->dec_info_list[lidx].module_queueid; - decid = audpp->dec_database->dec_info_list[lidx].module_decid; - audpp->dec_info_table[lidx].codec = - (dec_attrb & AUDPP_CODEC_MASK); - audpp->dec_info_table[lidx].pid = current->pid; - /* point to row to get supported operation */ - concurrency_entry = - ((audpp->dec_database->dec_concurrency_table + - ((audpp->concurrency) * (audpp->dec_database->num_dec))) + - lidx); - decid |= ((*concurrency_entry & AUDPP_OP_MASK) >> 12); - MM_INFO("decid =0x%08x module_name=%s, queueid=%d \n", - decid, *module_name, *queueid); - } - mutex_unlock(audpp->lock_dec); - return decid; - -} -EXPORT_SYMBOL(audpp_adec_alloc); - -void audpp_adec_free(int decid) -{ - struct audpp_state *audpp = &the_audpp_state; - int idx; - mutex_lock(audpp->lock_dec); - for (idx = audpp->dec_database->num_dec; idx > 0; idx--) { - if (audpp->dec_database->dec_info_list[idx - 1].module_decid == - decid) { - audpp->dec_inuse &= ~(1 << (idx - 1)); - audpp->dec_info_table[idx - 1].codec = -1; - audpp->dec_info_table[idx - 1].pid = 0; - MM_INFO("free decid =%d \n", decid); - break; - } - } - mutex_unlock(audpp->lock_dec); - return; - -} -EXPORT_SYMBOL(audpp_adec_free); - -static ssize_t concurrency_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct audpp_state *audpp = &the_audpp_state; - int rc; - mutex_lock(audpp->lock_dec); - rc = sprintf(buf, "%ld\n", audpp->concurrency); - mutex_unlock(audpp->lock_dec); - return rc; -} - -static ssize_t concurrency_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct audpp_state *audpp = &the_audpp_state; - unsigned long concurrency; - int rc = -1; - mutex_lock(audpp->lock_dec); - if (audpp->dec_inuse) { - MM_ERR("Can not change profile, while playback in progress\n"); - goto done; - } - rc = strict_strtoul(buf, 10, &concurrency); - if (!rc && - (concurrency < audpp->dec_database->num_concurrency_support)) { - audpp->concurrency = concurrency; - MM_DBG("Concurrency case %ld\n", audpp->concurrency); - rc = count; - } else { - MM_ERR("Not a valid Concurrency case\n"); - rc = -EINVAL; - } -done: - mutex_unlock(audpp->lock_dec); - return rc; -} - -static ssize_t decoder_info_show(struct device *dev, - struct device_attribute *attr, char *buf); -static struct device_attribute dev_attr_decoder[AUDPP_MAX_DECODER_CNT] = { - __ATTR(decoder0, S_IRUGO, decoder_info_show, NULL), - __ATTR(decoder1, S_IRUGO, decoder_info_show, NULL), - __ATTR(decoder2, S_IRUGO, decoder_info_show, NULL), - __ATTR(decoder3, S_IRUGO, decoder_info_show, NULL), - __ATTR(decoder4, S_IRUGO, decoder_info_show, NULL), -}; - -static ssize_t decoder_info_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int cpy_sz = 0; - struct audpp_state *audpp = &the_audpp_state; - const ptrdiff_t off = attr - dev_attr_decoder; /* decoder number */ - mutex_lock(audpp->lock_dec); - cpy_sz += scnprintf(buf + cpy_sz, PAGE_SIZE - cpy_sz, "%d:", - audpp->dec_info_table[off].codec); - cpy_sz += scnprintf(buf + cpy_sz, PAGE_SIZE - cpy_sz, "%d\n", - audpp->dec_info_table[off].pid); - mutex_unlock(audpp->lock_dec); - return cpy_sz; -} - -static DEVICE_ATTR(concurrency, S_IWUSR | S_IRUGO, concurrency_show, - concurrency_store); -static int audpp_probe(struct platform_device *pdev) -{ - int rc, idx; - struct audpp_state *audpp = &the_audpp_state; - audpp->concurrency = AUDPP_CONCURRENCY_DEFAULT; - audpp->dec_database = - (struct msm_adspdec_database *)pdev->dev.platform_data; - - MM_INFO("Number of decoder supported %d\n", - audpp->dec_database->num_dec); - MM_INFO("Number of concurrency supported %d\n", - audpp->dec_database->num_concurrency_support); - - init_waitqueue_head(&audpp->event_wait); - - spin_lock_init(&audpp->avsync_lock); - - for (idx = 0; idx < audpp->dec_database->num_dec; idx++) { - audpp->dec_info_table[idx].codec = -1; - audpp->dec_info_table[idx].pid = 0; - MM_INFO("module_name:%s\n", - audpp->dec_database->dec_info_list[idx].module_name); - MM_INFO("queueid:%d\n", - audpp->dec_database->dec_info_list[idx].module_queueid); - MM_INFO("decid:%d\n", - audpp->dec_database->dec_info_list[idx].module_decid); - MM_INFO("nr_codec_support:%d\n", - audpp->dec_database->dec_info_list[idx]. - nr_codec_support); - } - - for (idx = 0; idx < audpp->dec_database->num_dec; idx++) { - rc = device_create_file(&pdev->dev, &dev_attr_decoder[idx]); - if (rc) - goto err; - } - rc = device_create_file(&pdev->dev, &dev_attr_concurrency); - if (rc) - goto err; - else - goto done; -err: - while (idx--) - device_remove_file(&pdev->dev, &dev_attr_decoder[idx]); -done: - return rc; -} - -static struct platform_driver audpp_plat_driver = { - .probe = audpp_probe, - .driver = { - .name = "msm_adspdec", - .owner = THIS_MODULE, - }, -}; - -static int __init audpp_init(void) -{ - return platform_driver_register(&audpp_plat_driver); -} - -device_initcall(audpp_init); diff --git a/arch/arm/mach-msm/qdsp5/audpreproc.c b/arch/arm/mach-msm/qdsp5/audpreproc.c deleted file mode 100644 index 3dfa17963d69c142cddcd9b0c6e7fd9ed024ad9c..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audpreproc.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Common code to deal with the AUDPREPROC dsp task (audio preprocessing) - * - * Copyright (c) 2011, The Linux Foundation. All rights reserved. - * - * Based on the audpp layer in arch/arm/mach-msm/qdsp5/audpp.c - * - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - */ - -#include -#include -#include -#include -#include -#include - -static DEFINE_MUTEX(audpreproc_lock); - -struct msm_adspenc_info { - const char *module_name; - unsigned module_queueids; - int module_encid; /* streamid */ - int enc_formats; /* supported formats */ - int nr_codec_support; /* number of codec suported */ -}; - -#define ENC_MODULE_INFO(name, queueids, encid, formats, nr_codec) \ - {.module_name = name, .module_queueids = queueids, \ - .module_encid = encid, .enc_formats = formats, \ - .nr_codec_support = nr_codec } - -#ifdef CONFIG_MSM7X27A_AUDIO -#define ENC0_FORMAT ((1<lock); - /* Represents in bit mask */ - mode = ((enc_type & AUDPREPROC_MODE_MASK) << 16); - codec = (1 << (enc_type & AUDPREPROC_CODEC_MASK)); - - lidx = msm_enc_database.num_enc; - min_codecs_supported = sizeof(unsigned int) * 8; - MM_DBG("mode = 0x%08x codec = 0x%08x\n", mode, codec); - - for (idx = lidx-1; idx >= 0; idx--) { - /* encoder free and supports the format */ - if (!(audpreproc->enc_inuse & (1 << (idx))) && - ((mode & msm_enc_database.enc_info_list[idx].enc_formats) - == mode) && ((codec & - msm_enc_database.enc_info_list[idx].enc_formats) - == codec)){ - /* Check supports minimum number codecs */ - codecs_supported = - msm_enc_database.enc_info_list[idx].nr_codec_support; - if (codecs_supported < min_codecs_supported) { - lidx = idx; - min_codecs_supported = codecs_supported; - } - } - } - - if (lidx < msm_enc_database.num_enc) { - audpreproc->enc_inuse |= (1 << lidx); - *module_name = - msm_enc_database.enc_info_list[lidx].module_name; - *queue_ids = - msm_enc_database.enc_info_list[lidx].module_queueids; - encid = msm_enc_database.enc_info_list[lidx].module_encid; - } - - mutex_unlock(audpreproc->lock); - return encid; -} -EXPORT_SYMBOL(audpreproc_aenc_alloc); - -void audpreproc_aenc_free(int enc_id) -{ - struct audpreproc_state *audpreproc = &the_audpreproc_state; - int idx; - - mutex_lock(audpreproc->lock); - for (idx = 0; idx < msm_enc_database.num_enc; idx++) { - if (msm_enc_database.enc_info_list[idx].module_encid == - enc_id) { - audpreproc->enc_inuse &= ~(1 << idx); - break; - } - } - mutex_unlock(audpreproc->lock); - return; - -} -EXPORT_SYMBOL(audpreproc_aenc_free); diff --git a/arch/arm/mach-msm/qdsp5/audrec.c b/arch/arm/mach-msm/qdsp5/audrec.c deleted file mode 100644 index 0f68e089fca89577ff26bccdd97811e80a07b68d..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/audrec.c +++ /dev/null @@ -1,272 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/audrec.c - * - * common code to deal with the AUDREC dsp task (audio recording) - * - * Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * Based on the audpp layer in arch/arm/mach-msm/qdsp5/audpp.c - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org. - * - */ - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include "audmgr.h" -#include - -static DEFINE_MUTEX(audrec_lock); - -#define MAX_ENC_COUNT 8 /* Max encoder supported */ - -#define ENC_SESSION_FREE 0 -#define ENC_SESSION_ACTIVE 1 - -struct enc_session { - unsigned enc_type; /* Param to identify type of encoder */ - unsigned audrec_obj_idx; /* Param to identify REC_OBJ or Session ID */ - audrec_event_func event_func; /* Event Call back - routine for the encoder */ - void *private; /* private data element passed as - part of Event Call back routine */ - unsigned state; /* Current state of the encoder session , - free, active*/ -}; - -struct audrec_state { - struct msm_adsp_module *audrec_mod; - struct enc_session enc_session[MAX_ENC_COUNT]; - struct mutex *lock; - unsigned enc_count; -}; - -struct audrec_state the_audrec_state = { - .lock = &audrec_lock, -}; - -int audrectask_send_cmdqueue(void *cmd, unsigned len) -{ - return msm_adsp_write(the_audrec_state.audrec_mod, - QDSP_uPAudRecCmdQueue, cmd, len); -} -EXPORT_SYMBOL(audrectask_send_cmdqueue); - -int audrectask_send_bitstreamqueue(void *cmd, unsigned len) -{ - return msm_adsp_write(the_audrec_state.audrec_mod, - QDSP_uPAudRecBitStreamQueue, cmd, len); -} -EXPORT_SYMBOL(audrectask_send_bitstreamqueue); - -static void audrectask_dsp_event(void *data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - struct audrec_state *audrec = data; - int cnt; - uint16_t msg[5]; /* Max size of message */ - getevent(msg, len); - - switch (id) { - case AUDREC_MSG_CMD_CFG_DONE_MSG: { - MM_DBG("CMD CFG DONE %x\n", msg[1]); - if (msg[0] & AUDREC_MSG_CFG_DONE_ENC_ENA) { - for (cnt = 0; cnt < MAX_ENC_COUNT ; cnt++) { - if (audrec->enc_session[cnt].enc_type == - (msg[0] & AUDREC_CMD_ENC_TYPE_MASK)) { - audrec->enc_session[cnt].audrec_obj_idx - = msg[1]; - audrec->enc_session[cnt].event_func( - audrec->enc_session[cnt].private, id, - msg); - break; - } - } - } else { - for (cnt = 0; cnt < MAX_ENC_COUNT ; cnt++) { - if (audrec->enc_session[cnt].enc_type == - (msg[0] & AUDREC_CMD_ENC_TYPE_MASK)) { - audrec->enc_session[cnt].event_func( - audrec->enc_session[cnt].private, id, - msg); - audrec->enc_session[cnt].audrec_obj_idx - = 0xFFFFFFFF; - audrec->enc_session[cnt].state - = ENC_SESSION_FREE; - audrec->enc_session[cnt].enc_type - = 0xFFFFFFFF; - audrec->enc_session[cnt].event_func - = NULL; - audrec->enc_session[cnt].private - = NULL; - break; - } - } - } - break; - } - case AUDREC_MSG_CMD_AREC_MEM_CFG_DONE_MSG: { - MM_DBG("CMD AREC MEM CFG DONE %x\n", msg[0]); - for (cnt = 0; cnt < MAX_ENC_COUNT ; cnt++) { - if (audrec->enc_session[cnt].audrec_obj_idx == - msg[0]) { - audrec->enc_session[cnt].event_func( - audrec->enc_session[cnt].private, id, msg); - break; - } - } - break; - } - case AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG: { - MM_DBG("CMD AREC PARAM CFG DONE %x\n", msg[0]); - for (cnt = 0; cnt < MAX_ENC_COUNT ; cnt++) { - if (audrec->enc_session[cnt].audrec_obj_idx == - msg[0]) { - audrec->enc_session[cnt].event_func( - audrec->enc_session[cnt].private, id, msg); - break; - } - } - break; - } - case AUDREC_MSG_PACKET_READY_MSG: { - MM_DBG("PCK READY %x\n", msg[0]); - for (cnt = 0; cnt < MAX_ENC_COUNT ; cnt++) { - if (audrec->enc_session[cnt].audrec_obj_idx == - msg[0]) { - audrec->enc_session[cnt].event_func( - audrec->enc_session[cnt].private, id, msg); - break; - } - } - break; - } - case AUDREC_MSG_FATAL_ERR_MSG: { - MM_ERR("ERROR %x\n", msg[0]); - if (msg[1] & AUDREC_MSG_FATAL_ERR_TYPE_0) { - for (cnt = 0; cnt < MAX_ENC_COUNT ; cnt++) { - if (audrec->enc_session[cnt].audrec_obj_idx == - msg[0]) { - audrec->enc_session[cnt].event_func( - audrec->enc_session[cnt].private, id, - msg); - break; - } - } - } else if (msg[1] & AUDREC_MSG_FATAL_ERR_TYPE_1) { - cnt = audrec->enc_count-1; - if (audrec->enc_session[cnt].event_func) - audrec->enc_session[cnt].event_func( - audrec->enc_session[cnt].private, id, - msg); - } - break; - } - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module \ - enable/disable(audrectask)\n"); - break; - default: - MM_ERR("unknown event %d\n", id); - } -} - -static struct msm_adsp_ops adsp_ops = { - .event = audrectask_dsp_event, -}; - -int audrectask_enable(unsigned enc_type, audrec_event_func func, void *private) -{ - struct audrec_state *audrec = &the_audrec_state; - int cnt, rc = 0; - - mutex_lock(audrec->lock); - - if (audrec->enc_count++ == 0) { - MM_DBG("enable\n"); - for (cnt = 0; cnt < MAX_ENC_COUNT ; cnt++) { - if (audrec->enc_session[cnt].state == - ENC_SESSION_FREE) { - audrec->enc_session[cnt].state = - ENC_SESSION_ACTIVE; - audrec->enc_session[cnt].enc_type = enc_type; - audrec->enc_session[cnt].event_func = func; - audrec->enc_session[cnt].private = private; - break; - } - } - rc = msm_adsp_get("AUDRECTASK", &audrec->audrec_mod, &adsp_ops, - audrec); - if (rc < 0) { - MM_ERR("cannot open AUDRECTASK\n"); - audrec->enc_count = 0; - audrec->enc_session[cnt].state = ENC_SESSION_FREE; - audrec->enc_session[cnt].enc_type = 0xFFFFFFFF; - audrec->enc_session[cnt].event_func = NULL; - audrec->enc_session[cnt].private = NULL; - goto out; - } - msm_adsp_enable(audrec->audrec_mod); - } else { - for (cnt = 0; cnt < MAX_ENC_COUNT ; cnt++) { - if (audrec->enc_session[cnt].state == - ENC_SESSION_FREE) { - audrec->enc_session[cnt].state = - ENC_SESSION_ACTIVE; - audrec->enc_session[cnt].enc_type = enc_type; - audrec->enc_session[cnt].event_func = func; - audrec->enc_session[cnt].private = private; - break; - } - } - } - if (cnt == MAX_ENC_COUNT) - rc = -EBUSY; - else - rc = 0; - -out: - mutex_unlock(audrec->lock); - return rc; -} -EXPORT_SYMBOL(audrectask_enable); - -void audrectask_disable(unsigned enc_type, void *private) -{ - struct audrec_state *audrec = &the_audrec_state; - - mutex_lock(audrec->lock); - - if (--audrec->enc_count == 0) { - MM_DBG("\n"); /* Macro prints the file name and function */ - msm_adsp_disable(audrec->audrec_mod); - msm_adsp_put(audrec->audrec_mod); - audrec->audrec_mod = NULL; - } - - mutex_unlock(audrec->lock); -} -EXPORT_SYMBOL(audrectask_disable); - diff --git a/arch/arm/mach-msm/qdsp5/dsp_debug.c b/arch/arm/mach-msm/qdsp5/dsp_debug.c deleted file mode 100644 index 6e73a60a5492f94d52e47979d002d02fb38434ea..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/dsp_debug.c +++ /dev/null @@ -1,235 +0,0 @@ -/* Copyright (c) 2011, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "dsp_debug.h" - -static wait_queue_head_t dsp_wait; -static int dsp_has_crashed; -static int dsp_wait_count; - -static atomic_t dsp_crash_count = ATOMIC_INIT(0); -static dsp_state_cb cb_ptr; - -#define MAX_LEN 64 -#define HDR_LEN 20 -#define NUM_DSP_RAM_BANKS 3 - -static char l_buf[MAX_LEN]; -#ifdef CONFIG_DEBUG_FS -static struct dentry *dsp_dentry; -#endif - -void q5audio_dsp_not_responding(void) -{ - if (cb_ptr) - cb_ptr(DSP_STATE_CRASHED); - - MM_DBG("entered q5audio_dsp_not_responding\n"); - if (atomic_add_return(1, &dsp_crash_count) != 1) { - MM_ERR("q5audio_dsp_not_responding() \ - - parking additional crasher...\n"); - for (;;) - msleep(1000); - } - if (dsp_wait_count) { - dsp_has_crashed = 1; - wake_up(&dsp_wait); - - while (dsp_has_crashed != 2) - wait_event(dsp_wait, dsp_has_crashed == 2); - } else { - MM_ERR("q5audio_dsp_not_responding() - no waiter?\n"); - } - - if (cb_ptr) - cb_ptr(DSP_STATE_CRASH_DUMP_DONE); -} - -static int dsp_open(struct inode *inode, struct file *file) -{ - return 0; -} - -static ssize_t dsp_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - char cmd[32]; - - if (count >= sizeof(cmd)) - return -EINVAL; - if (copy_from_user(cmd, buf, count)) - return -EFAULT; - cmd[count] = 0; - - if ((count > 1) && (cmd[count-1] == '\n')) - cmd[count-1] = 0; - - if (!strncmp(cmd, "wait-for-crash", sizeof("wait-for-crash"))) { - while (!dsp_has_crashed) { - int res; - dsp_wait_count++; - res = wait_event_interruptible(dsp_wait, - dsp_has_crashed); - if (res < 0) { - dsp_wait_count--; - return res; - } - } - } else if (!strncmp(cmd, "boom", sizeof("boom"))) { - q5audio_dsp_not_responding(); - } else if (!strncmp(cmd, "continue-crash", sizeof("continue-crash"))) { - dsp_has_crashed = 2; - wake_up(&dsp_wait); - } else { - MM_ERR("[%s:%s] unknown dsp_debug command: %s\n", __MM_FILE__, - __func__, cmd); - } - - return count; -} - -static ssize_t dsp_read(struct file *file, char __user *buf, - size_t count, loff_t *pos) -{ - size_t actual = 0; - static void *dsp_addr; - static unsigned copy_ok_count; - - MM_INFO("pos = %lld\n", *pos); - if (*pos >= DSP_RAM_SIZE * NUM_DSP_RAM_BANKS) - return 0; - - if (*pos == 0) - dsp_addr = (*pos + RAMA_BASE); - else if (*pos == DSP_RAM_SIZE) - dsp_addr = RAMB_BASE; - else if (*pos >= DSP_RAM_SIZE * 2) - dsp_addr = RAMC_BASE; - - MM_INFO("dsp_addr = %p\n", dsp_addr); - while (count >= PAGE_SIZE) { - if (copy_to_user(buf, dsp_addr, PAGE_SIZE)) { - MM_ERR("[%s:%s] copy error @ %p\n", __MM_FILE__, - __func__, buf); - return -EFAULT; - } - copy_ok_count += PAGE_SIZE; - dsp_addr = (char *)dsp_addr + PAGE_SIZE; - buf += PAGE_SIZE; - actual += PAGE_SIZE; - count -= PAGE_SIZE; - } - - *pos += actual; - return actual; -} - -static int dsp_release(struct inode *inode, struct file *file) -{ - return 0; -} - -int dsp_debug_register(dsp_state_cb ptr) -{ - if (ptr == NULL) - return -EINVAL; - - cb_ptr = ptr; - - return 0; -} - -static const struct file_operations dsp_fops = { - .owner = THIS_MODULE, - .open = dsp_open, - .read = dsp_read, - .write = dsp_write, - .release = dsp_release, -}; - -#ifdef CONFIG_DEBUG_FS -static struct miscdevice dsp_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "dsp_debug", - .fops = &dsp_fops, -}; -#endif - -static ssize_t dsp_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - MM_DBG("adsp debugfs opened\n"); - return 0; -} - -static ssize_t dsp_debug_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - int len; - - if (count < 0) - return 0; - len = count > (MAX_LEN - 1) ? (MAX_LEN - 1) : count; - if (copy_from_user(l_buf + HDR_LEN, buf, len)) { - MM_ERR("Unable to copy data from user space\n"); - return -EFAULT; - } - l_buf[len + HDR_LEN] = 0; - if (l_buf[len + HDR_LEN - 1] == '\n') { - l_buf[len + HDR_LEN - 1] = 0; - len--; - } - if (!strncmp(l_buf + HDR_LEN, "boom", 64)) { - q5audio_dsp_not_responding(); - } else if (!strncmp(l_buf + HDR_LEN, "continue-crash", - sizeof("continue-crash"))) { - dsp_has_crashed = 2; - wake_up(&dsp_wait); - } else - MM_ERR("Unknown command\n"); - - return count; -} -static const struct file_operations dsp_debug_fops = { - .write = dsp_debug_write, - .open = dsp_debug_open, -}; - -static int __init dsp_init(void) -{ - init_waitqueue_head(&dsp_wait); -#ifdef CONFIG_DEBUG_FS - dsp_dentry = debugfs_create_file("dsp_debug", S_IFREG | S_IRUGO, - NULL, (void *) NULL, &dsp_debug_fops); - - return misc_register(&dsp_misc); -#else - return 0; -#endif /* CONFIG_DEBUG_FS */ -} - -device_initcall(dsp_init); diff --git a/arch/arm/mach-msm/qdsp5/dsp_debug.h b/arch/arm/mach-msm/qdsp5/dsp_debug.h deleted file mode 100644 index 15c14caf202917acc98af8a8b637c6be81efceca..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/dsp_debug.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright (c) 2011, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __DSP_DEBUG_H_ -#define __DSP_DEBUG_H_ - -typedef int (*dsp_state_cb)(int state); -int dsp_debug_register(dsp_state_cb ptr); - -#define DSP_STATE_CRASHED 0x0 -#define DSP_STATE_CRASH_DUMP_DONE 0x1 - -#define RAMA_BASE MSM_AD5_BASE -#define RAMB_BASE ((RAMA_BASE) + (0x200000)) -#define RAMC_BASE ((RAMB_BASE) + (0x200000)) -#define DSP_RAM_SIZE 0x40000 - -#endif diff --git a/arch/arm/mach-msm/qdsp5/evlog.h b/arch/arm/mach-msm/qdsp5/evlog.h deleted file mode 100644 index 1f0f16bada258301a5e5619ba626f953b3abb8c3..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/evlog.h +++ /dev/null @@ -1,125 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/evlog.h - * - * simple event log debugging facility - * - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include - -#define EV_LOG_ENTRY_NAME(n) n##_entry - -#define DECLARE_LOG(_name, _size, _str) \ -static struct ev_entry EV_LOG_ENTRY_NAME(_name)[_size]; \ -static struct ev_log _name = { \ - .name = #_name, \ - .strings = _str, \ - .num_strings = ARRAY_SIZE(_str), \ - .entry = EV_LOG_ENTRY_NAME(_name), \ - .max = ARRAY_SIZE(EV_LOG_ENTRY_NAME(_name)), \ -} - -struct ev_entry { - struct timespec when; - uint32_t id; - uint32_t arg; -}; - -struct ev_log { - struct ev_entry *entry; - unsigned max; - unsigned next; - unsigned fault; - const char **strings; - unsigned num_strings; - const char *name; -}; - -static char ev_buf[4096]; - -static ssize_t ev_log_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - struct ev_log *log = file->private_data; - struct ev_entry *entry; - unsigned long flags; - int size = 0; - unsigned n, id, max; - struct timespec now, t; - - max = log->max; - getnstimeofday(&now); - local_irq_save(flags); - n = (log->next - 1) & (max - 1); - entry = log->entry; - while (n != log->next) { - t = timespec_sub(now, entry[n].when); - id = entry[n].id; - if (id) { - const char *str; - if (id < log->num_strings) - str = log->strings[id]; - else - str = "UNKNOWN"; - size += scnprintf(ev_buf + size, 4096 - size, - "%lu.%03lu %08x %s\n", - t.tv_sec, t.tv_nsec / 1000000, - entry[n].arg, str); - } - n = (n - 1) & (max - 1); - } - log->fault = 0; - local_irq_restore(flags); - return simple_read_from_buffer(buf, count, ppos, ev_buf, size); -} - -static void ev_log_write(struct ev_log *log, unsigned id, unsigned arg) -{ - struct ev_entry *entry; - unsigned long flags; - local_irq_save(flags); - - if (log->fault) { - if (log->fault == 1) - goto done; - log->fault--; - } - - entry = log->entry + log->next; - getnstimeofday(&entry->when); - entry->id = id; - entry->arg = arg; - log->next = (log->next + 1) & (log->max - 1); -done: - local_irq_restore(flags); -} - -static int ev_log_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static const struct file_operations ev_log_ops = { - .read = ev_log_read, - .open = ev_log_open, -}; - -static int ev_log_init(struct ev_log *log) -{ - debugfs_create_file(log->name, 0444, 0, log, &ev_log_ops); - return 0; -} - diff --git a/arch/arm/mach-msm/qdsp5/snd.c b/arch/arm/mach-msm/qdsp5/snd.c deleted file mode 100644 index 3f379dcd27030569ce6b79a2b85ce7a506ec03eb..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/snd.c +++ /dev/null @@ -1,675 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/snd.c - * - * interface to "snd" service on the baseband cpu - * - * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct snd_ctxt { - struct mutex lock; - int opened; - struct msm_rpc_endpoint *ept; - struct msm_snd_endpoints *snd_epts; -}; - -struct snd_sys_ctxt { - struct mutex lock; - struct msm_rpc_endpoint *ept; -}; - -static struct snd_sys_ctxt the_snd_sys; - -static struct snd_ctxt the_snd; - -#define RPC_SND_PROG 0x30000002 -#define RPC_SND_CB_PROG 0x31000002 - -#define RPC_SND_VERS 0x00020001 -#define RPC_SND_VERS2 0x00030001 - -#define SND_SET_DEVICE_PROC 2 -#define SND_SET_VOLUME_PROC 3 -#define SND_AVC_CTL_PROC 29 -#define SND_AGC_CTL_PROC 30 - -struct rpc_snd_set_device_args { - uint32_t device; - uint32_t ear_mute; - uint32_t mic_mute; - - uint32_t cb_func; - uint32_t client_data; -}; - -struct rpc_snd_set_volume_args { - uint32_t device; - uint32_t method; - uint32_t volume; - - uint32_t cb_func; - uint32_t client_data; -}; - -struct rpc_snd_avc_ctl_args { - uint32_t avc_ctl; - uint32_t cb_func; - uint32_t client_data; -}; - -struct rpc_snd_agc_ctl_args { - uint32_t agc_ctl; - uint32_t cb_func; - uint32_t client_data; -}; - -struct snd_set_device_msg { - struct rpc_request_hdr hdr; - struct rpc_snd_set_device_args args; -}; - -struct snd_set_volume_msg { - struct rpc_request_hdr hdr; - struct rpc_snd_set_volume_args args; -}; - -struct snd_avc_ctl_msg { - struct rpc_request_hdr hdr; - struct rpc_snd_avc_ctl_args args; -}; - -struct snd_agc_ctl_msg { - struct rpc_request_hdr hdr; - struct rpc_snd_agc_ctl_args args; -}; - -struct snd_endpoint *get_snd_endpoints(int *size); - -static inline int check_mute(int mute) -{ - return (mute == SND_MUTE_MUTED || - mute == SND_MUTE_UNMUTED) ? 0 : -EINVAL; -} - -static int get_endpoint(struct snd_ctxt *snd, unsigned long arg) -{ - int rc = 0, index; - struct msm_snd_endpoint ept; - - if (copy_from_user(&ept, (void __user *)arg, sizeof(ept))) { - MM_ERR("snd_ioctl get endpoint: invalid read pointer\n"); - return -EFAULT; - } - - index = ept.id; - if (index < 0 || index >= snd->snd_epts->num) { - MM_ERR("snd_ioctl get endpoint: invalid index!\n"); - return -EINVAL; - } - - ept.id = snd->snd_epts->endpoints[index].id; - strncpy(ept.name, - snd->snd_epts->endpoints[index].name, - sizeof(ept.name)); - - if (copy_to_user((void __user *)arg, &ept, sizeof(ept))) { - MM_ERR("snd_ioctl get endpoint: invalid write pointer\n"); - rc = -EFAULT; - } - - return rc; -} - -static long snd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct snd_set_device_msg dmsg; - struct snd_set_volume_msg vmsg; - struct snd_avc_ctl_msg avc_msg; - struct snd_agc_ctl_msg agc_msg; - - struct msm_snd_device_config dev; - struct msm_snd_volume_config vol; - struct snd_ctxt *snd = file->private_data; - int rc = 0; - - uint32_t avc, agc; - - mutex_lock(&snd->lock); - switch (cmd) { - case SND_SET_DEVICE: - if (copy_from_user(&dev, (void __user *) arg, sizeof(dev))) { - MM_ERR("set device: invalid pointer\n"); - rc = -EFAULT; - break; - } - - dmsg.args.device = cpu_to_be32(dev.device); - dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute); - dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute); - if (check_mute(dev.ear_mute) < 0 || - check_mute(dev.mic_mute) < 0) { - MM_ERR("set device: invalid mute status\n"); - rc = -EINVAL; - break; - } - dmsg.args.cb_func = -1; - dmsg.args.client_data = 0; - - MM_INFO("snd_set_device %d %d %d\n", dev.device, - dev.ear_mute, dev.mic_mute); - - rc = msm_rpc_call(snd->ept, - SND_SET_DEVICE_PROC, - &dmsg, sizeof(dmsg), 5 * HZ); - break; - - case SND_SET_VOLUME: - if (copy_from_user(&vol, (void __user *) arg, sizeof(vol))) { - MM_ERR("set volume: invalid pointer\n"); - rc = -EFAULT; - break; - } - - vmsg.args.device = cpu_to_be32(vol.device); - vmsg.args.method = cpu_to_be32(vol.method); - if (vol.method != SND_METHOD_VOICE) { - MM_ERR("set volume: invalid method\n"); - rc = -EINVAL; - break; - } - - vmsg.args.volume = cpu_to_be32(vol.volume); - vmsg.args.cb_func = -1; - vmsg.args.client_data = 0; - - MM_INFO("snd_set_volume %d %d %d\n", vol.device, - vol.method, vol.volume); - - rc = msm_rpc_call(snd->ept, - SND_SET_VOLUME_PROC, - &vmsg, sizeof(vmsg), 5 * HZ); - break; - - case SND_AVC_CTL: - if (get_user(avc, (uint32_t __user *) arg)) { - rc = -EFAULT; - break; - } else if ((avc != 1) && (avc != 0)) { - rc = -EINVAL; - break; - } - - avc_msg.args.avc_ctl = cpu_to_be32(avc); - avc_msg.args.cb_func = -1; - avc_msg.args.client_data = 0; - - MM_INFO("snd_avc_ctl %d\n", avc); - - rc = msm_rpc_call(snd->ept, - SND_AVC_CTL_PROC, - &avc_msg, sizeof(avc_msg), 5 * HZ); - break; - - case SND_AGC_CTL: - if (get_user(agc, (uint32_t __user *) arg)) { - rc = -EFAULT; - break; - } else if ((agc != 1) && (agc != 0)) { - rc = -EINVAL; - break; - } - agc_msg.args.agc_ctl = cpu_to_be32(agc); - agc_msg.args.cb_func = -1; - agc_msg.args.client_data = 0; - - MM_INFO("snd_agc_ctl %d\n", agc); - - rc = msm_rpc_call(snd->ept, - SND_AGC_CTL_PROC, - &agc_msg, sizeof(agc_msg), 5 * HZ); - break; - - case SND_GET_NUM_ENDPOINTS: - if (copy_to_user((void __user *)arg, - &snd->snd_epts->num, sizeof(unsigned))) { - MM_ERR("get endpoint: invalid pointer\n"); - rc = -EFAULT; - } - break; - - case SND_GET_ENDPOINT: - rc = get_endpoint(snd, arg); - break; - - default: - MM_ERR("unknown command\n"); - rc = -EINVAL; - break; - } - mutex_unlock(&snd->lock); - - return rc; -} - -static int snd_release(struct inode *inode, struct file *file) -{ - struct snd_ctxt *snd = file->private_data; - int rc; - - mutex_lock(&snd->lock); - rc = msm_rpc_close(snd->ept); - if (rc < 0) - MM_ERR("msm_rpc_close failed\n"); - snd->ept = NULL; - snd->opened = 0; - mutex_unlock(&snd->lock); - return 0; -} -static int snd_sys_release(void) -{ - struct snd_sys_ctxt *snd_sys = &the_snd_sys; - int rc = 0; - - mutex_lock(&snd_sys->lock); - rc = msm_rpc_close(snd_sys->ept); - if (rc < 0) - MM_ERR("msm_rpc_close failed\n"); - snd_sys->ept = NULL; - mutex_unlock(&snd_sys->lock); - return rc; -} -static int snd_open(struct inode *inode, struct file *file) -{ - struct snd_ctxt *snd = &the_snd; - int rc = 0; - - mutex_lock(&snd->lock); - if (snd->opened == 0) { - if (snd->ept == NULL) { - snd->ept = msm_rpc_connect_compatible(RPC_SND_PROG, - RPC_SND_VERS, 0); - if (IS_ERR(snd->ept)) { - MM_DBG("connect failed with current VERS \ - = %x, trying again with another API\n", - RPC_SND_VERS2); - snd->ept = - msm_rpc_connect_compatible(RPC_SND_PROG, - RPC_SND_VERS2, 0); - } - if (IS_ERR(snd->ept)) { - rc = PTR_ERR(snd->ept); - snd->ept = NULL; - MM_ERR("failed to connect snd svc\n"); - goto err; - } - } - file->private_data = snd; - snd->opened = 1; - } else { - MM_ERR("snd already opened\n"); - rc = -EBUSY; - } - -err: - mutex_unlock(&snd->lock); - return rc; -} -static int snd_sys_open(void) -{ - struct snd_sys_ctxt *snd_sys = &the_snd_sys; - int rc = 0; - - mutex_lock(&snd_sys->lock); - if (snd_sys->ept == NULL) { - snd_sys->ept = msm_rpc_connect_compatible(RPC_SND_PROG, - RPC_SND_VERS, 0); - if (IS_ERR(snd_sys->ept)) { - MM_DBG("connect failed with current VERS \ - = %x, trying again with another API\n", - RPC_SND_VERS2); - snd_sys->ept = msm_rpc_connect_compatible(RPC_SND_PROG, - RPC_SND_VERS2, 0); - } - if (IS_ERR(snd_sys->ept)) { - rc = PTR_ERR(snd_sys->ept); - snd_sys->ept = NULL; - MM_ERR("failed to connect snd svc\n"); - goto err; - } - } else - MM_DBG("snd already opened\n"); - -err: - mutex_unlock(&snd_sys->lock); - return rc; -} - -static struct file_operations snd_fops = { - .owner = THIS_MODULE, - .open = snd_open, - .release = snd_release, - .unlocked_ioctl = snd_ioctl, -}; - -struct miscdevice snd_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_snd", - .fops = &snd_fops, -}; - -static long snd_agc_enable(unsigned long arg) -{ - struct snd_sys_ctxt *snd_sys = &the_snd_sys; - struct snd_agc_ctl_msg agc_msg; - int rc = 0; - - if ((arg != 1) && (arg != 0)) - return -EINVAL; - - agc_msg.args.agc_ctl = cpu_to_be32(arg); - agc_msg.args.cb_func = -1; - agc_msg.args.client_data = 0; - - MM_DBG("snd_agc_ctl %ld,%d\n", arg, agc_msg.args.agc_ctl); - - rc = msm_rpc_call(snd_sys->ept, - SND_AGC_CTL_PROC, - &agc_msg, sizeof(agc_msg), 5 * HZ); - return rc; -} - -static long snd_avc_enable(unsigned long arg) -{ - struct snd_sys_ctxt *snd_sys = &the_snd_sys; - struct snd_avc_ctl_msg avc_msg; - int rc = 0; - - if ((arg != 1) && (arg != 0)) - return -EINVAL; - - avc_msg.args.avc_ctl = cpu_to_be32(arg); - - avc_msg.args.cb_func = -1; - avc_msg.args.client_data = 0; - - MM_DBG("snd_avc_ctl %ld,%d\n", arg, avc_msg.args.avc_ctl); - - rc = msm_rpc_call(snd_sys->ept, - SND_AVC_CTL_PROC, - &avc_msg, sizeof(avc_msg), 5 * HZ); - return rc; -} - -static ssize_t snd_agc_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - ssize_t status; - struct snd_sys_ctxt *snd_sys = &the_snd_sys; - int rc = 0; - - rc = snd_sys_open(); - if (rc) - return rc; - - mutex_lock(&snd_sys->lock); - - if (sysfs_streq(buf, "enable")) - status = snd_agc_enable(1); - else if (sysfs_streq(buf, "disable")) - status = snd_agc_enable(0); - else - status = -EINVAL; - - mutex_unlock(&snd_sys->lock); - rc = snd_sys_release(); - if (rc) - return rc; - - return status ? : size; -} - -static ssize_t snd_avc_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - ssize_t status; - struct snd_sys_ctxt *snd_sys = &the_snd_sys; - int rc = 0; - - rc = snd_sys_open(); - if (rc) - return rc; - - mutex_lock(&snd_sys->lock); - - if (sysfs_streq(buf, "enable")) - status = snd_avc_enable(1); - else if (sysfs_streq(buf, "disable")) - status = snd_avc_enable(0); - else - status = -EINVAL; - - mutex_unlock(&snd_sys->lock); - rc = snd_sys_release(); - if (rc) - return rc; - - return status ? : size; -} - -static long snd_vol_enable(const char *arg) -{ - struct snd_sys_ctxt *snd_sys = &the_snd_sys; - struct snd_set_volume_msg vmsg; - struct msm_snd_volume_config vol; - int rc = 0; - - rc = sscanf(arg, "%d %d %d", &vol.device, &vol.method, &vol.volume); - if (rc != 3) { - MM_ERR("Invalid arguments. Usage: \ - \n"); - rc = -EINVAL; - return rc; - } - - vmsg.args.device = cpu_to_be32(vol.device); - vmsg.args.method = cpu_to_be32(vol.method); - if (vol.method != SND_METHOD_VOICE) { - MM_ERR("snd_ioctl set volume: invalid method\n"); - rc = -EINVAL; - return rc; - } - - vmsg.args.volume = cpu_to_be32(vol.volume); - vmsg.args.cb_func = -1; - vmsg.args.client_data = 0; - - MM_DBG("snd_set_volume %d %d %d\n", vol.device, vol.method, - vol.volume); - - rc = msm_rpc_call(snd_sys->ept, - SND_SET_VOLUME_PROC, - &vmsg, sizeof(vmsg), 5 * HZ); - return rc; -} - -static long snd_dev_enable(const char *arg) -{ - struct snd_sys_ctxt *snd_sys = &the_snd_sys; - struct snd_set_device_msg dmsg; - struct msm_snd_device_config dev; - int rc = 0; - - rc = sscanf(arg, "%d %d %d", &dev.device, &dev.ear_mute, &dev.mic_mute); - if (rc != 3) { - MM_ERR("Invalid arguments. Usage: \ - \n"); - rc = -EINVAL; - return rc; - } - dmsg.args.device = cpu_to_be32(dev.device); - dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute); - dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute); - if (check_mute(dev.ear_mute) < 0 || - check_mute(dev.mic_mute) < 0) { - MM_ERR("snd_ioctl set device: invalid mute status\n"); - rc = -EINVAL; - return rc; - } - dmsg.args.cb_func = -1; - dmsg.args.client_data = 0; - - MM_INFO("snd_set_device %d %d %d\n", dev.device, dev.ear_mute, - dev.mic_mute); - - rc = msm_rpc_call(snd_sys->ept, - SND_SET_DEVICE_PROC, - &dmsg, sizeof(dmsg), 5 * HZ); - return rc; -} - -static ssize_t snd_dev_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - ssize_t status; - struct snd_sys_ctxt *snd_sys = &the_snd_sys; - int rc = 0; - - rc = snd_sys_open(); - if (rc) - return rc; - - mutex_lock(&snd_sys->lock); - status = snd_dev_enable(buf); - mutex_unlock(&snd_sys->lock); - - rc = snd_sys_release(); - if (rc) - return rc; - - return status ? : size; -} - -static ssize_t snd_vol_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - ssize_t status; - struct snd_sys_ctxt *snd_sys = &the_snd_sys; - int rc = 0; - - rc = snd_sys_open(); - if (rc) - return rc; - - mutex_lock(&snd_sys->lock); - status = snd_vol_enable(buf); - mutex_unlock(&snd_sys->lock); - - rc = snd_sys_release(); - if (rc) - return rc; - - return status ? : size; -} - -static DEVICE_ATTR(agc, S_IWUSR | S_IRUGO, - NULL, snd_agc_store); - -static DEVICE_ATTR(avc, S_IWUSR | S_IRUGO, - NULL, snd_avc_store); - -static DEVICE_ATTR(device, S_IWUSR | S_IRUGO, - NULL, snd_dev_store); - -static DEVICE_ATTR(volume, S_IWUSR | S_IRUGO, - NULL, snd_vol_store); - -static int snd_probe(struct platform_device *pdev) -{ - struct snd_ctxt *snd = &the_snd; - struct snd_sys_ctxt *snd_sys = &the_snd_sys; - int rc = 0; - - mutex_init(&snd->lock); - mutex_init(&snd_sys->lock); - snd_sys->ept = NULL; - snd->snd_epts = (struct msm_snd_endpoints *)pdev->dev.platform_data; - rc = misc_register(&snd_misc); - if (rc) - return rc; - - rc = device_create_file(snd_misc.this_device, &dev_attr_agc); - if (rc) { - misc_deregister(&snd_misc); - return rc; - } - - rc = device_create_file(snd_misc.this_device, &dev_attr_avc); - if (rc) { - device_remove_file(snd_misc.this_device, - &dev_attr_agc); - misc_deregister(&snd_misc); - return rc; - } - - rc = device_create_file(snd_misc.this_device, &dev_attr_device); - if (rc) { - device_remove_file(snd_misc.this_device, - &dev_attr_agc); - device_remove_file(snd_misc.this_device, - &dev_attr_avc); - misc_deregister(&snd_misc); - return rc; - } - - rc = device_create_file(snd_misc.this_device, &dev_attr_volume); - if (rc) { - device_remove_file(snd_misc.this_device, - &dev_attr_agc); - device_remove_file(snd_misc.this_device, - &dev_attr_avc); - device_remove_file(snd_misc.this_device, - &dev_attr_device); - misc_deregister(&snd_misc); - } - - return rc; -} - -static struct platform_driver snd_plat_driver = { - .probe = snd_probe, - .driver = { - .name = "msm_snd", - .owner = THIS_MODULE, - }, -}; - -static int __init snd_init(void) -{ - return platform_driver_register(&snd_plat_driver); -} - -module_init(snd_init); diff --git a/arch/arm/mach-msm/qdsp5/snd_adie.c b/arch/arm/mach-msm/qdsp5/snd_adie.c deleted file mode 100644 index 160ed93c2e33399c03a85425b499423403f7f88a..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/snd_adie.c +++ /dev/null @@ -1,480 +0,0 @@ -/* Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct adie_svc_client adie_client[ADIE_SVC_MAX_CLIENTS]; -static DEFINE_MUTEX(adie_client_lock); - -static int adie_svc_process_cb(struct msm_rpc_client *client, - void *buffer, int in_size) -{ - int rc, id; - uint32_t accept_status; - struct rpc_request_hdr *req; - struct adie_svc_client_register_cb_cb_args arg, *buf_ptr; - - req = (struct rpc_request_hdr *)buffer; - for (id = 0; id < ADIE_SVC_MAX_CLIENTS; id++) { - if (adie_client[id].rpc_client == client) - break; - } - if (id == ADIE_SVC_MAX_CLIENTS) { - MM_ERR("RPC reply with invalid rpc client\n"); - accept_status = RPC_ACCEPTSTAT_SYSTEM_ERR; - goto err; - } - - buf_ptr = (struct adie_svc_client_register_cb_cb_args *)(req + 1); - arg.cb_id = be32_to_cpu(buf_ptr->cb_id); - arg.size = be32_to_cpu(buf_ptr->size); - arg.client_id = be32_to_cpu(buf_ptr->client_id); - arg.adie_block = be32_to_cpu(buf_ptr->adie_block); - arg.status = be32_to_cpu(buf_ptr->status); - arg.client_operation = be32_to_cpu(buf_ptr->client_operation); - - if (arg.cb_id != adie_client[id].cb_id) { - MM_ERR("RPC reply with invalid invalid cb_id\n"); - accept_status = RPC_ACCEPTSTAT_SYSTEM_ERR; - goto err; - } - - mutex_lock(&adie_client[id].lock); - switch (arg.client_operation) { - case ADIE_SVC_REGISTER_CLIENT: - MM_DBG("ADIE_SVC_REGISTER_CLIENT callback\n"); - adie_client[id].client_id = arg.client_id; - break; - case ADIE_SVC_DEREGISTER_CLIENT: - MM_DBG("ADIE_SVC_DEREGISTER_CLIENT callback\n"); - break; - case ADIE_SVC_CONFIG_ADIE_BLOCK: - MM_DBG("ADIE_SVC_CONFIG_ADIE_BLOCK callback\n"); - if (adie_client[id].client_id != arg.client_id) { - mutex_unlock(&adie_client[id].lock); - accept_status = RPC_ACCEPTSTAT_SYSTEM_ERR; - goto err; - } - break; - default: - accept_status = RPC_ACCEPTSTAT_SYSTEM_ERR; - goto err; - } - - adie_client[id].status = arg.status; - adie_client[id].adie_svc_cb_done = 1; - mutex_unlock(&adie_client[id].lock); - wake_up(&adie_client[id].wq); - accept_status = RPC_ACCEPTSTAT_SUCCESS; - -err: - msm_rpc_start_accepted_reply(client, be32_to_cpu(req->xid), - accept_status); - rc = msm_rpc_send_accepted_reply(client, 0); - if (rc) - MM_ERR("%s: send accepted reply failed: %d\n", __func__, rc); - - return rc; -} - -static int adie_svc_rpc_cb_func(struct msm_rpc_client *client, - void *buffer, int in_size) -{ - int rc = 0; - struct rpc_request_hdr *req; - - req = (struct rpc_request_hdr *)buffer; - - MM_DBG("procedure received to rpc cb %d\n", - be32_to_cpu(req->procedure)); - switch (be32_to_cpu(req->procedure)) { - case ADIE_SVC_CLIENT_STATUS_FUNC_PTR_TYPE_PROC: - rc = adie_svc_process_cb(client, buffer, in_size); - break; - default: - MM_ERR("%s: procedure not supported %d\n", __func__, - be32_to_cpu(req->procedure)); - msm_rpc_start_accepted_reply(client, be32_to_cpu(req->xid), - RPC_ACCEPTSTAT_PROC_UNAVAIL); - rc = msm_rpc_send_accepted_reply(client, 0); - if (rc) - MM_ERR("%s: sending reply failed: %d\n", __func__, rc); - break; - } - return rc; -} - -static int adie_svc_client_register_arg(struct msm_rpc_client *client, - void *buf, void *data) -{ - struct adie_svc_client_register_cb_args *arg; - - arg = (struct adie_svc_client_register_cb_args *)data; - - *((int *)buf) = cpu_to_be32((int)arg->cb_id); - return sizeof(int); -} - -static int adie_svc_client_deregister_arg(struct msm_rpc_client *client, - void *buf, void *data) -{ - struct adie_svc_client_deregister_cb_args *arg; - - arg = (struct adie_svc_client_deregister_cb_args *)data; - - *((int *)buf) = cpu_to_be32(arg->client_id); - return sizeof(int); -} - -static int adie_svc_config_adie_block_arg(struct msm_rpc_client *client, - void *buf, void *data) -{ - struct adie_svc_config_adie_block_cb_args *arg; - int size = 0; - - arg = (struct adie_svc_config_adie_block_cb_args *)data; - - *((int *)buf) = cpu_to_be32(arg->client_id); - size += sizeof(int); - buf += sizeof(int); - - *((int *)buf) = cpu_to_be32(arg->adie_block); - size += sizeof(int); - buf += sizeof(int); - - *((int *)buf) = cpu_to_be32(arg->config); - size += sizeof(int); - - return size; -} - -/* Returns : client id on success - * and -1 on failure - */ -int adie_svc_get(void) -{ - int id, rc = 0; - struct adie_svc_client_register_cb_args arg; - - mutex_lock(&adie_client_lock); - for (id = 0; id < ADIE_SVC_MAX_CLIENTS; id++) { - if (adie_client[id].client_id == -1 && - adie_client[id].rpc_client == NULL) - break; - } - if (id == ADIE_SVC_MAX_CLIENTS) { - mutex_unlock(&adie_client_lock); - return -1; - } - - mutex_lock(&adie_client[id].lock); - adie_client[id].rpc_client = msm_rpc_register_client("adie_client", - ADIE_SVC_PROG, - ADIE_SVC_VERS, 1, - adie_svc_rpc_cb_func); - if (IS_ERR(adie_client[id].rpc_client)) { - MM_ERR("Failed to register RPC client\n"); - adie_client[id].rpc_client = NULL; - mutex_unlock(&adie_client[id].lock); - mutex_unlock(&adie_client_lock); - return -1; - } - mutex_unlock(&adie_client_lock); - - adie_client[id].adie_svc_cb_done = 0; - arg.cb_id = id; - adie_client[id].cb_id = arg.cb_id; - mutex_unlock(&adie_client[id].lock); - rc = msm_rpc_client_req(adie_client[id].rpc_client, - SND_ADIE_SVC_CLIENT_REGISTER_PROC, - adie_svc_client_register_arg, &arg, - NULL, NULL, -1); - if (!rc) { - rc = wait_event_interruptible(adie_client[id].wq, - adie_client[id].adie_svc_cb_done); - mutex_lock(&adie_client[id].lock); - if (unlikely(rc < 0)) { - if (rc == -ERESTARTSYS) - MM_ERR("wait_event_interruptible " - "returned -ERESTARTSYS\n"); - else - MM_ERR("wait_event_interruptible " - "returned error\n"); - rc = -1; - goto err; - } - MM_DBG("Status %d received from CB function, id %d rc %d\n", - adie_client[id].status, adie_client[id].client_id, rc); - rc = id; - if (adie_client[id].status == ADIE_SVC_STATUS_FAILURE) { - MM_ERR("Received failed status for register request\n"); - rc = -1; - } else - goto done; - } else { - MM_ERR("Failed to send register client request\n"); - rc = -1; - mutex_lock(&adie_client[id].lock); - } -err: - msm_rpc_unregister_client(adie_client[id].rpc_client); - adie_client[id].rpc_client = NULL; - adie_client[id].client_id = -1; - adie_client[id].cb_id = MSM_RPC_CLIENT_NULL_CB_ID; - adie_client[id].adie_svc_cb_done = 0; -done: - mutex_unlock(&adie_client[id].lock); - return rc; -} -EXPORT_SYMBOL(adie_svc_get); - -/* Returns: 0 on succes and - * -1 on failure - */ -int adie_svc_put(int id) -{ - int rc = 0; - struct adie_svc_client_deregister_cb_args arg; - - if (id < 0 || id >= ADIE_SVC_MAX_CLIENTS) - return -1; - - mutex_lock(&adie_client[id].lock); - if (adie_client[id].client_id == -1 || - adie_client[id].rpc_client == NULL) { - mutex_unlock(&adie_client[id].lock); - return -1; - } - arg.client_id = adie_client[id].client_id; - adie_client[id].adie_svc_cb_done = 0; - mutex_unlock(&adie_client[id].lock); - rc = msm_rpc_client_req(adie_client[id].rpc_client, - SND_ADIE_SVC_CLIENT_DEREGISTER_PROC, - adie_svc_client_deregister_arg, &arg, - NULL, NULL, -1); - if (!rc) { - rc = wait_event_interruptible(adie_client[id].wq, - adie_client[id].adie_svc_cb_done); - if (unlikely(rc < 0)) { - if (rc == -ERESTARTSYS) - MM_ERR("wait_event_interruptible " - "returned -ERESTARTSYS\n"); - else - MM_ERR("wait_event_interruptible " - "returned error\n"); - rc = -1; - goto err; - } - MM_DBG("Status received from CB function\n"); - mutex_lock(&adie_client[id].lock); - if (adie_client[id].status == ADIE_SVC_STATUS_FAILURE) { - rc = -1; - } else { - msm_rpc_unregister_client(adie_client[id].rpc_client); - adie_client[id].rpc_client = NULL; - adie_client[id].client_id = -1; - adie_client[id].cb_id = MSM_RPC_CLIENT_NULL_CB_ID; - adie_client[id].adie_svc_cb_done = 0; - } - mutex_unlock(&adie_client[id].lock); - } else { - MM_ERR("Failed to send deregister client request\n"); - rc = -1; - } -err: - return rc; -} -EXPORT_SYMBOL(adie_svc_put); - -/* Returns: 0 on success - * 2 already in use - * -1 on failure - */ -int adie_svc_config_adie_block(int id, - enum adie_block_enum_type adie_block_type, bool enable) -{ - int rc = 0; - struct adie_svc_config_adie_block_cb_args arg; - - if (id < 0 || id >= ADIE_SVC_MAX_CLIENTS) - return -1; - - mutex_lock(&adie_client[id].lock); - if (adie_client[id].client_id == -1 || - adie_client[id].rpc_client == NULL) { - mutex_unlock(&adie_client[id].lock); - return -1; - } - arg.client_id = adie_client[id].client_id; - arg.adie_block = adie_block_type; - arg.config = (enum adie_config_enum_type)enable; - adie_client[id].adie_svc_cb_done = 0; - mutex_unlock(&adie_client[id].lock); - rc = msm_rpc_client_req(adie_client[id].rpc_client, - SND_ADIE_SVC_CONFIG_ADIE_BLOCK_PROC, - adie_svc_config_adie_block_arg, &arg, - NULL, NULL, -1); - if (!rc) { - rc = wait_event_interruptible(adie_client[id].wq, - adie_client[id].adie_svc_cb_done); - if (unlikely(rc < 0)) { - if (rc == -ERESTARTSYS) - MM_ERR("wait_event_interruptible " - "returned -ERESTARTSYS\n"); - else - MM_ERR("wait_event_interruptible " - "returned error\n"); - rc = -1; - goto err; - } - MM_DBG("Status received from CB function\n"); - mutex_lock(&adie_client[id].lock); - if (adie_client[id].status == ADIE_SVC_STATUS_FAILURE) - rc = -1; - else - rc = adie_client[id].status; - mutex_unlock(&adie_client[id].lock); - } else { - MM_ERR("Failed to send adie block config request\n"); - rc = -1; - } -err: - return rc; -} -EXPORT_SYMBOL(adie_svc_config_adie_block); - -#ifdef CONFIG_DEBUG_FS - -struct dentry *dentry; - -static ssize_t snd_adie_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t snd_adie_debug_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - int rc = 0, op = 0; - int id = 0, adie_block = 0, config = 1; - - sscanf(buf, "%d %d %d %d", &op, &id, &adie_block, &config); - MM_INFO("\nUser input: op %d id %d block %d config %d\n", op, id, - adie_block, config); - switch (op) { - case ADIE_SVC_REGISTER_CLIENT: - MM_INFO("ADIE_SVC_REGISTER_CLIENT\n"); - rc = adie_svc_get(); - if (rc >= 0) - MM_INFO("Client registered: %d\n", rc); - else - MM_ERR("Failed registering client\n"); - break; - case ADIE_SVC_DEREGISTER_CLIENT: - MM_INFO("ADIE_SVC_DEREGISTER_CLIENT: %d\n", id); - rc = adie_svc_put(id); - if (!rc) - MM_INFO("Client %d deregistered\n", id); - else - MM_ERR("Failed unregistering the client: %d\n", id); - break; - case ADIE_SVC_CONFIG_ADIE_BLOCK: - MM_INFO("ADIE_SVC_CONFIG_ADIE_BLOCK: id %d adie_block %d \ - config %d\n", id, adie_block, config); - rc = adie_svc_config_adie_block(id, - (enum adie_block_enum_type)adie_block, (bool)config); - if (!rc) - MM_INFO("ADIE block %d %s", adie_block, - config ? "enabled\n" : "disabled\n"); - else if (rc == 2) - MM_INFO("ADIE block %d already in use\n", adie_block); - else - MM_ERR("ERROR configuring the ADIE block\n"); - break; - default: - MM_INFO("Invalid operation\n"); - } - return count; -} - -static ssize_t snd_adie_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - static char buffer[1024]; - const int debug_bufmax = sizeof(buffer); - int id, n = 0; - - n += scnprintf(buffer + n, debug_bufmax - n, - "LIST OF CLIENTS\n"); - for (id = 0; id < ADIE_SVC_MAX_CLIENTS ; id++) { - if (adie_client[id].client_id != -1 && - adie_client[id].rpc_client != NULL) { - n += scnprintf(buffer + n, debug_bufmax - n, - "id %d rpc client 0x%08x\n", id, - (uint32_t)adie_client[id].rpc_client); - } - } - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations snd_adie_debug_fops = { - .read = snd_adie_debug_read, - .open = snd_adie_debug_open, - .write = snd_adie_debug_write, -}; -#endif - -static void __exit snd_adie_exit(void) -{ -#ifdef CONFIG_DEBUG_FS - if (dentry) - debugfs_remove(dentry); -#endif -} - -static int __init snd_adie_init(void) -{ - int id; -#ifdef CONFIG_DEBUG_FS - char name[sizeof "msm_snd_adie"]; - - snprintf(name, sizeof name, "msm_snd_adie"); - dentry = debugfs_create_file(name, S_IFREG | S_IRUGO | S_IWUGO, - NULL, NULL, &snd_adie_debug_fops); - if (IS_ERR(dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif - for (id = 0; id < ADIE_SVC_MAX_CLIENTS; id++) { - adie_client[id].client_id = -1; - adie_client[id].cb_id = MSM_RPC_CLIENT_NULL_CB_ID; - adie_client[id].status = 0; - adie_client[id].adie_svc_cb_done = 0; - mutex_init(&adie_client[id].lock); - init_waitqueue_head(&adie_client[id].wq); - adie_client[id].rpc_client = NULL; - } - return 0; -} - -module_init(snd_adie_init); -module_exit(snd_adie_exit); diff --git a/arch/arm/mach-msm/qdsp5/snd_pcm_client.c b/arch/arm/mach-msm/qdsp5/snd_pcm_client.c deleted file mode 100644 index 5c596017e473e83f76f9c2364022ae9a06106ada..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5/snd_pcm_client.c +++ /dev/null @@ -1,522 +0,0 @@ -/* Copyright (c) 2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SND_VOC_PCM_INTERFACE_PROG 0x30000002 -#define SND_VOC_PCM_INTERFACE_VERS 0x00020004 - -/* Supply always 160 words of PCM samples (20ms data) */ -#define MAX_VOC_FRAME_SIZE 160 -#define VOC_FRAME_DURATION 20 -/* Buffering for Maximum 8 frames between userspace and driver */ -#define MAX_VOC_FRAMES 8 -#define BUFSZ ((MAX_VOC_FRAME_SIZE*2)*MAX_VOC_FRAMES) -#define SND_VOC_PCM_CLIENT_INPUT_FN_TYPE_PROC 3 -#define SND_VOC_REGISTER_PCM_INPUT_CLIENT_PROC 24 - -#define START_CALLBACK_ID 0x12345678 -#define STOP_CALLBACK_ID 0xffffffff - -#define MAX_WAIT_CONSUME (MAX_VOC_FRAMES * VOC_FRAME_DURATION) -/* PCM Interfaces */ -enum voice_pcm_interface_type { - VOICE_PCM_INTERFACE_TX_INPUT = 3, /* PCM Inject input to PreProc */ -}; - -enum voice_pcm_interface_reg_status_type { - SUCCESS = 0, /* Success 0, else failure */ -}; - -/* status used by PCM input callbacks to indicate availability of PCM Data */ -enum voice_pcm_data_status_type { - VOICE_PCM_DATA_STATUS_AVAILABLE, /* Data available for PCM input */ - VOICE_PCM_DATA_STATUS_UNAVAILABLE, /* Data not available */ - VOICE_PCM_DATA_STATUS_MAX -}; - -/* Argument needed to register PCM input client */ -struct snd_voice_pcm_interface_ipclnt_reg_args { - /* Interface number specifies the PCM inject point */ - enum voice_pcm_interface_type interface; - /* Non-NULL indicates start,NULL indicates stop */ - uint32_t callback_id; -}; - -struct snd_voice_pcm_interface_ipclnt_reg_status { - enum voice_pcm_interface_reg_status_type status; -}; - -struct snd_voice_pcm_interface_ipclnt_fn_type_args { - uint32_t callback_id; - uint32_t pcm_data_ptr_not_null; - uint32_t pcm_data_max_length; -}; - -struct snd_voice_pcm_interface_ipclnt_fn_type_reply { - enum voice_pcm_data_status_type status; - struct { - uint32_t pcm_data_len; - struct { - uint16_t pcm_data_ignore; - uint16_t pcm_data_valid; - } pcm_data_val[MAX_VOC_FRAME_SIZE]; - } pcm_data; -}; - -struct buffer { - void *data; - unsigned size; - unsigned used; -}; - -struct audio { - struct buffer out[MAX_VOC_FRAMES]; - - uint8_t out_head; - uint8_t out_tail; - - atomic_t out_bytes; - /* data allocated for various buffers */ - char *data; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t wait; - wait_queue_head_t stop_wait; - - int buffer_finished; - int opened; - int enabled; - int running; - int stopped; /* set when stopped */ - - struct msm_rpc_client *client; -}; - -static struct audio the_audio; - -static int snd_voice_pcm_interface_ipclnt_reg_args( - struct msm_rpc_client *client, void *buf, void *data) -{ - struct snd_voice_pcm_interface_ipclnt_reg_args *arg; - int size = 0; - - arg = (struct snd_voice_pcm_interface_ipclnt_reg_args *)data; - *((int *)buf) = cpu_to_be32(arg->interface); - size += sizeof(int); - buf += sizeof(int); - *((int *)buf) = cpu_to_be32(arg->callback_id); - size += sizeof(int); - - return size; -} - -static int snd_voice_pcm_interface_ipclnt_reg_status( - struct msm_rpc_client *client, void *buf, void *data) -{ - struct snd_voice_pcm_interface_ipclnt_reg_status *result = - (struct snd_voice_pcm_interface_ipclnt_reg_status *)buf; - - *((int *)data) = be32_to_cpu(result->status); - return 0; -} - -static void process_callback(struct audio *audio, - void *buffer, int in_size) -{ - uint32_t accept_status = RPC_ACCEPTSTAT_SUCCESS; - struct rpc_request_hdr *req; - struct snd_voice_pcm_interface_ipclnt_fn_type_args arg, *buf_ptr; - struct snd_voice_pcm_interface_ipclnt_fn_type_reply *reply; - struct buffer *frame; - uint32_t status; - uint32_t pcm_data_len; - - req = (struct rpc_request_hdr *)buffer; - buf_ptr = (struct snd_voice_pcm_interface_ipclnt_fn_type_args *)\ - (req + 1); - arg.callback_id = be32_to_cpu(buf_ptr->callback_id); - arg.pcm_data_ptr_not_null = be32_to_cpu(buf_ptr->pcm_data_ptr_not_null); - arg.pcm_data_max_length = be32_to_cpu(buf_ptr->pcm_data_max_length); - - MM_DBG("callback_id = 0x%8x pcm_data_ptr_not_null = 0x%8x"\ - "pcm_data_max_length = 0x%8x\n", arg.callback_id,\ - arg.pcm_data_ptr_not_null, arg.pcm_data_max_length); - /* Flag interface as running */ - if (!audio->running) - audio->running = 1; - if (!arg.pcm_data_ptr_not_null) { - accept_status = RPC_ACCEPTSTAT_SYSTEM_ERR; - msm_rpc_start_accepted_reply(audio->client, - be32_to_cpu(req->xid), accept_status); - msm_rpc_send_accepted_reply(audio->client, 0); - return; - } - reply = (struct snd_voice_pcm_interface_ipclnt_fn_type_reply *) - msm_rpc_start_accepted_reply(audio->client, - be32_to_cpu(req->xid), accept_status); - frame = audio->out + audio->out_tail; - /* If Data available, send data */ - if (frame->used) { - int i; - unsigned short *src = frame->data; - atomic_add(frame->used, &audio->out_bytes); - status = VOICE_PCM_DATA_STATUS_AVAILABLE; - pcm_data_len = MAX_VOC_FRAME_SIZE; - xdr_send_int32(&audio->client->cb_xdr, &status); - xdr_send_int32(&audio->client->cb_xdr, &pcm_data_len); - /* Expected cb_xdr buffer size is more than PCM buffer size */ - for (i = 0; i < MAX_VOC_FRAME_SIZE; i++, ++src) - xdr_send_int16(&audio->client->cb_xdr, src); - frame->used = 0; - audio->out_tail = ((++audio->out_tail) % MAX_VOC_FRAMES); - wake_up(&audio->wait); - } else { - status = VOICE_PCM_DATA_STATUS_UNAVAILABLE; - pcm_data_len = 0; - xdr_send_int32(&audio->client->cb_xdr, &status); - xdr_send_int32(&audio->client->cb_xdr, &pcm_data_len); - wake_up(&audio->wait); - /* Flag all buffer completed */ - if (audio->stopped) { - audio->buffer_finished = 1; - wake_up(&audio->stop_wait); - } - } - MM_DBG("Provided PCM data = 0x%8x\n", reply->status); - msm_rpc_send_accepted_reply(audio->client, 0); - return; -} - -static int pcm_interface_process_callback_routine(struct msm_rpc_client *client, - void *buffer, int in_size) -{ - struct rpc_request_hdr *req; - struct audio *audio = &the_audio; - int rc = 0; - - req = (struct rpc_request_hdr *)buffer; - - MM_DBG("proc id = 0x%8x xid = 0x%8x size = 0x%8x\n", - be32_to_cpu(req->procedure), be32_to_cpu(req->xid), in_size); - switch (be32_to_cpu(req->procedure)) { - /* Procedure which called every 20ms for PCM samples request*/ - case SND_VOC_PCM_CLIENT_INPUT_FN_TYPE_PROC: - process_callback(audio, buffer, in_size); - break; - default: - MM_ERR("Not supported proceudure 0x%8x\n", - be32_to_cpu(req->procedure)); - /* Not supported RPC Procedure, send nagative code */ - msm_rpc_start_accepted_reply(client, be32_to_cpu(req->xid), - RPC_ACCEPTSTAT_PROC_UNAVAIL); - msm_rpc_send_accepted_reply(client, 0); - } - return rc; -} - -static void audio_flush(struct audio *audio) -{ - int cnt; - for (cnt = 0; cnt < MAX_VOC_FRAMES; cnt++) - audio->out[cnt].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->stopped = 0; - audio->running = 0; - audio->buffer_finished = 0; -} - -/* must be called with audio->lock held */ -static int audio_enable(struct audio *audio) -{ - int rc; - struct snd_voice_pcm_interface_ipclnt_reg_args arg; - struct snd_voice_pcm_interface_ipclnt_reg_status result; - - /* voice_pcm_interface_type */ - arg.interface = VOICE_PCM_INTERFACE_TX_INPUT; - /* Should be non-zero, unique */ - arg.callback_id = START_CALLBACK_ID; - /* Start Voice PCM interface */ - rc = msm_rpc_client_req(audio->client, - SND_VOC_REGISTER_PCM_INPUT_CLIENT_PROC, - snd_voice_pcm_interface_ipclnt_reg_args, &arg, - snd_voice_pcm_interface_ipclnt_reg_status, - &result, -1); - MM_DBG("input client registration status rc 0x%8x result 0x%8x\n", - rc, result.status); - /* If error in server side */ - if (rc == 0) - if (result.status != SUCCESS) - rc = -ENODEV; - return rc; -} -static int audio_disable(struct audio *audio) -{ - int rc; - struct snd_voice_pcm_interface_ipclnt_reg_args arg; - struct snd_voice_pcm_interface_ipclnt_reg_status result; - - /* Wait till all buffers consumed to prevent data loss - Also ensure if client stops due to vocoder disable - do not loop forever */ - rc = wait_event_interruptible_timeout(audio->stop_wait, - !(audio->running) || (audio->buffer_finished == 1), - msecs_to_jiffies(MAX_WAIT_CONSUME)); - if (rc < 0) - return 0; - /* voice_pcm_interface_type */ - arg.interface = VOICE_PCM_INTERFACE_TX_INPUT; - arg.callback_id = STOP_CALLBACK_ID; /* Should be zero */ - /* Stop Voice PCM interface */ - rc = msm_rpc_client_req(audio->client, - SND_VOC_REGISTER_PCM_INPUT_CLIENT_PROC, - snd_voice_pcm_interface_ipclnt_reg_args, &arg, - snd_voice_pcm_interface_ipclnt_reg_status, - &result, -1); - MM_DBG("input client de-registration status rc 0x%8x result 0x%8x\n", - rc, result.status); - /* If error in server side */ - if (rc == 0) - if (result.status != SUCCESS) - rc = -ENODEV; - return rc; -} - -static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = atomic_read(&audio->out_bytes); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - rc = audio_enable(audio); - if (rc == 0) - audio->enabled = 1; - break; - case AUDIO_STOP: - if (audio->enabled) { - audio->stopped = 1; - rc = audio_disable(audio); - if (rc == 0) { - audio->enabled = 0; - audio->running = 0; - wake_up(&audio->wait); - } else - audio->stopped = 0; - } - break; - case AUDIO_SET_CONFIG: { - struct msm_audio_config config; - if (copy_from_user(&config, (void *) arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.type == 0) { - /* Selection for different PCM intect point */ - } else { - rc = -EINVAL; - break; - } - rc = 0; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config config; - config.buffer_size = MAX_VOC_FRAME_SIZE * 2; - config.buffer_count = MAX_VOC_FRAMES; - config.sample_rate = 8000; - config.channel_count = 1; - config.type = 0; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *) arg, &config, sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - default: { - rc = -EINVAL; - MM_ERR(" Unsupported ioctl 0x%8x\n", cmd); - } - } - mutex_unlock(&audio->lock); - return rc; -} -static ssize_t audio_read(struct file *file, char __user *buf, - size_t count, loff_t *pos) -{ - return -EINVAL; -} - -static ssize_t audio_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - int rc = 0; - - mutex_lock(&audio->write_lock); - /* Ensure to copy only till frame boundary */ - while (count >= (MAX_VOC_FRAME_SIZE*2)) { - frame = audio->out + audio->out_head; - rc = wait_event_interruptible_timeout(audio->wait,\ - (frame->used == 0) || (audio->stopped), - msecs_to_jiffies(MAX_WAIT_CONSUME)); - - if (rc < 0) - break; - if (audio->stopped) { - rc = -EBUSY; - break; - } - if (rc == 0) { - rc = -ETIMEDOUT; - break; - } - - xfer = count > frame->size ? frame->size : count; - if (copy_from_user(frame->data, buf, xfer)) { - rc = -EFAULT; - break; - } - frame->used = xfer; - audio->out_head = ((++audio->out_head) % MAX_VOC_FRAMES); - count -= xfer; - buf += xfer; - } - mutex_unlock(&audio->write_lock); - MM_DBG("write done 0x%8x\n", (unsigned int)(buf - start)); - if (rc < 0) - return rc; - return buf - start; -} - -static int audio_open(struct inode *inode, struct file *file) -{ - struct audio *audio = &the_audio; - int rc, cnt; - - mutex_lock(&audio->lock); - - if (audio->opened) { - MM_ERR("busy as driver already in open state\n"); - rc = -EBUSY; - goto done; - } - - if (!audio->data) { - audio->data = kmalloc(BUFSZ, GFP_KERNEL); - if (!audio->data) { - MM_ERR("could not allocate buffers\n"); - rc = -ENOMEM; - goto done; - } - } - - audio->client = msm_rpc_register_client("voice_pcm_interface_client", - SND_VOC_PCM_INTERFACE_PROG, - SND_VOC_PCM_INTERFACE_VERS, 1, - pcm_interface_process_callback_routine); - if (IS_ERR(audio->client)) { - MM_ERR("Failed to register voice pcm interface client"\ - "to 0x%8x\n", SND_VOC_PCM_INTERFACE_PROG); - kfree(audio->data); - audio->data = NULL; - rc = -ENODEV; - goto done; - } - MM_INFO("voice pcm client registred %p\n", audio->client); - for (cnt = 0; cnt < MAX_VOC_FRAMES; cnt++) { - audio->out[cnt].data = (audio->data +\ - ((MAX_VOC_FRAME_SIZE * 2) * cnt)); - audio->out[cnt].size = MAX_VOC_FRAME_SIZE * 2; - MM_DBG("data ptr = %p\n", audio->out[cnt].data); - } - file->private_data = audio; - audio_flush(audio); - audio->opened = 1; - rc = 0; -done: - mutex_unlock(&audio->lock); - return rc; -} - -static int audio_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - if (audio->enabled) { - audio->stopped = 1; - audio_disable(audio); - audio->running = 0; - audio->enabled = 0; - wake_up(&audio->wait); - } - msm_rpc_unregister_client(audio->client); - kfree(audio->data); - audio->data = NULL; - audio->opened = 0; - mutex_unlock(&audio->lock); - return 0; -} - -static const struct file_operations audio_fops = { - .owner = THIS_MODULE, - .open = audio_open, - .release = audio_release, - .read = audio_read, - .write = audio_write, - .unlocked_ioctl = audio_ioctl, -}; - -static struct miscdevice audio_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "snd_pcm_client", - .fops = &audio_fops, -}; - -static int __init audio_init(void) -{ - mutex_init(&the_audio.lock); - mutex_init(&the_audio.write_lock); - init_waitqueue_head(&the_audio.wait); - init_waitqueue_head(&the_audio.stop_wait); - return misc_register(&audio_misc); -} -device_initcall(audio_init); diff --git a/arch/arm/mach-msm/qdsp5v2/Makefile b/arch/arm/mach-msm/qdsp5v2/Makefile deleted file mode 100644 index 3ae3c1b1fb402d2d5cf078324b1c0b9a417794be..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -obj-y += afe.o audio_interct.o mi2s.o audio_dev_ctl.o voice.o - -ifeq ($(CONFIG_TIMPANI_CODEC), y) -obj-y += snddev_icodec.o -else ifeq ($(CONFIG_MARIMBA_CODEC), y) -obj-y += snddev_icodec.o -endif - -obj-$(CONFIG_MARIMBA_CODEC) += snddev_data_marimba.o -obj-$(CONFIG_TIMPANI_CODEC) += snddev_data_timpani.o - -obj-y += audio_pcm.o audpp.o audio_mp3.o audio_wma.o audio_aac.o audio_amrnb.o -obj-y += audio_amrwb.o audio_wmapro.o audio_adpcm.o audio_evrc.o audio_qcelp.o -obj-y += aux_pcm.o snddev_ecodec.o audio_out.o -obj-y += audio_lpa.o mp3_funcs.o pcm_funcs.o -obj-y += audpreproc.o audio_pcm_in.o audio_aac_in.o audio_amrnb_in.o audio_a2dp_in.o -obj-y += audio_evrc_in.o audio_qcelp_in.o -obj-y += adsp.o adsp_driver.o adsp_info.o -obj-y += audio_acdb.o snddev_virtual.o -obj-y += audio_fm.o -obj-y += lpa.o snddev_mi2s.o -obj-y += audio_mvs.o \ No newline at end of file diff --git a/arch/arm/mach-msm/qdsp5v2/adsp.c b/arch/arm/mach-msm/qdsp5v2/adsp.c deleted file mode 100644 index 371ef008f717555c98d1191bda13da272defac35..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/adsp.c +++ /dev/null @@ -1,1225 +0,0 @@ -/* - * Register/Interrupt access for userspace aDSP library. - * - * Copyright (C) 2008 Google, Inc. - * Copyright (c) 2008-2009,2011-2012 The Linux Foundation. All rights reserved. - * Author: Iliyan Malchev - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -/* TODO: - * - move shareable rpc code outside of adsp.c - * - general solution for virt->phys patchup - * - queue IDs should be relative to modules - * - disallow access to non-associated queues - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "adsp.h" -#include -#include - -#ifdef CONFIG_DEBUG_FS -static struct dentry *dentry_adsp; -static struct dentry *dentry_wdata; -static struct dentry *dentry_rdata; -static int wdump, rdump; -#endif /* CONFIG_DEBUG_FS */ - -static struct adsp_info adsp_info; -static struct msm_adsp_module *adsp_modules; -static int adsp_open_count; - -static DEFINE_MUTEX(adsp_open_lock); - -/* protect interactions with the ADSP command/message queue */ -static spinlock_t adsp_cmd_lock; -static spinlock_t adsp_write_lock; - -static uint32_t current_image = -1; - -void adsp_set_image(struct adsp_info *info, uint32_t image) -{ - current_image = image; -} - -/* - * Checks whether the module_id is available in the - * module_entries table.If module_id is available returns `0`. - * If module_id is not available returns `-ENXIO`. - */ -static int32_t adsp_validate_module(uint32_t module_id) -{ - uint32_t *ptr; - uint32_t module_index; - uint32_t num_mod_entries; - - ptr = adsp_info.init_info_ptr->module_entries; - num_mod_entries = adsp_info.init_info_ptr->module_table_size; - - for (module_index = 0; module_index < num_mod_entries; module_index++) - if (module_id == ptr[module_index]) - return 0; - - return -ENXIO; -} - -static int32_t adsp_validate_queue(uint32_t mod_id, unsigned q_idx, - uint32_t size) -{ - int32_t i; - struct adsp_rtos_mp_mtoa_init_info_type *sptr; - - sptr = adsp_info.init_info_ptr; - for (i = 0; i < sptr->mod_to_q_entries; i++) - if (mod_id == sptr->mod_to_q_tbl[i].module) - if (q_idx == sptr->mod_to_q_tbl[i].q_type) { - if (size <= sptr->mod_to_q_tbl[i].q_max_len) - return 0; - MM_ERR("q_idx: %d is not a valid queue \ - for module %x\n", q_idx, mod_id); - return -EINVAL; - } - MM_ERR("cmd_buf size is more than allowed size\n"); - return -EINVAL; -} - -uint32_t adsp_get_module(struct adsp_info *info, uint32_t task) -{ - return info->task_to_module[current_image][task]; -} - -uint32_t adsp_get_queue_offset(struct adsp_info *info, uint32_t queue_id) -{ - return info->queue_offset[current_image][queue_id]; -} - -static int rpc_adsp_rtos_app_to_modem(uint32_t cmd, uint32_t module, - struct msm_adsp_module *adsp_module) -{ - struct adsp_rtos_atom_cmd adspsvc_cmd; - int err; - - adspsvc_cmd.cmd = cmd; - adspsvc_cmd.proc_id = RPC_ADSP_RTOS_PROC_APPS; - adspsvc_cmd.module = module; - adspsvc_cmd.cb_handle = adsp_info.cb_handle; - - err = dalrpc_fcn_5(DALDEVICE_ADSP_CMD_IDX | 0x80000000, - adsp_info.handle, - &adspsvc_cmd, sizeof(adspsvc_cmd)); - if (err < 0) - MM_ERR("ADSP command send Failed\n"); - - return 0; -} - -static int get_module_index(uint32_t id) -{ - int mod_idx; - for (mod_idx = 0; mod_idx < adsp_info.module_count; mod_idx++) - if (adsp_info.module[mod_idx].id == id) - return mod_idx; - - return -ENXIO; -} - -static struct msm_adsp_module *find_adsp_module_by_id( - struct adsp_info *info, uint32_t id) -{ - int mod_idx; - - if (id > info->max_module_id) { - return NULL; - } else { - mod_idx = get_module_index(id); - if (mod_idx < 0) - return NULL; - return info->id_to_module[mod_idx]; - } -} - -static struct msm_adsp_module *find_adsp_module_by_name( - struct adsp_info *info, const char *name) -{ - unsigned n; - for (n = 0; n < info->module_count; n++) - if (!strcmp(name, adsp_modules[n].name)) - return adsp_modules + n; - return NULL; -} - -/* - * Send RPC_ADSP_RTOS_CMD_GET_INIT_INFO cmd to ARM9 and get - * queue offsets and module entries (init info) as part of the event. - */ -static void msm_get_init_info(void) -{ - struct adsp_rtos_atom_cmd cmd; - int err; - - cmd.cmd = RPC_ADSP_RTOS_CMD_GET_INIT_INFO; - cmd.proc_id = RPC_ADSP_RTOS_PROC_APPS; - cmd.module = 0; - cmd.cb_handle = adsp_info.cb_handle; - - err = dalrpc_fcn_5(DALDEVICE_ADSP_CMD_IDX | 0x80000000, - adsp_info.handle, - &cmd, sizeof(cmd)); - if (err < 0) - MM_ERR("INIT_INFO command send Failed\n"); -} - -int msm_adsp_get(const char *name, struct msm_adsp_module **out, - struct msm_adsp_ops *ops, void *driver_data) -{ - struct msm_adsp_module *module; - int rc = 0; - - module = find_adsp_module_by_name(&adsp_info, name); - if (!module) - return -ENODEV; - - mutex_lock(&module->lock); - MM_DBG("opening module %s\n", module->name); - - if (module->ops) { - rc = -EBUSY; - mutex_unlock(&module->lock); - goto done; - } - - module->ops = ops; - module->driver_data = driver_data; - *out = module; - mutex_unlock(&module->lock); - rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_REGISTER_APP, - module->id, module); - if (rc) { - mutex_lock(&module->lock); - module->ops = NULL; - module->driver_data = NULL; - *out = NULL; - MM_ERR("REGISTER_APP failed\n"); - mutex_unlock(&module->lock); - goto done; - } - - MM_INFO("module %s has been registered\n", module->name); - -done: - return rc; -} -EXPORT_SYMBOL(msm_adsp_get); - -void msm_adsp_put(struct msm_adsp_module *module) -{ - unsigned long flags; - - mutex_lock(&module->lock); - if (module->ops) { - MM_INFO("closing module %s\n", module->name); - - /* lock to ensure a dsp event cannot be delivered - * during or after removal of the ops and driver_data - */ - spin_lock_irqsave(&adsp_cmd_lock, flags); - module->ops = NULL; - module->driver_data = NULL; - spin_unlock_irqrestore(&adsp_cmd_lock, flags); - - if (module->state != ADSP_STATE_DISABLED) { - MM_INFO("disabling module %s\n", module->name); - mutex_unlock(&module->lock); - msm_adsp_disable(module); - return; - } - } else { - MM_INFO("module %s is already closed\n", module->name); - } - mutex_unlock(&module->lock); -} -EXPORT_SYMBOL(msm_adsp_put); - -int __msm_adsp_write(struct msm_adsp_module *module, unsigned dsp_queue_addr, - void *cmd_buf, size_t cmd_size) -{ - uint32_t ctrl_word; - uint32_t dsp_q_addr; - uint32_t dsp_addr; - uint32_t cmd_id = 0; - int cnt = 0; - int ret_status = 0; - unsigned long flags; - struct adsp_info *info; - - if (!module || !cmd_buf) { - MM_ERR("Called with NULL parameters\n"); - return -EINVAL; - } - info = module->info; - spin_lock_irqsave(&adsp_write_lock, flags); - - if (module->state != ADSP_STATE_ENABLED) { - spin_unlock_irqrestore(&adsp_write_lock, flags); - MM_ERR("module %s not enabled before write\n", module->name); - return -ENODEV; - } - if (adsp_validate_module(module->id)) { - spin_unlock_irqrestore(&adsp_write_lock, flags); - MM_ERR("module id validation failed %s %d\n", - module->name, module->id); - return -ENXIO; - } - if (dsp_queue_addr >= QDSP_MAX_NUM_QUEUES) { - spin_unlock_irqrestore(&adsp_write_lock, flags); - MM_ERR("Invalid Queue Index: %d\n", dsp_queue_addr); - return -ENXIO; - } - if (adsp_validate_queue(module->id, dsp_queue_addr, cmd_size)) { - spin_unlock_irqrestore(&adsp_write_lock, flags); - return -EINVAL; - } - dsp_q_addr = adsp_get_queue_offset(info, dsp_queue_addr); - dsp_q_addr &= ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M; - - /* Poll until the ADSP is ready to accept a command. - * Wait for 100us, return error if it's not responding. - * If this returns an error, we need to disable ALL modules and - * then retry. - */ - while (((ctrl_word = readl(info->write_ctrl)) & - ADSP_RTOS_WRITE_CTRL_WORD_READY_M) != - ADSP_RTOS_WRITE_CTRL_WORD_READY_V) { - if (cnt > 50) { - MM_ERR("timeout waiting for DSP write ready\n"); - ret_status = -EIO; - goto fail; - } - MM_DBG("waiting for DSP write ready\n"); - udelay(2); - cnt++; - } - - /* Set the mutex bits */ - ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M); - ctrl_word |= ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V; - - /* Clear the command bits */ - ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_CMD_M); - - /* Set the queue address bits */ - ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M); - ctrl_word |= dsp_q_addr; - - writel(ctrl_word, info->write_ctrl); - - /* Generate an interrupt to the DSP. This notifies the DSP that - * we are about to send a command on this particular queue. The - * DSP will in response change its state. - */ - writel(1, info->send_irq); - - /* Poll until the adsp responds to the interrupt; this does not - * generate an interrupt from the adsp. This should happen within - * 5ms. - */ - cnt = 0; - while ((readl(info->write_ctrl) & - ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M) == - ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V) { - if (cnt > 2500) { - MM_ERR("timeout waiting for adsp ack\n"); - ret_status = -EIO; - goto fail; - } - udelay(2); - cnt++; - } - - /* Read the ctrl word */ - ctrl_word = readl(info->write_ctrl); - - if ((ctrl_word & ADSP_RTOS_WRITE_CTRL_WORD_STATUS_M) != - ADSP_RTOS_WRITE_CTRL_WORD_NO_ERR_V) { - ret_status = -EAGAIN; - goto fail; - } else { - /* No error */ - /* Get the DSP buffer address */ - dsp_addr = (ctrl_word & ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M) + - (uint32_t)MSM_AD5_BASE; - - if (dsp_addr < (uint32_t)(MSM_AD5_BASE + QDSP_RAMC_OFFSET)) { - uint16_t *buf_ptr = (uint16_t *) cmd_buf; - uint16_t *dsp_addr16 = (uint16_t *)dsp_addr; - cmd_size /= sizeof(uint16_t); - - /* Save the command ID */ - cmd_id = (uint32_t) buf_ptr[0]; - - /* Copy the command to DSP memory */ - cmd_size++; - while (--cmd_size) - *dsp_addr16++ = *buf_ptr++; - } else { - uint32_t *buf_ptr = (uint32_t *) cmd_buf; - uint32_t *dsp_addr32 = (uint32_t *)dsp_addr; - cmd_size /= sizeof(uint32_t); - - /* Save the command ID */ - cmd_id = buf_ptr[0]; - - cmd_size++; - while (--cmd_size) - *dsp_addr32++ = *buf_ptr++; - } - - /* Set the mutex bits */ - ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M); - ctrl_word |= ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V; - - /* Set the command bits to write done */ - ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_CMD_M); - ctrl_word |= ADSP_RTOS_WRITE_CTRL_WORD_CMD_WRITE_DONE_V; - - /* Set the queue address bits */ - ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M); - ctrl_word |= dsp_q_addr; - - writel(ctrl_word, info->write_ctrl); - - /* Generate an interrupt to the DSP. It does not respond with - * an interrupt, and we do not need to wait for it to - * acknowledge, because it will hold the mutex lock until it's - * ready to receive more commands again. - */ - writel(1, info->send_irq); - - module->num_commands++; - } /* Ctrl word status bits were 00, no error in the ctrl word */ - -fail: - spin_unlock_irqrestore(&adsp_write_lock, flags); - return ret_status; -} -EXPORT_SYMBOL(msm_adsp_write); - -int msm_adsp_write(struct msm_adsp_module *module, unsigned dsp_queue_addr, - void *cmd_buf, size_t cmd_size) -{ - int rc, retries = 0; -#ifdef CONFIG_DEBUG_FS - uint16_t *ptr; - int ii; - - if (wdump > 0) { - ptr = cmd_buf; - pr_info("A->D:%x\n", module->id); - pr_info("adsp: %x %d\n", dsp_queue_addr, cmd_size); - for (ii = 0; ii < cmd_size/2; ii++) - pr_info("%x ", ptr[ii]); - pr_info("\n"); - } -#endif /* CONFIG_DEBUG_FS */ - do { - rc = __msm_adsp_write(module, dsp_queue_addr, cmd_buf, - cmd_size); - if (rc == -EAGAIN) - udelay(50); - } while (rc == -EAGAIN && retries++ < 300); - if (retries > 20) - MM_INFO("%s command took %d attempts: rc %d\n", - module->name, retries, rc); - return rc; -} - -#ifdef CONFIG_MSM_ADSP_REPORT_EVENTS -static void *event_addr; -static void read_event(void *buf, size_t len) -{ - uint32_t dptr[3]; - struct adsp_rtos_mp_mtoa_s_type *sptr; - struct adsp_rtos_mp_mtoa_type *pkt_ptr; - - sptr = event_addr; - pkt_ptr = &sptr->adsp_rtos_mp_mtoa_data.mp_mtoa_packet; - - dptr[0] = sptr->mp_mtoa_header.event; - dptr[1] = pkt_ptr->module; - dptr[2] = pkt_ptr->image; - - if (len > EVENT_LEN) - len = EVENT_LEN; - - memcpy(buf, dptr, len); -} -#endif - -static void adsp_rtos_mtoa_cb(void *context, uint32_t param, - void *evt_buf, uint32_t len) -{ - struct adsp_rtos_mp_mtoa_s_type *args = NULL; - uint32_t event = 0; - uint32_t proc_id = 0; - uint32_t module_id; - uint32_t image; - struct msm_adsp_module *module; - struct adsp_rtos_mp_mtoa_type *pkt_ptr; - struct queue_to_offset_type *qptr; - struct queue_to_offset_type *qtbl; - struct mod_to_queue_offsets *mqptr; - struct mod_to_queue_offsets *mqtbl; - uint32_t *mptr; - uint32_t *mtbl; - uint32_t q_idx; - uint32_t num_entries; - uint32_t entries_per_image; - struct adsp_rtos_mp_mtoa_init_info_type *iptr; - struct adsp_rtos_mp_mtoa_init_info_type *sptr; - int32_t i_no, e_idx; - static uint32_t init_info_completed; - static uint32_t init_info_len = - sizeof(struct adsp_rtos_mp_mtoa_header_type); - static uint32_t next_init_info_byte; - static uint32_t expected_byte = 1; - uint32_t hdr_len = sizeof(struct adsp_rtos_mp_mtoa_header_type); - - if (len) { - args = (struct adsp_rtos_mp_mtoa_s_type *) evt_buf; - event = args->mp_mtoa_header.event; - proc_id = args->mp_mtoa_header.proc_id; - } - - if (!init_info_completed && event == RPC_ADSP_RTOS_INIT_INFO) { - memcpy(((char *)adsp_info.raw_event) + init_info_len, - (char *)evt_buf + hdr_len + 4, - len - ((hdr_len + 4))); - init_info_len += (len - (hdr_len + 4)); - evt_buf += hdr_len; - next_init_info_byte = *(uint32_t *) evt_buf; - expected_byte += len; - if (next_init_info_byte && - (expected_byte != next_init_info_byte)) { - MM_ERR("INIT_INFO - expecting next byte to be %d\n" - "\tbut ADSPSVC indicated next byte to be %d\n", - expected_byte, next_init_info_byte); - return; - } - if (!next_init_info_byte) { - args = adsp_info.raw_event; - args->mp_mtoa_header.event = event; - args->mp_mtoa_header.proc_id = proc_id; - init_info_completed = 1; - } else - return; - } - - if (event == RPC_ADSP_RTOS_INIT_INFO) { - MM_INFO("INIT_INFO Event\n"); - sptr = &args->adsp_rtos_mp_mtoa_data.mp_mtoa_init_packet; - - iptr = adsp_info.init_info_ptr; - iptr->image_count = sptr->image_count; - if (iptr->image_count > IMG_MAX) - iptr->image_count = IMG_MAX; - iptr->num_queue_offsets = sptr->num_queue_offsets; - num_entries = iptr->num_queue_offsets; - if (num_entries > ENTRIES_MAX) { - num_entries = ENTRIES_MAX; - iptr->num_queue_offsets = ENTRIES_MAX; - } - qptr = &sptr->queue_offsets_tbl[0][0]; - for (i_no = 0; i_no < iptr->image_count; i_no++) { - qtbl = &iptr->queue_offsets_tbl[i_no][0]; - for (e_idx = 0; e_idx < num_entries; e_idx++) { - qtbl[e_idx].offset = qptr->offset; - qtbl[e_idx].queue = qptr->queue; - q_idx = qptr->queue; - iptr->queue_offsets[i_no][q_idx] = - qtbl[e_idx].offset; - qptr++; - } - } - - num_entries = sptr->num_task_module_entries; - if (num_entries > ENTRIES_MAX) - num_entries = ENTRIES_MAX; - iptr->num_task_module_entries = num_entries; - entries_per_image = num_entries / iptr->image_count; - mptr = &sptr->task_to_module_tbl[0][0]; - for (i_no = 0; i_no < iptr->image_count; i_no++) { - mtbl = &iptr->task_to_module_tbl[i_no][0]; - for (e_idx = 0; e_idx < entries_per_image; e_idx++) { - mtbl[e_idx] = *mptr; - mptr++; - } - } - - iptr->module_table_size = sptr->module_table_size; - if (iptr->module_table_size > MODULES_MAX) - iptr->module_table_size = MODULES_MAX; - mptr = &sptr->module_entries[0]; - for (i_no = 0; i_no < iptr->module_table_size; i_no++) - iptr->module_entries[i_no] = mptr[i_no]; - - mqptr = &sptr->mod_to_q_tbl[0]; - mqtbl = &iptr->mod_to_q_tbl[0]; - iptr->mod_to_q_entries = sptr->mod_to_q_entries; - if (iptr->mod_to_q_entries > ENTRIES_MAX) - iptr->mod_to_q_entries = ENTRIES_MAX; - for (e_idx = 0; e_idx < iptr->mod_to_q_entries; e_idx++) { - mqtbl[e_idx].module = mqptr->module; - mqtbl[e_idx].q_type = mqptr->q_type; - mqtbl[e_idx].q_max_len = mqptr->q_max_len; - mqptr++; - } - - adsp_info.init_info_state = ADSP_STATE_INIT_INFO; - kfree(adsp_info.raw_event); - wake_up(&adsp_info.init_info_wait); - return; - } - pkt_ptr = &args->adsp_rtos_mp_mtoa_data.mp_mtoa_packet; - module_id = pkt_ptr->module; - image = pkt_ptr->image; - - MM_INFO("rpc event=%d, proc_id=%d, module=%d, image=%d\n", - event, proc_id, module_id, image); - - module = find_adsp_module_by_id(&adsp_info, module_id); - if (!module) { - MM_ERR("module %d is not supported!\n", module_id); - return; - } - - mutex_lock(&module->lock); - switch (event) { - case RPC_ADSP_RTOS_MOD_READY: - MM_INFO("module %s: READY\n", module->name); - module->state = ADSP_STATE_ENABLED; - wake_up(&module->state_wait); - adsp_set_image(module->info, image); - break; - case RPC_ADSP_RTOS_MOD_DISABLE: - MM_INFO("module %s: DISABLED\n", module->name); - module->state = ADSP_STATE_DISABLED; - wake_up(&module->state_wait); - break; - case RPC_ADSP_RTOS_SERVICE_RESET: - MM_INFO("module %s: SERVICE_RESET\n", module->name); - module->state = ADSP_STATE_DISABLED; - wake_up(&module->state_wait); - break; - case RPC_ADSP_RTOS_CMD_SUCCESS: - MM_INFO("module %s: CMD_SUCCESS\n", module->name); - break; - case RPC_ADSP_RTOS_CMD_FAIL: - MM_INFO("module %s: CMD_FAIL\n", module->name); - break; - case RPC_ADSP_RTOS_DISABLE_FAIL: - MM_INFO("module %s: DISABLE_FAIL\n", module->name); - break; - default: - MM_ERR("unknown event %d\n", event); - mutex_unlock(&module->lock); - return; - } -#ifdef CONFIG_MSM_ADSP_REPORT_EVENTS - event_addr = (uint32_t *)evt_buf; - if (module->ops) - module->ops->event(module->driver_data, - EVENT_MSG_ID, - EVENT_LEN, - read_event); -#endif - mutex_unlock(&module->lock); -} - -static size_t read_event_size; -static void *read_event_addr; - -static void read_event_16(void *buf, size_t len) -{ - uint16_t *dst = buf; - uint16_t *src = read_event_addr; - len /= 2; - if (len > read_event_size) - len = read_event_size; - while (len--) - *dst++ = *src++; -} - -static void read_event_32(void *buf, size_t len) -{ - uint32_t *dst = buf; - uint32_t *src = read_event_addr; - len /= 2; - if (len > read_event_size) - len = read_event_size; - while (len--) - *dst++ = *src++; -} - -static int adsp_rtos_read_ctrl_word_cmd_tast_to_h_v( - struct adsp_info *info, void *dsp_addr) -{ - struct msm_adsp_module *module; - unsigned rtos_task_id; - unsigned msg_id; - unsigned msg_length; -#ifdef CONFIG_DEBUG_FS - uint16_t *ptr; - int ii; -#endif /* CONFIG_DEBUG_FS */ - void (*func)(void *, size_t); - - if (dsp_addr >= (void *)(MSM_AD5_BASE + QDSP_RAMC_OFFSET)) { - uint32_t *dsp_addr32 = dsp_addr; - uint32_t tmp = *dsp_addr32++; - rtos_task_id = (tmp & ADSP_RTOS_READ_CTRL_WORD_TASK_ID_M) >> 8; - msg_id = (tmp & ADSP_RTOS_READ_CTRL_WORD_MSG_ID_M); - read_event_size = tmp >> 16; - read_event_addr = dsp_addr32; - msg_length = read_event_size * sizeof(uint32_t); - func = read_event_32; - } else { - uint16_t *dsp_addr16 = dsp_addr; - uint16_t tmp = *dsp_addr16++; - rtos_task_id = (tmp & ADSP_RTOS_READ_CTRL_WORD_TASK_ID_M) >> 8; - msg_id = tmp & ADSP_RTOS_READ_CTRL_WORD_MSG_ID_M; - read_event_size = *dsp_addr16++; - read_event_addr = dsp_addr16; - msg_length = read_event_size * sizeof(uint16_t); - func = read_event_16; - } - - if (rtos_task_id > info->max_task_id) { - MM_ERR("bogus task id %d\n", rtos_task_id); - return 0; - } - module = find_adsp_module_by_id(info, - adsp_get_module(info, rtos_task_id)); - - if (!module) { - MM_ERR("no module for task id %d\n", rtos_task_id); - return 0; - } - - module->num_events++; - - if (!module->ops) { - MM_ERR("module %s is not open\n", module->name); - return 0; - } -#ifdef CONFIG_DEBUG_FS - if (rdump > 0) { - ptr = read_event_addr; - pr_info("D->A\n"); - pr_info("m_id = %x id = %x\n", module->id, msg_id); - for (ii = 0; ii < msg_length/2; ii++) - pr_info("%x ", ptr[ii]); - pr_info("\n"); - } -#endif /* CONFIG_DEBUG_FS */ - - module->ops->event(module->driver_data, msg_id, msg_length, func); - return 0; -} - -static int adsp_get_event(struct adsp_info *info) -{ - uint32_t ctrl_word; - uint32_t ready; - void *dsp_addr; - uint32_t cmd_type; - int cnt; - unsigned long flags; - int rc = 0; - - spin_lock_irqsave(&adsp_cmd_lock, flags); - - /* Whenever the DSP has a message, it updates this control word - * and generates an interrupt. When we receive the interrupt, we - * read this register to find out what ADSP task the command is - * comming from. - * - * The ADSP should *always* be ready on the first call, but the - * irq handler calls us in a loop (to handle back-to-back command - * processing), so we give the DSP some time to return to the - * ready state. The DSP will not issue another IRQ for events - * pending between the first IRQ and the event queue being drained, - * unfortunately. - */ - - for (cnt = 0; cnt < 50; cnt++) { - ctrl_word = readl(info->read_ctrl); - - if ((ctrl_word & ADSP_RTOS_READ_CTRL_WORD_FLAG_M) == - ADSP_RTOS_READ_CTRL_WORD_FLAG_UP_CONT_V) - goto ready; - - udelay(2); - } - MM_ERR("not ready after 100uS\n"); - rc = -EBUSY; - goto done; - -ready: - /* Here we check to see if there are pending messages. If there are - * none, we siply return -EAGAIN to indicate that there are no more - * messages pending. - */ - ready = ctrl_word & ADSP_RTOS_READ_CTRL_WORD_READY_M; - if ((ready != ADSP_RTOS_READ_CTRL_WORD_READY_V) && - (ready != ADSP_RTOS_READ_CTRL_WORD_CONT_V)) { - rc = -EAGAIN; - goto done; - } - - /* DSP says that there are messages waiting for the host to read */ - - /* Get the Command Type */ - cmd_type = ctrl_word & ADSP_RTOS_READ_CTRL_WORD_CMD_TYPE_M; - - /* Get the DSP buffer address */ - dsp_addr = (void *)((ctrl_word & - ADSP_RTOS_READ_CTRL_WORD_DSP_ADDR_M) + - (uint32_t)MSM_AD5_BASE); - - /* We can only handle Task-to-Host messages */ - if (cmd_type != ADSP_RTOS_READ_CTRL_WORD_CMD_TASK_TO_H_V) { - MM_ERR("unknown dsp cmd_type %d\n", cmd_type); - rc = -EIO; - goto done; - } - - adsp_rtos_read_ctrl_word_cmd_tast_to_h_v(info, dsp_addr); - - ctrl_word = readl(info->read_ctrl); - ctrl_word &= ~ADSP_RTOS_READ_CTRL_WORD_READY_M; - - /* Write ctrl word to the DSP */ - writel(ctrl_word, info->read_ctrl); - - /* Generate an interrupt to the DSP */ - writel(1, info->send_irq); - -done: - spin_unlock_irqrestore(&adsp_cmd_lock, flags); - return rc; -} - -static irqreturn_t adsp_irq_handler(int irq, void *data) -{ - struct adsp_info *info = &adsp_info; - int cnt = 0; - for (cnt = 0; cnt < 15; cnt++) - if (adsp_get_event(info) < 0) - break; - if (cnt > info->event_backlog_max) - info->event_backlog_max = cnt; - info->events_received += cnt; - if (cnt == 15) - MM_ERR("too many (%d) events for single irq!\n", cnt); - return IRQ_HANDLED; -} - -int adsp_set_clkrate(struct msm_adsp_module *module, unsigned long clk_rate) -{ - if (module->clk && clk_rate) - return clk_set_rate(module->clk, clk_rate); - - return -EINVAL; -} - -int msm_adsp_enable(struct msm_adsp_module *module) -{ - int rc = 0; - - MM_INFO("enable '%s'state[%d] id[%d]\n", - module->name, module->state, module->id); - - mutex_lock(&module->lock); - switch (module->state) { - case ADSP_STATE_DISABLED: - module->state = ADSP_STATE_ENABLING; - mutex_unlock(&module->lock); - rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_ENABLE, - module->id, module); - if (rc) { - mutex_lock(&module->lock); - module->state = ADSP_STATE_DISABLED; - break; - } - rc = wait_event_timeout(module->state_wait, - module->state != ADSP_STATE_ENABLING, - 1 * HZ); - mutex_lock(&module->lock); - if (module->state == ADSP_STATE_ENABLED) { - rc = 0; - } else { - MM_ERR("module '%s' enable timed out\n", module->name); - rc = -ETIMEDOUT; - } - if (module->open_count++ == 0 && module->clk) - clk_prepare_enable(module->clk); - - mutex_lock(&adsp_open_lock); - if (adsp_open_count++ == 0) - enable_irq(adsp_info.int_adsp); - mutex_unlock(&adsp_open_lock); - break; - case ADSP_STATE_ENABLING: - MM_DBG("module '%s' enable in progress\n", module->name); - break; - case ADSP_STATE_ENABLED: - MM_DBG("module '%s' already enabled\n", module->name); - break; - case ADSP_STATE_DISABLING: - MM_ERR("module '%s' disable in progress\n", module->name); - rc = -EBUSY; - break; - } - mutex_unlock(&module->lock); - return rc; -} -EXPORT_SYMBOL(msm_adsp_enable); - -int msm_adsp_disable_event_rsp(struct msm_adsp_module *module) -{ - int rc = 0; - - mutex_lock(&module->lock); - - rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_DISABLE_EVENT_RSP, - module->id, module); - mutex_unlock(&module->lock); - - return rc; -} -EXPORT_SYMBOL(msm_adsp_disable_event_rsp); - -int msm_adsp_disable(struct msm_adsp_module *module) -{ - int rc = 0; - - mutex_lock(&module->lock); - switch (module->state) { - case ADSP_STATE_DISABLED: - MM_DBG("module '%s' already disabled\n", module->name); - mutex_unlock(&module->lock); - break; - case ADSP_STATE_ENABLING: - case ADSP_STATE_ENABLED: - mutex_unlock(&module->lock); - rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_DISABLE, - module->id, module); - mutex_lock(&module->lock); - module->state = ADSP_STATE_DISABLED; - if (--module->open_count == 0 && module->clk) - clk_disable_unprepare(module->clk); - mutex_unlock(&module->lock); - mutex_lock(&adsp_open_lock); - if (--adsp_open_count == 0) { - disable_irq(adsp_info.int_adsp); - MM_INFO("disable interrupt\n"); - } - mutex_unlock(&adsp_open_lock); - break; - } - return rc; -} -EXPORT_SYMBOL(msm_adsp_disable); - -static int msm_adsp_probe(struct platform_device *pdev) -{ - unsigned count; - int rc, i; - - adsp_info.int_adsp = platform_get_irq(pdev, 0); - if (adsp_info.int_adsp < 0) { - MM_ERR("no irq resource?\n"); - return -ENODEV; - } - - adsp_info.init_info_ptr = kzalloc( - (sizeof(struct adsp_rtos_mp_mtoa_init_info_type)), GFP_KERNEL); - if (!adsp_info.init_info_ptr) - return -ENOMEM; - - adsp_info.raw_event = kzalloc( - (sizeof(struct adsp_rtos_mp_mtoa_s_type)), GFP_KERNEL); - if (!adsp_info.raw_event) { - kfree(adsp_info.init_info_ptr); - return -ENOMEM; - } - - rc = adsp_init_info(&adsp_info); - if (rc) { - kfree(adsp_info.init_info_ptr); - kfree(adsp_info.raw_event); - return rc; - } - adsp_info.send_irq += (uint32_t) MSM_AD5_BASE; - adsp_info.read_ctrl += (uint32_t) MSM_AD5_BASE; - adsp_info.write_ctrl += (uint32_t) MSM_AD5_BASE; - count = adsp_info.module_count; - - adsp_modules = kzalloc( - (sizeof(struct msm_adsp_module) + sizeof(void *)) * - count, GFP_KERNEL); - if (!adsp_modules) { - kfree(adsp_info.init_info_ptr); - kfree(adsp_info.raw_event); - return -ENOMEM; - } - - adsp_info.id_to_module = (void *) (adsp_modules + count); - - spin_lock_init(&adsp_cmd_lock); - spin_lock_init(&adsp_write_lock); - - rc = request_irq(adsp_info.int_adsp, adsp_irq_handler, - IRQF_TRIGGER_RISING, "adsp", 0); - if (rc < 0) - goto fail_request_irq; - disable_irq(adsp_info.int_adsp); - - for (i = 0; i < count; i++) { - struct msm_adsp_module *mod = adsp_modules + i; - mutex_init(&mod->lock); - init_waitqueue_head(&mod->state_wait); - mod->info = &adsp_info; - mod->name = adsp_info.module[i].name; - mod->id = adsp_info.module[i].id; - if (adsp_info.module[i].clk_name) - mod->clk = clk_get(NULL, adsp_info.module[i].clk_name); - else - mod->clk = NULL; - if (mod->clk && adsp_info.module[i].clk_rate) - clk_set_rate(mod->clk, adsp_info.module[i].clk_rate); - mod->verify_cmd = adsp_info.module[i].verify_cmd; - mod->patch_event = adsp_info.module[i].patch_event; - INIT_HLIST_HEAD(&mod->pmem_regions); - mod->pdev.name = adsp_info.module[i].pdev_name; - mod->pdev.id = -1; - adsp_info.id_to_module[i] = mod; - platform_device_register(&mod->pdev); - } - - msm_adsp_publish_cdevs(adsp_modules, count); - - rc = daldevice_attach(DALRPC_ADSPSVC_DEVICEID, DALRPC_ADSPSVC_PORT, - DALRPC_ADSPSVC_DEST, &adsp_info.handle); - if (rc) { - MM_ERR("adsp attach failed : %d\n", rc); - goto fail_dal_attach; - } - - adsp_info.cb_handle = dalrpc_alloc_cb(adsp_info.handle, - adsp_rtos_mtoa_cb, NULL); - if (adsp_info.cb_handle == NULL) { - MM_ERR("Callback registration failed\n"); - goto fail_allocate_cb; - } - - /* Get INIT_INFO */ - init_waitqueue_head(&adsp_info.init_info_wait); - msm_get_init_info(); - rc = wait_event_timeout(adsp_info.init_info_wait, - adsp_info.init_info_state == ADSP_STATE_INIT_INFO, - 10 * HZ); - if (!rc) { - MM_ERR("INIT_INFO failed\n"); - rc = -ETIMEDOUT; - } else - return 0; - -fail_allocate_cb: - daldevice_detach(adsp_info.handle); - adsp_info.handle = NULL; -fail_dal_attach: - enable_irq(adsp_info.int_adsp); - free_irq(adsp_info.int_adsp, 0); -fail_request_irq: - kfree(adsp_modules); - kfree(adsp_info.init_info_ptr); - kfree(adsp_info.raw_event); - return rc; -} - -#ifdef CONFIG_DEBUG_FS -static int get_parameters(char *buf, long int *param1, int num_of_par) -{ - char *token; - int base, cnt; - - token = strsep(&buf, " "); - - for (cnt = 0; cnt < num_of_par; cnt++) { - if (token != NULL) { - if ((token[1] == 'x') || (token[1] == 'X')) - base = 16; - else - base = 10; - - if (strict_strtoul(token, base, ¶m1[cnt]) != 0) - return -EINVAL; - - token = strsep(&buf, " "); - } - else - return -EINVAL; - } - return 0; -} - -static ssize_t adsp_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - pr_debug("adsp debugfs opened\n"); - return 0; -} -static ssize_t adsp_debug_write(struct file *file, const char __user *buf, - size_t cnt, loff_t *ppos) -{ - char *access_str = file->private_data; - char lbuf[32]; - int rc; - long int param[5]; - - if (cnt > sizeof(lbuf) - 1) - return -EINVAL; - rc = copy_from_user(lbuf, buf, cnt); - if (rc) { - pr_info("Unable to copy data from user space\n"); - return -EFAULT; - } - lbuf[cnt] = '\0'; - - if (!strncmp(access_str, "write_log", 9)) { - if (get_parameters(lbuf, param, 1) == 0) { - switch (param[0]) { - case 1: - if (wdump <= 0) - wdump = 1; - pr_debug("write cmd to DSP(A->D) dump \ - started:%d\n", wdump); - break; - case 0: - if (wdump > 0) - wdump = 0; - pr_debug("Stop write cmd to \ - DSP(A->D):%d\n", wdump); - break; - default: - rc = -EINVAL; - break; - } - } else - rc = -EINVAL; - } else if (!strncmp(access_str, "read_log", 8)) { - if (get_parameters(lbuf, param, 1) == 0) { - switch (param[0]) { - case 1: - if (rdump <= 0) - rdump = 1; - pr_debug("write cmd from DSP(D->A) dump \ - started:%d\n", wdump); - break; - case 0: - if (rdump > 0) - rdump = 0; - pr_debug("Stop write cmd from \ - DSP(D->A):%d\n", wdump); - break; - default: - rc = -EINVAL; - break; - } - } else - rc = -EINVAL; - } else { - rc = -EINVAL; - } - if (rc == 0) - rc = cnt; - else { - pr_err("%s: rc = %d\n", __func__, rc); - pr_info("\nWrong command: Use =>\n"); - pr_info("-------------------------\n"); - pr_info("To Start A->D:: echo \"1\">/sys/kernel/debug/ \ - adsp_cmd/write_log\n"); - pr_info("To Start D->A:: echo \"1\">/sys/kernel/debug/ \ - adsp_cmd/read_log\n"); - pr_info("To Stop A->D:: echo \"0\">/sys/kernel/debug/ \ - adsp_cmd/write_log\n"); - pr_info("To Stop D->A:: echo \"0\">/sys/kernel/debug/ \ - adsp_cmd/read_log\n"); - pr_info("------------------------\n"); - } - - return rc; -} -#endif - -static struct platform_driver msm_adsp_driver = { - .probe = msm_adsp_probe, - .driver = { - .owner = THIS_MODULE, - }, -}; - -static char msm_adsp_driver_name[] = "msm_adsp"; - -#ifdef CONFIG_DEBUG_FS -static const struct file_operations adsp_debug_fops = { - .write = adsp_debug_write, - .open = adsp_debug_open, -}; -#endif - -static int __init adsp_init(void) -{ - int rc; - -#ifdef CONFIG_DEBUG_FS - dentry_adsp = debugfs_create_dir("adsp_cmd", 0); - if (!IS_ERR(dentry_adsp)) { - dentry_wdata = debugfs_create_file("write_log", \ - S_IFREG | S_IRUGO, dentry_adsp, - (void *) "write_log" , &adsp_debug_fops); - dentry_rdata = debugfs_create_file("read_log", \ - S_IFREG | S_IRUGO, dentry_adsp, - (void *) "read_log", &adsp_debug_fops); - } -#endif /* CONFIG_DEBUG_FS */ - - msm_adsp_driver.driver.name = msm_adsp_driver_name; - rc = platform_driver_register(&msm_adsp_driver); - MM_INFO("%s -- %d\n", msm_adsp_driver_name, rc); - return rc; -} - -device_initcall(adsp_init); diff --git a/arch/arm/mach-msm/qdsp5v2/adsp.h b/arch/arm/mach-msm/qdsp5v2/adsp.h deleted file mode 100644 index b5a574beaa0ef498b287922c1c3b7b2f31ef57d3..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/adsp.h +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Copyright (C) 2008 Google, Inc. - * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved. - * Author: Iliyan Malchev - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _ARCH_ARM_MACH_MSM_ADSP_H -#define _ARCH_ARM_MACH_MSM_ADSP_H - -#include -#include -#include -#include -#include - -int adsp_pmem_fixup(struct msm_adsp_module *module, void **addr, - unsigned long len); -int adsp_pmem_fixup_kvaddr(struct msm_adsp_module *module, void **addr, - unsigned long *kvaddr, unsigned long len); -int adsp_pmem_paddr_fixup(struct msm_adsp_module *module, void **addr); - -int adsp_vfe_verify_cmd(struct msm_adsp_module *module, - unsigned int queue_id, void *cmd_data, - size_t cmd_size); -int adsp_jpeg_verify_cmd(struct msm_adsp_module *module, - unsigned int queue_id, void *cmd_data, - size_t cmd_size); -int adsp_lpm_verify_cmd(struct msm_adsp_module *module, - unsigned int queue_id, void *cmd_data, - size_t cmd_size); -int adsp_video_verify_cmd(struct msm_adsp_module *module, - unsigned int queue_id, void *cmd_data, - size_t cmd_size); -int adsp_videoenc_verify_cmd(struct msm_adsp_module *module, - unsigned int queue_id, void *cmd_data, - size_t cmd_size); - - -struct adsp_event; - -int adsp_vfe_patch_event(struct msm_adsp_module *module, - struct adsp_event *event); - -int adsp_jpeg_patch_event(struct msm_adsp_module *module, - struct adsp_event *event); - - -struct adsp_module_info { - const char *name; - const char *pdev_name; - uint32_t id; - const char *clk_name; - unsigned long clk_rate; - int (*verify_cmd) (struct msm_adsp_module*, unsigned int, void *, - size_t); - int (*patch_event) (struct msm_adsp_module*, struct adsp_event *); -}; - -#define ADSP_EVENT_MAX_SIZE 496 -#define EVENT_LEN 12 -#define EVENT_MSG_ID ((uint16_t)~0) - -struct adsp_event { - struct list_head list; - uint32_t size; /* always in bytes */ - uint16_t msg_id; - uint16_t type; /* 0 for msgs (from aDSP), -1 for events (from ARM9) */ - int is16; /* always 0 (msg is 32-bit) when the event type is 1(ARM9) */ - union { - uint16_t msg16[ADSP_EVENT_MAX_SIZE / 2]; - uint32_t msg32[ADSP_EVENT_MAX_SIZE / 4]; - } data; -}; - -#define DALRPC_ADSPSVC_DEVICEID 0x0200009A -#define DALRPC_ADSPSVC_DEST SMD_APPS_MODEM -#define DALRPC_ADSPSVC_PORT "DAL00" - -enum { - DALDEVICE_ADSP_CMD_IDX = DALDEVICE_FIRST_DEVICE_API_IDX, -}; - -struct adsp_rtos_atom_cmd { - uint32_t cmd; - uint32_t proc_id; - uint32_t module; - void *cb_handle; -}; - -enum rpc_adsp_rtos_proc_type { - RPC_ADSP_RTOS_PROC_NONE = 0, - RPC_ADSP_RTOS_PROC_MODEM = 1, - RPC_ADSP_RTOS_PROC_APPS = 2, -}; - -enum { - RPC_ADSP_RTOS_CMD_REGISTER_APP, - RPC_ADSP_RTOS_CMD_ENABLE, - RPC_ADSP_RTOS_CMD_DISABLE, - RPC_ADSP_RTOS_CMD_KERNEL_COMMAND, - RPC_ADSP_RTOS_CMD_16_COMMAND, - RPC_ADSP_RTOS_CMD_32_COMMAND, - RPC_ADSP_RTOS_CMD_DISABLE_EVENT_RSP, - RPC_ADSP_RTOS_CMD_REMOTE_EVENT, - RPC_ADSP_RTOS_CMD_SET_STATE, - RPC_ADSP_RTOS_CMD_REMOTE_INIT_INFO_EVENT, - RPC_ADSP_RTOS_CMD_GET_INIT_INFO, -}; - -enum rpc_adsp_rtos_mod_status_type { - RPC_ADSP_RTOS_MOD_READY, - RPC_ADSP_RTOS_MOD_DISABLE, - RPC_ADSP_RTOS_SERVICE_RESET, - RPC_ADSP_RTOS_CMD_FAIL, - RPC_ADSP_RTOS_CMD_SUCCESS, - RPC_ADSP_RTOS_INIT_INFO, - RPC_ADSP_RTOS_DISABLE_FAIL, -}; - -enum qdsp_image_type { - QDSP_IMAGE_COMBO, - QDSP_IMAGE_GAUDIO, - QDSP_IMAGE_QTV_LP, - QDSP_IMAGE_MAX, - /* DO NOT USE: Force this enum to be a 32bit type to improve speed */ - QDSP_IMAGE_32BIT_DUMMY = 0x10000 -}; - -struct adsp_rtos_mp_mtoa_header_type { - enum rpc_adsp_rtos_mod_status_type event; - uint32_t version; - enum rpc_adsp_rtos_proc_type proc_id; -}; - -/* ADSP RTOS MP Communications - Modem to APP's Event Info*/ -struct adsp_rtos_mp_mtoa_type { - uint32_t module; - uint32_t image; - uint32_t apps_okts; -}; - -/* ADSP RTOS MP Communications - Modem to APP's Init Info */ -#define IMG_MAX 2 -#define ENTRIES_MAX 36 -#define MODULES_MAX 64 -#define QUEUES_MAX 64 - -struct queue_to_offset_type { - uint32_t queue; - uint32_t offset; -}; - -struct mod_to_queue_offsets { - uint32_t module; - uint32_t q_type; - uint32_t q_max_len; -}; - -struct adsp_rtos_mp_mtoa_init_info_type { - uint32_t image_count; - uint32_t num_queue_offsets; - struct queue_to_offset_type queue_offsets_tbl[IMG_MAX][ENTRIES_MAX]; - uint32_t num_task_module_entries; - uint32_t task_to_module_tbl[IMG_MAX][ENTRIES_MAX]; - - uint32_t module_table_size; - uint32_t module_entries[MODULES_MAX]; - uint32_t mod_to_q_entries; - struct mod_to_queue_offsets mod_to_q_tbl[ENTRIES_MAX]; - /* - * queue_offsets[] is to store only queue_offsets - */ - uint32_t queue_offsets[IMG_MAX][QUEUES_MAX]; -}; - -struct adsp_rtos_mp_mtoa_s_type { - struct adsp_rtos_mp_mtoa_header_type mp_mtoa_header; - - union { - struct adsp_rtos_mp_mtoa_init_info_type mp_mtoa_init_packet; - struct adsp_rtos_mp_mtoa_type mp_mtoa_packet; - } adsp_rtos_mp_mtoa_data; -}; - -struct adsp_info { - uint32_t send_irq; - uint32_t read_ctrl; - uint32_t write_ctrl; - - uint32_t max_msg16_size; - uint32_t max_msg32_size; - - uint32_t max_task_id; - uint32_t max_module_id; - uint32_t max_queue_id; - uint32_t max_image_id; - - /* for each image id, a map of queue id to offset */ - uint32_t **queue_offset; - - /* for each image id, a map of task id to module id */ - uint32_t **task_to_module; - - /* for each module id, map of module id to module */ - struct msm_adsp_module **id_to_module; - - uint32_t module_count; - struct adsp_module_info *module; - - /* stats */ - uint32_t events_received; - uint32_t event_backlog_max; - - /* rpc_client for init_info */ - struct adsp_rtos_mp_mtoa_init_info_type *init_info_ptr; - struct adsp_rtos_mp_mtoa_s_type *raw_event; - wait_queue_head_t init_info_wait; - unsigned init_info_state; - - void *handle; - void *cb_handle; - - /* Interrupt value */ - int int_adsp; -}; - -#define ADSP_STATE_DISABLED 0 -#define ADSP_STATE_ENABLING 1 -#define ADSP_STATE_ENABLED 2 -#define ADSP_STATE_DISABLING 3 -#define ADSP_STATE_INIT_INFO 4 - -struct msm_adsp_module { - struct mutex lock; - const char *name; - unsigned id; - struct adsp_info *info; - - struct msm_adsp_ops *ops; - void *driver_data; - - /* statistics */ - unsigned num_commands; - unsigned num_events; - - wait_queue_head_t state_wait; - unsigned state; - - struct platform_device pdev; - struct clk *clk; - int open_count; - - struct mutex pmem_regions_lock; - struct hlist_head pmem_regions; - int (*verify_cmd) (struct msm_adsp_module*, unsigned int, void *, - size_t); - int (*patch_event) (struct msm_adsp_module*, struct adsp_event *); -}; - -extern void msm_adsp_publish_cdevs(struct msm_adsp_module *, unsigned); -extern int adsp_init_info(struct adsp_info *info); - -/* Value to indicate that a queue is not defined for a particular image */ -#define QDSP_RTOS_NO_QUEUE 0xfffffffe - -/* - * Constants used to communicate with the ADSP RTOS - */ -#define ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M 0x80000000U -#define ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V 0x80000000U -#define ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_AVAIL_V 0x00000000U - -#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_M 0x70000000U -#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_WRITE_REQ_V 0x00000000U -#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_WRITE_DONE_V 0x10000000U -#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_NO_CMD_V 0x70000000U - -#define ADSP_RTOS_WRITE_CTRL_WORD_STATUS_M 0x0E000000U -#define ADSP_RTOS_WRITE_CTRL_WORD_NO_ERR_V 0x00000000U -#define ADSP_RTOS_WRITE_CTRL_WORD_NO_FREE_BUF_V 0x02000000U - -#define ADSP_RTOS_WRITE_CTRL_WORD_KERNEL_FLG_M 0x01000000U -#define ADSP_RTOS_WRITE_CTRL_WORD_HTOD_MSG_WRITE_V 0x00000000U -#define ADSP_RTOS_WRITE_CTRL_WORD_HTOD_CMD_V 0x01000000U - -#define ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M 0x00FFFFFFU -#define ADSP_RTOS_WRITE_CTRL_WORD_HTOD_CMD_ID_M 0x00FFFFFFU - -/* Combination of MUTEX and CMD bits to check if the DSP is busy */ -#define ADSP_RTOS_WRITE_CTRL_WORD_READY_M 0xF0000000U -#define ADSP_RTOS_WRITE_CTRL_WORD_READY_V 0x70000000U - -/* RTOS to Host processor command mask values */ -#define ADSP_RTOS_READ_CTRL_WORD_FLAG_M 0x80000000U -#define ADSP_RTOS_READ_CTRL_WORD_FLAG_UP_WAIT_V 0x00000000U -#define ADSP_RTOS_READ_CTRL_WORD_FLAG_UP_CONT_V 0x80000000U - -#define ADSP_RTOS_READ_CTRL_WORD_CMD_M 0x60000000U -#define ADSP_RTOS_READ_CTRL_WORD_READ_DONE_V 0x00000000U -#define ADSP_RTOS_READ_CTRL_WORD_READ_REQ_V 0x20000000U -#define ADSP_RTOS_READ_CTRL_WORD_NO_CMD_V 0x60000000U - -/* Combination of FLAG and COMMAND bits to check if MSG ready */ -#define ADSP_RTOS_READ_CTRL_WORD_READY_M 0xE0000000U -#define ADSP_RTOS_READ_CTRL_WORD_READY_V 0xA0000000U -#define ADSP_RTOS_READ_CTRL_WORD_CONT_V 0xC0000000U -#define ADSP_RTOS_READ_CTRL_WORD_DONE_V 0xE0000000U - -#define ADSP_RTOS_READ_CTRL_WORD_STATUS_M 0x18000000U -#define ADSP_RTOS_READ_CTRL_WORD_NO_ERR_V 0x00000000U - -#define ADSP_RTOS_READ_CTRL_WORD_IN_PROG_M 0x04000000U -#define ADSP_RTOS_READ_CTRL_WORD_NO_READ_IN_PROG_V 0x00000000U -#define ADSP_RTOS_READ_CTRL_WORD_READ_IN_PROG_V 0x04000000U - -#define ADSP_RTOS_READ_CTRL_WORD_CMD_TYPE_M 0x03000000U -#define ADSP_RTOS_READ_CTRL_WORD_CMD_TASK_TO_H_V 0x00000000U -#define ADSP_RTOS_READ_CTRL_WORD_CMD_KRNL_TO_H_V 0x01000000U -#define ADSP_RTOS_READ_CTRL_WORD_CMD_H_TO_KRNL_CFM_V 0x02000000U - -#define ADSP_RTOS_READ_CTRL_WORD_DSP_ADDR_M 0x00FFFFFFU - -#define ADSP_RTOS_READ_CTRL_WORD_MSG_ID_M 0x000000FFU -#define ADSP_RTOS_READ_CTRL_WORD_TASK_ID_M 0x0000FF00U - -/* Base address of DSP and DSP hardware registers */ -#define QDSP_RAMC_OFFSET 0x400000 - -#endif diff --git a/arch/arm/mach-msm/qdsp5v2/adsp_driver.c b/arch/arm/mach-msm/qdsp5v2/adsp_driver.c deleted file mode 100644 index 7249bb1bfe54964b6d7b0ea85f12466693bb199a..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/adsp_driver.c +++ /dev/null @@ -1,656 +0,0 @@ -/* - * Copyright (C) 2008 Google, Inc. - * Copyright (c) 2009, The Linux Foundation. All rights reserved. - * Author: Iliyan Malchev - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "adsp.h" -#include -#include - -struct adsp_pmem_info { - int fd; - void *vaddr; -}; - -struct adsp_pmem_region { - struct hlist_node list; - void *vaddr; - unsigned long paddr; - unsigned long kvaddr; - unsigned long len; - struct file *file; -}; - -struct adsp_device { - struct msm_adsp_module *module; - - spinlock_t event_queue_lock; - wait_queue_head_t event_wait; - struct list_head event_queue; - int abort; - - const char *name; - struct device *device; - struct cdev cdev; -}; - -static struct adsp_device *inode_to_device(struct inode *inode); - -#define __CONTAINS(r, v, l) ({ \ - typeof(r) __r = r; \ - typeof(v) __v = v; \ - typeof(v) __e = __v + l; \ - int res = __v >= __r->vaddr && \ - __e <= __r->vaddr + __r->len; \ - res; \ -}) - -#define CONTAINS(r1, r2) ({ \ - typeof(r2) __r2 = r2; \ - __CONTAINS(r1, __r2->vaddr, __r2->len); \ -}) - -#define IN_RANGE(r, v) ({ \ - typeof(r) __r = r; \ - typeof(v) __vv = v; \ - int res = ((__vv >= __r->vaddr) && \ - (__vv < (__r->vaddr + __r->len))); \ - res; \ -}) - -#define OVERLAPS(r1, r2) ({ \ - typeof(r1) __r1 = r1; \ - typeof(r2) __r2 = r2; \ - typeof(__r2->vaddr) __v = __r2->vaddr; \ - typeof(__v) __e = __v + __r2->len - 1; \ - int res = (IN_RANGE(__r1, __v) || IN_RANGE(__r1, __e)); \ - res; \ -}) - -static int adsp_pmem_check(struct msm_adsp_module *module, - void *vaddr, unsigned long len) -{ - struct adsp_pmem_region *region_elt; - struct hlist_node *node; - struct adsp_pmem_region t = { .vaddr = vaddr, .len = len }; - - hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) { - if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) || - OVERLAPS(region_elt, &t)) { - MM_ERR("module %s:" - " region (vaddr %p len %ld)" - " clashes with registered region" - " (vaddr %p paddr %p len %ld)\n", - module->name, - vaddr, len, - region_elt->vaddr, - (void *)region_elt->paddr, - region_elt->len); - return -EINVAL; - } - } - - return 0; -} - -static int adsp_pmem_add(struct msm_adsp_module *module, - struct adsp_pmem_info *info) -{ - unsigned long paddr, kvaddr, len; - struct file *file; - struct adsp_pmem_region *region; - int rc = -EINVAL; - - mutex_lock(&module->pmem_regions_lock); - region = kmalloc(sizeof(*region), GFP_KERNEL); - if (!region) { - rc = -ENOMEM; - goto end; - } - INIT_HLIST_NODE(®ion->list); - if (get_pmem_file(info->fd, &paddr, &kvaddr, &len, &file)) { - kfree(region); - goto end; - } - - rc = adsp_pmem_check(module, info->vaddr, len); - if (rc < 0) { - put_pmem_file(file); - kfree(region); - goto end; - } - - region->vaddr = info->vaddr; - region->paddr = paddr; - region->kvaddr = kvaddr; - region->len = len; - region->file = file; - - hlist_add_head(®ion->list, &module->pmem_regions); -end: - mutex_unlock(&module->pmem_regions_lock); - return rc; -} - -static int adsp_pmem_lookup_vaddr(struct msm_adsp_module *module, void **addr, - unsigned long len, struct adsp_pmem_region **region) -{ - struct hlist_node *node; - void *vaddr = *addr; - struct adsp_pmem_region *region_elt; - - int match_count = 0; - - *region = NULL; - - /* returns physical address or zero */ - hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) { - if (vaddr >= region_elt->vaddr && - vaddr < region_elt->vaddr + region_elt->len && - vaddr + len <= region_elt->vaddr + region_elt->len) { - /* offset since we could pass vaddr inside a registerd - * pmem buffer - */ - - match_count++; - if (!*region) - *region = region_elt; - } - } - - if (match_count > 1) { - MM_ERR("module %s: " - "multiple hits for vaddr %p, len %ld\n", - module->name, vaddr, len); - hlist_for_each_entry(region_elt, node, - &module->pmem_regions, list) { - if (vaddr >= region_elt->vaddr && - vaddr < region_elt->vaddr + region_elt->len && - vaddr + len <= region_elt->vaddr + region_elt->len) - MM_ERR("%p, %ld --> %p\n", - region_elt->vaddr, - region_elt->len, - (void *)region_elt->paddr); - } - } - - return *region ? 0 : -1; -} - -int adsp_pmem_fixup_kvaddr(struct msm_adsp_module *module, void **addr, - unsigned long *kvaddr, unsigned long len) -{ - struct adsp_pmem_region *region; - void *vaddr = *addr; - unsigned long *paddr = (unsigned long *)addr; - int ret; - - ret = adsp_pmem_lookup_vaddr(module, addr, len, ®ion); - if (ret) { - MM_ERR("not patching %s (paddr & kvaddr)," - " lookup (%p, %ld) failed\n", - module->name, vaddr, len); - return ret; - } - *paddr = region->paddr + (vaddr - region->vaddr); - *kvaddr = region->kvaddr + (vaddr - region->vaddr); - return 0; -} - -int adsp_pmem_fixup(struct msm_adsp_module *module, void **addr, - unsigned long len) -{ - struct adsp_pmem_region *region; - void *vaddr = *addr; - unsigned long *paddr = (unsigned long *)addr; - int ret; - - ret = adsp_pmem_lookup_vaddr(module, addr, len, ®ion); - if (ret) { - MM_ERR("not patching %s, lookup (%p, %ld) failed\n", - module->name, vaddr, len); - return ret; - } - - *paddr = region->paddr + (vaddr - region->vaddr); - return 0; -} - -static int adsp_verify_cmd(struct msm_adsp_module *module, - unsigned int queue_id, void *cmd_data, - size_t cmd_size) -{ - /* call the per module verifier */ - if (module->verify_cmd) - return module->verify_cmd(module, queue_id, cmd_data, - cmd_size); - else - MM_INFO("no packet verifying function " - "for task %s\n", module->name); - return 0; -} - -static long adsp_write_cmd(struct adsp_device *adev, void __user *arg) -{ - struct adsp_command_t cmd; - unsigned char buf[256]; - void *cmd_data; - long rc; - - if (copy_from_user(&cmd, (void __user *)arg, sizeof(cmd))) - return -EFAULT; - - if (cmd.len > 256) { - cmd_data = kmalloc(cmd.len, GFP_USER); - if (!cmd_data) - return -ENOMEM; - } else { - cmd_data = buf; - } - - if (copy_from_user(cmd_data, (void __user *)(cmd.data), cmd.len)) { - rc = -EFAULT; - goto end; - } - - mutex_lock(&adev->module->pmem_regions_lock); - if (adsp_verify_cmd(adev->module, cmd.queue, cmd_data, cmd.len)) { - MM_ERR("module %s: verify failed.\n", adev->module->name); - rc = -EINVAL; - goto end; - } - rc = msm_adsp_write(adev->module, cmd.queue, cmd_data, cmd.len); -end: - mutex_unlock(&adev->module->pmem_regions_lock); - - if (cmd.len > 256) - kfree(cmd_data); - - return rc; -} - -static int adsp_events_pending(struct adsp_device *adev) -{ - unsigned long flags; - int yes; - spin_lock_irqsave(&adev->event_queue_lock, flags); - yes = !list_empty(&adev->event_queue); - spin_unlock_irqrestore(&adev->event_queue_lock, flags); - return yes || adev->abort; -} - -static int adsp_pmem_lookup_paddr(struct msm_adsp_module *module, void **addr, - struct adsp_pmem_region **region) -{ - struct hlist_node *node; - unsigned long paddr = (unsigned long)(*addr); - struct adsp_pmem_region *region_elt; - - hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) { - if (paddr >= region_elt->paddr && - paddr < region_elt->paddr + region_elt->len) { - *region = region_elt; - return 0; - } - } - return -1; -} - -int adsp_pmem_paddr_fixup(struct msm_adsp_module *module, void **addr) -{ - struct adsp_pmem_region *region; - unsigned long paddr = (unsigned long)(*addr); - unsigned long *vaddr = (unsigned long *)addr; - int ret; - - ret = adsp_pmem_lookup_paddr(module, addr, ®ion); - if (ret) { - MM_ERR("not patching %s, paddr %p lookup failed\n", - module->name, vaddr); - return ret; - } - - *vaddr = (unsigned long)region->vaddr + (paddr - region->paddr); - return 0; -} - -static int adsp_patch_event(struct msm_adsp_module *module, - struct adsp_event *event) -{ - /* call the per-module msg verifier */ - if (module->patch_event) - return module->patch_event(module, event); - return 0; -} - -static long adsp_get_event(struct adsp_device *adev, void __user *arg) -{ - unsigned long flags; - struct adsp_event *data = NULL; - struct adsp_event_t evt; - int timeout; - long rc = 0; - - if (copy_from_user(&evt, arg, sizeof(struct adsp_event_t))) - return -EFAULT; - - timeout = (int)evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - adev->event_wait, adsp_events_pending(adev), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - adev->event_wait, adsp_events_pending(adev)); - } - if (rc < 0) - return rc; - - if (adev->abort) - return -ENODEV; - - spin_lock_irqsave(&adev->event_queue_lock, flags); - if (!list_empty(&adev->event_queue)) { - data = list_first_entry(&adev->event_queue, - struct adsp_event, list); - list_del(&data->list); - } - spin_unlock_irqrestore(&adev->event_queue_lock, flags); - - if (!data) - return -EAGAIN; - - /* DSP messages are type 0; they may contain physical addresses */ - if (data->type == 0) - adsp_patch_event(adev->module, data); - - /* map adsp_event --> adsp_event_t */ - if (evt.len < data->size) { - rc = -ETOOSMALL; - goto end; - } - if (data->msg_id != EVENT_MSG_ID) { - if (copy_to_user((void *)(evt.data), data->data.msg16, - data->size)) { - rc = -EFAULT; - goto end; - } - } else { - if (copy_to_user((void *)(evt.data), data->data.msg32, - data->size)) { - rc = -EFAULT; - goto end; - } - } - - evt.type = data->type; /* 0 --> from aDSP, 1 --> from ARM9 */ - evt.msg_id = data->msg_id; - evt.flags = data->is16; - evt.len = data->size; - if (copy_to_user(arg, &evt, sizeof(evt))) - rc = -EFAULT; -end: - kfree(data); - return rc; -} - -static int adsp_pmem_del(struct msm_adsp_module *module) -{ - struct hlist_node *node, *tmp; - struct adsp_pmem_region *region; - - mutex_lock(&module->pmem_regions_lock); - hlist_for_each_safe(node, tmp, &module->pmem_regions) { - region = hlist_entry(node, struct adsp_pmem_region, list); - hlist_del(node); - put_pmem_file(region->file); - kfree(region); - } - mutex_unlock(&module->pmem_regions_lock); - BUG_ON(!hlist_empty(&module->pmem_regions)); - - return 0; -} - -static long adsp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - struct adsp_device *adev = filp->private_data; - - switch (cmd) { - case ADSP_IOCTL_ENABLE: - return msm_adsp_enable(adev->module); - - case ADSP_IOCTL_DISABLE: - return msm_adsp_disable(adev->module); - - case ADSP_IOCTL_DISABLE_EVENT_RSP: - return msm_adsp_disable_event_rsp(adev->module); - - case ADSP_IOCTL_DISABLE_ACK: - MM_ERR("ADSP_IOCTL_DISABLE_ACK is not implemented\n"); - break; - - case ADSP_IOCTL_WRITE_COMMAND: - return adsp_write_cmd(adev, (void __user *) arg); - - case ADSP_IOCTL_GET_EVENT: - return adsp_get_event(adev, (void __user *) arg); - - case ADSP_IOCTL_SET_CLKRATE: { - unsigned long clk_rate; - if (copy_from_user(&clk_rate, (void *) arg, sizeof(clk_rate))) - return -EFAULT; - return adsp_set_clkrate(adev->module, clk_rate); - } - - case ADSP_IOCTL_REGISTER_PMEM: { - struct adsp_pmem_info info; - if (copy_from_user(&info, (void *) arg, sizeof(info))) - return -EFAULT; - return adsp_pmem_add(adev->module, &info); - } - - case ADSP_IOCTL_ABORT_EVENT_READ: - adev->abort = 1; - wake_up(&adev->event_wait); - break; - - case ADSP_IOCTL_UNREGISTER_PMEM: - return adsp_pmem_del(adev->module); - - default: - break; - } - return -EINVAL; -} - -static int adsp_release(struct inode *inode, struct file *filp) -{ - struct adsp_device *adev = filp->private_data; - struct msm_adsp_module *module = adev->module; - int rc = 0; - - MM_INFO("release '%s'\n", adev->name); - - /* clear module before putting it to avoid race with open() */ - adev->module = NULL; - - rc = adsp_pmem_del(module); - - msm_adsp_put(module); - return rc; -} - -static void adsp_event(void *driver_data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - struct adsp_device *adev = driver_data; - struct adsp_event *event; - unsigned long flags; - - if (len > ADSP_EVENT_MAX_SIZE) { - MM_ERR("event too large (%d bytes)\n", len); - return; - } - - event = kmalloc(sizeof(*event), GFP_ATOMIC); - if (!event) { - MM_ERR("cannot allocate buffer\n"); - return; - } - - if (id != EVENT_MSG_ID) { - event->type = 0; - event->is16 = 0; - event->msg_id = id; - event->size = len; - - getevent(event->data.msg16, len); - } else { - event->type = 1; - event->is16 = 1; - event->msg_id = id; - event->size = len; - getevent(event->data.msg32, len); - } - - spin_lock_irqsave(&adev->event_queue_lock, flags); - list_add_tail(&event->list, &adev->event_queue); - spin_unlock_irqrestore(&adev->event_queue_lock, flags); - wake_up(&adev->event_wait); -} - -static struct msm_adsp_ops adsp_ops = { - .event = adsp_event, -}; - -static int adsp_open(struct inode *inode, struct file *filp) -{ - struct adsp_device *adev; - int rc; - - rc = nonseekable_open(inode, filp); - if (rc < 0) - return rc; - - adev = inode_to_device(inode); - if (!adev) - return -ENODEV; - - MM_INFO("open '%s'\n", adev->name); - - rc = msm_adsp_get(adev->name, &adev->module, &adsp_ops, adev); - if (rc) - return rc; - - MM_INFO("opened module '%s' adev %p\n", adev->name, adev); - filp->private_data = adev; - adev->abort = 0; - INIT_HLIST_HEAD(&adev->module->pmem_regions); - mutex_init(&adev->module->pmem_regions_lock); - - return 0; -} - -static unsigned adsp_device_count; -static struct adsp_device *adsp_devices; - -static struct adsp_device *inode_to_device(struct inode *inode) -{ - unsigned n = MINOR(inode->i_rdev); - if (n < adsp_device_count) { - if (adsp_devices[n].device) - return adsp_devices + n; - } - return NULL; -} - -static dev_t adsp_devno; -static struct class *adsp_class; - -static const struct file_operations adsp_fops = { - .owner = THIS_MODULE, - .open = adsp_open, - .unlocked_ioctl = adsp_ioctl, - .release = adsp_release, -}; - -static void adsp_create(struct adsp_device *adev, const char *name, - struct device *parent, dev_t devt) -{ - struct device *dev; - int rc; - - dev = device_create(adsp_class, parent, devt, "%s", name); - if (IS_ERR(dev)) - return; - - init_waitqueue_head(&adev->event_wait); - INIT_LIST_HEAD(&adev->event_queue); - spin_lock_init(&adev->event_queue_lock); - - cdev_init(&adev->cdev, &adsp_fops); - adev->cdev.owner = THIS_MODULE; - - rc = cdev_add(&adev->cdev, devt, 1); - if (rc < 0) { - device_destroy(adsp_class, devt); - } else { - adev->device = dev; - adev->name = name; - } -} - -void msm_adsp_publish_cdevs(struct msm_adsp_module *modules, unsigned n) -{ - int rc; - - adsp_devices = kzalloc(sizeof(struct adsp_device) * n, GFP_KERNEL); - if (!adsp_devices) - return; - - adsp_class = class_create(THIS_MODULE, "adsp"); - if (IS_ERR(adsp_class)) - goto fail_create_class; - - rc = alloc_chrdev_region(&adsp_devno, 0, n, "adsp"); - if (rc < 0) - goto fail_alloc_region; - - adsp_device_count = n; - for (n = 0; n < adsp_device_count; n++) { - adsp_create(adsp_devices + n, - modules[n].name, &modules[n].pdev.dev, - MKDEV(MAJOR(adsp_devno), n)); - } - - return; - -fail_alloc_region: - class_unregister(adsp_class); -fail_create_class: - kfree(adsp_devices); -} diff --git a/arch/arm/mach-msm/qdsp5v2/adsp_info.c b/arch/arm/mach-msm/qdsp5v2/adsp_info.c deleted file mode 100644 index 03b810d738369ee066d5f6b9b4f17ec069a0825c..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/adsp_info.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2008-2010, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include "adsp.h" - -/* Firmware modules */ -#define QDSP_MODULE_KERNEL 0x0106dd4e -#define QDSP_MODULE_AFETASK 0x0106dd6f -#define QDSP_MODULE_AUDPLAY0TASK 0x0106dd70 -#define QDSP_MODULE_AUDPLAY1TASK 0x0106dd71 -#define QDSP_MODULE_AUDPPTASK 0x0106dd72 -#define QDSP_MODULE_VIDEOTASK 0x0106dd73 -#define QDSP_MODULE_VIDEO_AAC_VOC 0x0106dd74 -#define QDSP_MODULE_PCM_DEC 0x0106dd75 -#define QDSP_MODULE_AUDIO_DEC_MP3 0x0106dd76 -#define QDSP_MODULE_AUDIO_DEC_AAC 0x0106dd77 -#define QDSP_MODULE_AUDIO_DEC_WMA 0x0106dd78 -#define QDSP_MODULE_HOSTPCM 0x0106dd79 -#define QDSP_MODULE_DTMF 0x0106dd7a -#define QDSP_MODULE_AUDRECTASK 0x0106dd7b -#define QDSP_MODULE_AUDPREPROCTASK 0x0106dd7c -#define QDSP_MODULE_SBC_ENC 0x0106dd7d -#define QDSP_MODULE_VOC_UMTS 0x0106dd9a -#define QDSP_MODULE_VOC_CDMA 0x0106dd98 -#define QDSP_MODULE_VOC_PCM 0x0106dd7f -#define QDSP_MODULE_VOCENCTASK 0x0106dd80 -#define QDSP_MODULE_VOCDECTASK 0x0106dd81 -#define QDSP_MODULE_VOICEPROCTASK 0x0106dd82 -#define QDSP_MODULE_VIDEOENCTASK 0x0106dd83 -#define QDSP_MODULE_VFETASK 0x0106dd84 -#define QDSP_MODULE_WAV_ENC 0x0106dd85 -#define QDSP_MODULE_AACLC_ENC 0x0106dd86 -#define QDSP_MODULE_VIDEO_AMR 0x0106dd87 -#define QDSP_MODULE_VOC_AMR 0x0106dd88 -#define QDSP_MODULE_VOC_EVRC 0x0106dd89 -#define QDSP_MODULE_VOC_13K 0x0106dd8a -#define QDSP_MODULE_VOC_FGV 0x0106dd8b -#define QDSP_MODULE_DIAGTASK 0x0106dd8c -#define QDSP_MODULE_JPEGTASK 0x0106dd8d -#define QDSP_MODULE_LPMTASK 0x0106dd8e -#define QDSP_MODULE_QCAMTASK 0x0106dd8f -#define QDSP_MODULE_MODMATHTASK 0x0106dd90 -#define QDSP_MODULE_AUDPLAY2TASK 0x0106dd91 -#define QDSP_MODULE_AUDPLAY3TASK 0x0106dd92 -#define QDSP_MODULE_AUDPLAY4TASK 0x0106dd93 -#define QDSP_MODULE_GRAPHICSTASK 0x0106dd94 -#define QDSP_MODULE_MIDI 0x0106dd95 -#define QDSP_MODULE_GAUDIO 0x0106dd96 -#define QDSP_MODULE_VDEC_LP_MODE 0x0106dd97 -#define QDSP_MODULE_VIDEO_AAC_VOC_TURBO 0x01089f77 -#define QDSP_MODULE_VIDEO_AMR_TURBO 0x01089f78 -#define QDSP_MODULE_WM_TURBO_MODE 0x01089f79 -#define QDSP_MODULE_VDEC_LP_MODE_TURBO 0x01089f7a -#define QDSP_MODULE_AUDREC0TASK 0x0109696f -#define QDSP_MODULE_AUDREC1TASK 0x01096970 -#define QDSP_MODULE_AUDREC2TASK 0x010a2f59 -#define QDSP_MODULE_MAX 0x7fffffff - - /* DO NOT USE: Force this enum to be a 32bit type to improve speed */ -#define QDSP_MODULE_32BIT_DUMMY 0x10000 - -static uint32_t *qdsp_task_to_module[IMG_MAX]; -static uint32_t *qdsp_queue_offset_table[IMG_MAX]; - -#define QDSP_MODULE(n, clkname, clkrate, verify_cmd_func, patch_event_func) \ - { .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n, \ - .clk_name = clkname, .clk_rate = clkrate, \ - .verify_cmd = verify_cmd_func, .patch_event = patch_event_func } - -static struct adsp_module_info module_info[] = { - QDSP_MODULE(AUDPLAY0TASK, NULL, 0, NULL, NULL), - QDSP_MODULE(AUDPLAY1TASK, NULL, 0, NULL, NULL), - QDSP_MODULE(AUDPLAY2TASK, NULL, 0, NULL, NULL), - QDSP_MODULE(AUDPLAY3TASK, NULL, 0, NULL, NULL), - QDSP_MODULE(AUDPPTASK, NULL, 0, NULL, NULL), - QDSP_MODULE(AUDPREPROCTASK, NULL, 0, NULL, NULL), - QDSP_MODULE(AFETASK , NULL, 0, NULL, NULL), - QDSP_MODULE(AUDREC0TASK, NULL, 0, NULL, NULL), - QDSP_MODULE(AUDREC1TASK, NULL, 0, NULL, NULL), - QDSP_MODULE(AUDREC2TASK, NULL, 0, NULL, NULL), -}; - -int adsp_init_info(struct adsp_info *info) -{ - uint32_t img_num; - - info->send_irq = 0x00c00200; - info->read_ctrl = 0x00400038; - info->write_ctrl = 0x00400034; - - info->max_msg16_size = 193; - info->max_msg32_size = 8; - for (img_num = 0; img_num < IMG_MAX; img_num++) - qdsp_queue_offset_table[img_num] = - &info->init_info_ptr->queue_offsets[img_num][0]; - - for (img_num = 0; img_num < IMG_MAX; img_num++) - qdsp_task_to_module[img_num] = - &info->init_info_ptr->task_to_module_tbl[img_num][0]; - info->max_task_id = ENTRIES_MAX; - info->max_module_id = QDSP_MODULE_MAX - 1; - info->max_queue_id = QDSP_MAX_NUM_QUEUES; - info->max_image_id = 0; - info->queue_offset = qdsp_queue_offset_table; - info->task_to_module = qdsp_task_to_module; - - info->module_count = ARRAY_SIZE(module_info); - info->module = module_info; - return 0; -} diff --git a/arch/arm/mach-msm/qdsp5v2/afe.c b/arch/arm/mach-msm/qdsp5v2/afe.c deleted file mode 100644 index 1e856e5d9247f9feddab77701e311b62351e4ca2..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/afe.c +++ /dev/null @@ -1,534 +0,0 @@ -/* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define AFE_MAX_TIMEOUT 500 /* 500 ms */ -#define AFE_MAX_CLNT 6 /* 6 HW path defined so far */ -#define GETDEVICEID(x) ((x) - 1) - -struct msm_afe_state { - struct msm_adsp_module *mod; - struct msm_adsp_ops adsp_ops; - struct mutex lock; - u8 in_use; - u8 codec_config[AFE_MAX_CLNT]; - wait_queue_head_t wait; - u8 aux_conf_flag; -}; - -#ifdef CONFIG_DEBUG_FS -static struct dentry *debugfs_afelb; -#endif - - -static struct msm_afe_state the_afe_state; - -#define afe_send_queue(afe, cmd, len) \ - msm_adsp_write(afe->mod, QDSP_apuAfeQueue, \ - cmd, len) - -static void afe_dsp_event(void *data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - struct msm_afe_state *afe = data; - - MM_DBG("msg_id %d \n", id); - - switch (id) { - case AFE_APU_MSG_CODEC_CONFIG_ACK: { - struct afe_msg_codec_config_ack afe_ack; - getevent(&afe_ack, AFE_APU_MSG_CODEC_CONFIG_ACK_LEN); - MM_DBG("%s: device_id: %d device activity: %d\n", __func__, - afe_ack.device_id, afe_ack.device_activity); - if (afe_ack.device_activity == AFE_MSG_CODEC_CONFIG_DISABLED) - afe->codec_config[GETDEVICEID(afe_ack.device_id)] = 0; - else - afe->codec_config[GETDEVICEID(afe_ack.device_id)] = - afe_ack.device_activity; - - wake_up(&afe->wait); - break; - } - case AFE_APU_MSG_VOC_TIMING_SUCCESS: - MM_INFO("Received VOC_TIMING_SUCCESS message from AFETASK\n"); - break; - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable/disable(audpptask)"); - break; - default: - MM_ERR("unexpected message from afe \n"); - } - - return; -} - -static void afe_dsp_codec_config(struct msm_afe_state *afe, - u8 path_id, u8 enable, struct msm_afe_config *config) -{ - struct afe_cmd_codec_config cmd; - - MM_DBG("%s() %p\n", __func__, config); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AFE_CMD_CODEC_CONFIG_CMD; - cmd.device_id = path_id; - cmd.activity = enable; - if (config) { - MM_DBG("%s: sample_rate %x ch mode %x vol %x\n", - __func__, config->sample_rate, - config->channel_mode, config->volume); - cmd.sample_rate = config->sample_rate; - cmd.channel_mode = config->channel_mode; - cmd.volume = config->volume; - } - afe_send_queue(afe, &cmd, sizeof(cmd)); -} -/* Function is called after afe module been enabled */ -void afe_loopback(int enable) -{ - struct afe_cmd_loopback cmd; - struct msm_afe_state *afe; - - afe = &the_afe_state; - MM_DBG("enable %d\n", enable); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AFE_CMD_LOOPBACK; - if (enable) - cmd.enable_flag = AFE_LOOPBACK_ENABLE_COMMAND; - - afe_send_queue(afe, &cmd, sizeof(cmd)); -} -EXPORT_SYMBOL(afe_loopback); - -void afe_ext_loopback(int enable, int rx_copp_id, int tx_copp_id) -{ - struct afe_cmd_ext_loopback cmd; - struct msm_afe_state *afe; - - afe = &the_afe_state; - MM_DBG("enable %d\n", enable); - if ((rx_copp_id == 0) && (tx_copp_id == 0)) { - afe_loopback(enable); - } else { - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AFE_CMD_EXT_LOOPBACK; - cmd.source_id = tx_copp_id; - cmd.dst_id = rx_copp_id; - if (enable) - cmd.enable_flag = AFE_LOOPBACK_ENABLE_COMMAND; - - afe_send_queue(afe, &cmd, sizeof(cmd)); - } -} -EXPORT_SYMBOL(afe_ext_loopback); - -void afe_device_volume_ctrl(u16 device_id, u16 device_volume) -{ - struct afe_cmd_device_volume_ctrl cmd; - struct msm_afe_state *afe; - - afe = &the_afe_state; - MM_DBG("device 0x%4x volume 0x%4x\n", device_id, device_volume); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AFE_CMD_DEVICE_VOLUME_CTRL; - cmd.device_id = device_id; - cmd.device_volume = device_volume; - afe_send_queue(afe, &cmd, sizeof(cmd)); -} -EXPORT_SYMBOL(afe_device_volume_ctrl); - -int afe_enable(u8 path_id, struct msm_afe_config *config) -{ - struct msm_afe_state *afe = &the_afe_state; - int rc; - - MM_DBG("%s: path %d\n", __func__, path_id); - if ((GETDEVICEID(path_id) < 0) || (GETDEVICEID(path_id) > 5)) { - MM_ERR("Invalid path_id: %d\n", path_id); - return -EINVAL; - } - mutex_lock(&afe->lock); - if (!afe->in_use && !afe->aux_conf_flag) { - /* enable afe */ - rc = msm_adsp_get("AFETASK", &afe->mod, &afe->adsp_ops, afe); - if (rc < 0) { - MM_ERR("%s: failed to get AFETASK module\n", __func__); - goto error_adsp_get; - } - rc = msm_adsp_enable(afe->mod); - if (rc < 0) - goto error_adsp_enable; - } - /* Issue codec config command */ - afe_dsp_codec_config(afe, path_id, 1, config); - rc = wait_event_timeout(afe->wait, - afe->codec_config[GETDEVICEID(path_id)], - msecs_to_jiffies(AFE_MAX_TIMEOUT)); - if (!rc) { - MM_ERR("AFE failed to respond within %d ms\n", AFE_MAX_TIMEOUT); - rc = -ENODEV; - if (!afe->in_use) { - if (!afe->aux_conf_flag || - (afe->aux_conf_flag && - (path_id == AFE_HW_PATH_AUXPCM_RX || - path_id == AFE_HW_PATH_AUXPCM_TX))) { - /* clean up if there is no client */ - msm_adsp_disable(afe->mod); - msm_adsp_put(afe->mod); - afe->aux_conf_flag = 0; - afe->mod = NULL; - } - } - - } else { - rc = 0; - afe->in_use++; - } - - mutex_unlock(&afe->lock); - return rc; - -error_adsp_enable: - msm_adsp_put(afe->mod); - afe->mod = NULL; -error_adsp_get: - mutex_unlock(&afe->lock); - return rc; -} -EXPORT_SYMBOL(afe_enable); - -int afe_config_fm_codec(int fm_enable, uint16_t source) -{ - struct afe_cmd_fm_codec_config cmd; - struct msm_afe_state *afe = &the_afe_state; - int rc = 0; - int i = 0; - unsigned short *ptrmem = (unsigned short *)&cmd; - - MM_INFO(" configure fm codec\n"); - mutex_lock(&afe->lock); - if (!afe->in_use) { - /* enable afe */ - rc = msm_adsp_get("AFETASK", &afe->mod, &afe->adsp_ops, afe); - if (rc < 0) { - MM_ERR("%s: failed to get AFETASK module\n", __func__); - goto error_adsp_get; - } - rc = msm_adsp_enable(afe->mod); - if (rc < 0) - goto error_adsp_enable; - } - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AFE_CMD_FM_RX_ROUTING_CMD; - cmd.enable = fm_enable; - cmd.device_id = source; - - for (i = 0; i < sizeof(cmd)/2; i++, ++ptrmem) - MM_DBG("cmd[%d]=0x%04x\n", i, *ptrmem); - afe_send_queue(afe, &cmd, sizeof(cmd)); - - mutex_unlock(&afe->lock); - return rc; -error_adsp_enable: - msm_adsp_put(afe->mod); - afe->mod = NULL; -error_adsp_get: - mutex_unlock(&afe->lock); - return rc; -} -EXPORT_SYMBOL(afe_config_fm_codec); - -int afe_config_fm_volume(uint16_t volume) -{ - struct afe_cmd_fm_volume_config cmd; - struct msm_afe_state *afe = &the_afe_state; - int rc = 0; - - MM_INFO(" configure fm volume\n"); - mutex_lock(&afe->lock); - if (!afe->in_use) { - /* enable afe */ - rc = msm_adsp_get("AFETASK", &afe->mod, &afe->adsp_ops, afe); - if (rc < 0) { - MM_ERR("%s: failed to get AFETASK module\n", __func__); - goto error_adsp_get; - } - rc = msm_adsp_enable(afe->mod); - if (rc < 0) - goto error_adsp_enable; - } - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AFE_CMD_FM_PLAYBACK_VOLUME_CMD; - cmd.volume = volume; - - afe_send_queue(afe, &cmd, sizeof(cmd)); - - mutex_unlock(&afe->lock); - return rc; -error_adsp_enable: - msm_adsp_put(afe->mod); - afe->mod = NULL; -error_adsp_get: - mutex_unlock(&afe->lock); - return rc; -} -EXPORT_SYMBOL(afe_config_fm_volume); - -int afe_config_fm_calibration_gain(uint16_t device_id, - uint16_t calibration_gain) -{ - struct afe_cmd_fm_calibgain_config cmd; - struct msm_afe_state *afe = &the_afe_state; - int rc = 0; - - MM_INFO("Configure for rx device = 0x%4x, gain = 0x%4x\n", device_id, - calibration_gain); - mutex_lock(&afe->lock); - if (!afe->in_use) { - /* enable afe */ - rc = msm_adsp_get("AFETASK", &afe->mod, &afe->adsp_ops, afe); - if (rc < 0) { - MM_ERR("%s: failed to get AFETASK module\n", __func__); - goto error_adsp_get; - } - rc = msm_adsp_enable(afe->mod); - if (rc < 0) - goto error_adsp_enable; - } - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AFE_CMD_FM_CALIBRATION_GAIN_CMD; - cmd.device_id = device_id; - cmd.calibration_gain = calibration_gain; - - afe_send_queue(afe, &cmd, sizeof(cmd)); - - mutex_unlock(&afe->lock); - return rc; -error_adsp_enable: - msm_adsp_put(afe->mod); - afe->mod = NULL; -error_adsp_get: - mutex_unlock(&afe->lock); - return rc; -} -EXPORT_SYMBOL(afe_config_fm_calibration_gain); - -int afe_config_aux_codec(int pcm_ctl_value, int aux_codec_intf_value, - int data_format_pad) -{ - struct afe_cmd_aux_codec_config cmd; - struct msm_afe_state *afe = &the_afe_state; - int rc = 0; - - MM_DBG(" configure aux codec \n"); - mutex_lock(&afe->lock); - if (!afe->in_use && !afe->aux_conf_flag) { - /* enable afe */ - rc = msm_adsp_get("AFETASK", &afe->mod, &afe->adsp_ops, afe); - if (rc < 0) { - MM_ERR("%s: failed to get AFETASK module\n", __func__); - goto error_adsp_get; - } - rc = msm_adsp_enable(afe->mod); - if (rc < 0) - goto error_adsp_enable; - } - afe->aux_conf_flag = 1; - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AFE_CMD_AUX_CODEC_CONFIG_CMD; - cmd.dma_path_ctl = 0; - cmd.pcm_ctl = pcm_ctl_value; - cmd.eight_khz_int_mode = 0; - cmd.aux_codec_intf_ctl = aux_codec_intf_value; - cmd.data_format_padding_info = data_format_pad; - - afe_send_queue(afe, &cmd, sizeof(cmd)); - - mutex_unlock(&afe->lock); - return rc; -error_adsp_enable: - msm_adsp_put(afe->mod); - afe->mod = NULL; -error_adsp_get: - mutex_unlock(&afe->lock); - return rc; -} -EXPORT_SYMBOL(afe_config_aux_codec); - -int afe_config_rmc_block(struct acdb_rmc_block *acdb_rmc) -{ - struct afe_cmd_cfg_rmc cmd; - struct msm_afe_state *afe = &the_afe_state; - int rc = 0; - int i = 0; - unsigned short *ptrmem = (unsigned short *)&cmd; - - MM_DBG(" configure rmc block\n"); - mutex_lock(&afe->lock); - if (!afe->in_use && !afe->mod) { - /* enable afe */ - rc = msm_adsp_get("AFETASK", &afe->mod, &afe->adsp_ops, afe); - if (rc < 0) { - MM_DBG("%s: failed to get AFETASK module\n", __func__); - goto error_adsp_get; - } - rc = msm_adsp_enable(afe->mod); - if (rc < 0) - goto error_adsp_enable; - } - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AFE_CMD_CFG_RMC_PARAMS; - - cmd.rmc_mode = acdb_rmc->rmc_enable; - cmd.rmc_ipw_length_ms = acdb_rmc->rmc_ipw_length_ms; - cmd.rmc_peak_length_ms = acdb_rmc->rmc_peak_length_ms; - cmd.rmc_init_pulse_length_ms = acdb_rmc->rmc_init_pulse_length_ms; - cmd.rmc_total_int_length_ms = acdb_rmc->rmc_total_int_length_ms; - cmd.rmc_rampupdn_length_ms = acdb_rmc->rmc_rampupdn_length_ms; - cmd.rmc_delay_length_ms = acdb_rmc->rmc_delay_length_ms; - cmd.rmc_detect_start_threshdb = acdb_rmc->rmc_detect_start_threshdb; - cmd.rmc_init_pulse_threshdb = acdb_rmc->rmc_init_pulse_threshdb; - - for (i = 0; i < sizeof(cmd)/2; i++, ++ptrmem) - MM_DBG("cmd[%d]=0x%04x\n", i, *ptrmem); - afe_send_queue(afe, &cmd, sizeof(cmd)); - - mutex_unlock(&afe->lock); - return rc; -error_adsp_enable: - msm_adsp_put(afe->mod); - afe->mod = NULL; -error_adsp_get: - mutex_unlock(&afe->lock); - return rc; -} -EXPORT_SYMBOL(afe_config_rmc_block); - -int afe_disable(u8 path_id) -{ - struct msm_afe_state *afe = &the_afe_state; - int rc; - - mutex_lock(&afe->lock); - - BUG_ON(!afe->in_use); - MM_DBG("%s() path_id:%d codec state:%d\n", __func__, path_id, - afe->codec_config[GETDEVICEID(path_id)]); - afe_dsp_codec_config(afe, path_id, 0, NULL); - rc = wait_event_timeout(afe->wait, - !afe->codec_config[GETDEVICEID(path_id)], - msecs_to_jiffies(AFE_MAX_TIMEOUT)); - if (!rc) { - MM_ERR("AFE failed to respond within %d ms\n", AFE_MAX_TIMEOUT); - rc = -1; - } else - rc = 0; - afe->in_use--; - MM_DBG("%s() in_use:%d \n", __func__, afe->in_use); - if (!afe->in_use) { - msm_adsp_disable(afe->mod); - msm_adsp_put(afe->mod); - afe->aux_conf_flag = 0; - afe->mod = NULL; - } - mutex_unlock(&afe->lock); - return rc; -} -EXPORT_SYMBOL(afe_disable); - - -#ifdef CONFIG_DEBUG_FS -static int afe_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - MM_INFO("debug intf %s\n", (char *) file->private_data); - return 0; -} - -static ssize_t afe_debug_write(struct file *filp, - const char __user *ubuf, size_t cnt, loff_t *ppos) -{ - char *lb_str = filp->private_data; - char cmd; - - if (get_user(cmd, ubuf)) - return -EFAULT; - - MM_INFO("%s %c\n", lb_str, cmd); - - if (!strcmp(lb_str, "afe_loopback")) { - switch (cmd) { - case '1': - afe_loopback(1); - break; - case '0': - afe_loopback(0); - break; - } - } - - return cnt; -} - -static const struct file_operations afe_debug_fops = { - .open = afe_debug_open, - .write = afe_debug_write -}; -#endif - -static int __init afe_init(void) -{ - struct msm_afe_state *afe = &the_afe_state; - - MM_INFO("AFE driver init\n"); - - memset(afe, 0, sizeof(struct msm_afe_state)); - afe->adsp_ops.event = afe_dsp_event; - mutex_init(&afe->lock); - init_waitqueue_head(&afe->wait); - -#ifdef CONFIG_DEBUG_FS - debugfs_afelb = debugfs_create_file("afe_loopback", - S_IFREG | S_IWUGO, NULL, (void *) "afe_loopback", - &afe_debug_fops); -#endif - - return 0; -} - -static void __exit afe_exit(void) -{ - MM_INFO("AFE driver exit\n"); -#ifdef CONFIG_DEBUG_FS - if (debugfs_afelb) - debugfs_remove(debugfs_afelb); -#endif - if (the_afe_state.mod) - msm_adsp_put(the_afe_state.mod); - return; -} - -module_init(afe_init); -module_exit(afe_exit); - -MODULE_DESCRIPTION("MSM AFE driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_a2dp_in.c b/arch/arm/mach-msm/qdsp5v2/audio_a2dp_in.c deleted file mode 100644 index 076a03ef5743bd3a64ec839d156dc4cb07b23fc6..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_a2dp_in.c +++ /dev/null @@ -1,991 +0,0 @@ -/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. - * - * sbc/pcm audio input driver - * Based on the pcm input driver in arch/arm/mach-msm/qdsp5v2/audio_pcm_in.c - * - * Copyright (C) 2008 HTC Corporation - * Copyright (C) 2008 Google, Inc. - * - * All source code in this file is licensed under the following license except - * where indicated. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* FRAME_NUM must be a power of two */ -#define FRAME_NUM (8) -#define FRAME_SIZE (2052 * 2) -#define FRAME_SIZE_SBC (768 * 2) -#define MONO_DATA_SIZE (2048) -#define STEREO_DATA_SIZE (MONO_DATA_SIZE * 2) -#define DMASZ (FRAME_SIZE * FRAME_NUM) - -struct buffer { - void *data; - uint32_t size; - uint32_t read; - uint32_t addr; - uint32_t frame_num; - uint32_t frame_len; -}; - -struct audio_a2dp_in { - struct buffer in[FRAME_NUM]; - - spinlock_t dsp_lock; - - atomic_t in_bytes; - atomic_t in_samples; - - struct mutex lock; - struct mutex read_lock; - wait_queue_head_t wait; - wait_queue_head_t wait_enable; - - struct msm_adsp_module *audrec; - - struct audrec_session_info session_info; /*audrec session info*/ - - /* configuration to use on next enable */ - uint32_t samp_rate; - uint32_t channel_mode; - uint32_t buffer_size; /* 2048 for mono, 4096 for stereo */ - uint32_t enc_type; - struct msm_audio_sbc_enc_config cfg; - - uint32_t dsp_cnt; - uint32_t in_head; /* next buffer dsp will write */ - uint32_t in_tail; /* next buffer read() will read */ - uint32_t in_count; /* number of buffers available to read() */ - uint32_t mode; - - const char *module_name; - unsigned queue_ids; - uint16_t enc_id; /* Session Id */ - - uint16_t source; /* Encoding source bit mask */ - uint32_t device_events; /* device events interested in */ - uint32_t dev_cnt; - spinlock_t dev_lock; - - /* data allocated for various buffers */ - char *data; - dma_addr_t phys; - void *msm_map; - - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - int abort; /* set when error, like sample rate mismatch */ - char *build_id; -}; - -static struct audio_a2dp_in the_audio_a2dp_in; - -struct wav_frame { - uint16_t frame_count_lsw; - uint16_t frame_count_msw; - uint16_t frame_length; - uint16_t erased_a2dp; - unsigned char raw_bitstream[]; /* samples */ -}; - -struct sbc_frame { - uint16_t bit_rate_msw; - uint16_t bit_rate_lsw; - uint16_t frame_length; - uint16_t frame_num; - unsigned char raw_bitstream[]; /* samples */ -}; - -struct audio_frame { - union { - struct wav_frame wav; - struct sbc_frame sbc; - } a2dp; -} __attribute__((packed)); - -/* Audrec Queue command sent macro's */ -#define audrec_send_bitstreamqueue(audio, cmd, len) \ - msm_adsp_write(audio->audrec, ((audio->queue_ids & 0xFFFF0000) >> 16),\ - cmd, len) - -#define audrec_send_audrecqueue(audio, cmd, len) \ - msm_adsp_write(audio->audrec, (audio->queue_ids & 0x0000FFFF),\ - cmd, len) - -/* DSP command send functions */ -static int auda2dp_in_enc_config(struct audio_a2dp_in *audio, int enable); -static int auda2dp_in_param_config(struct audio_a2dp_in *audio); -static int auda2dp_in_mem_config(struct audio_a2dp_in *audio); -static int auda2dp_in_record_config(struct audio_a2dp_in *audio, int enable); -static int auda2dp_dsp_read_buffer(struct audio_a2dp_in *audio, - uint32_t read_cnt); - -static void auda2dp_in_get_dsp_frames(struct audio_a2dp_in *audio); - -static void auda2dp_in_flush(struct audio_a2dp_in *audio); - -static void a2dp_in_listener(u32 evt_id, union auddev_evt_data *evt_payload, - void *private_data) -{ - struct audio_a2dp_in *audio = (struct audio_a2dp_in *) private_data; - unsigned long flags; - - MM_DBG("evt_id = 0x%8x\n", evt_id); - switch (evt_id) { - case AUDDEV_EVT_DEV_RDY: { - MM_DBG("AUDDEV_EVT_DEV_RDY\n"); - spin_lock_irqsave(&audio->dev_lock, flags); - audio->dev_cnt++; - audio->source |= (0x1 << evt_payload->routing_id); - spin_unlock_irqrestore(&audio->dev_lock, flags); - - if ((audio->running == 1) && (audio->enabled == 1)) - auda2dp_in_record_config(audio, 1); - - break; - } - case AUDDEV_EVT_DEV_RLS: { - MM_DBG("AUDDEV_EVT_DEV_RLS\n"); - spin_lock_irqsave(&audio->dev_lock, flags); - audio->dev_cnt--; - audio->source &= ~(0x1 << evt_payload->routing_id); - spin_unlock_irqrestore(&audio->dev_lock, flags); - - if (!audio->running || !audio->enabled) - break; - - /* Turn of as per source */ - if (audio->source) - auda2dp_in_record_config(audio, 1); - else - /* Turn off all */ - auda2dp_in_record_config(audio, 0); - - break; - } - case AUDDEV_EVT_FREQ_CHG: { - MM_DBG("Encoder Driver got sample rate change event\n"); - MM_DBG("sample rate %d\n", evt_payload->freq_info.sample_rate); - MM_DBG("dev_type %d\n", evt_payload->freq_info.dev_type); - MM_DBG("acdb_dev_id %d\n", evt_payload->freq_info.acdb_dev_id); - if (audio->running == 1) { - /* Stop Recording sample rate does not match - with device sample rate */ - if (evt_payload->freq_info.sample_rate != - audio->samp_rate) { - auda2dp_in_record_config(audio, 0); - audio->abort = 1; - wake_up(&audio->wait); - } - } - break; - } - default: - MM_ERR("wrong event %d\n", evt_id); - break; - } -} - -/* ------------------- dsp preproc event handler--------------------- */ -static void audpreproc_dsp_event(void *data, unsigned id, void *msg) -{ - struct audio_a2dp_in *audio = data; - - switch (id) { - case AUDPREPROC_ERROR_MSG: { - struct audpreproc_err_msg *err_msg = msg; - - MM_ERR("ERROR_MSG: stream id %d err idx %d\n", - err_msg->stream_id, err_msg->aud_preproc_err_idx); - /* Error case */ - wake_up(&audio->wait_enable); - break; - } - case AUDPREPROC_CMD_CFG_DONE_MSG: { - MM_DBG("CMD_CFG_DONE_MSG \n"); - break; - } - case AUDPREPROC_CMD_ENC_CFG_DONE_MSG: { - struct audpreproc_cmd_enc_cfg_done_msg *enc_cfg_msg = msg; - - MM_DBG("CMD_ENC_CFG_DONE_MSG: stream id %d enc type \ - 0x%8x\n", enc_cfg_msg->stream_id, - enc_cfg_msg->rec_enc_type); - /* Encoder enable success */ - if (enc_cfg_msg->rec_enc_type & ENCODE_ENABLE) - auda2dp_in_param_config(audio); - else { /* Encoder disable success */ - audio->running = 0; - auda2dp_in_record_config(audio, 0); - } - break; - } - case AUDPREPROC_CMD_ENC_PARAM_CFG_DONE_MSG: { - MM_DBG("CMD_ENC_PARAM_CFG_DONE_MSG \n"); - auda2dp_in_mem_config(audio); - break; - } - case AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG_DONE_MSG: { - MM_DBG("AFE_CMD_AUDIO_RECORD_CFG_DONE_MSG \n"); - wake_up(&audio->wait_enable); - break; - } - default: - MM_ERR("Unknown Event id %d\n", id); - } -} - -/* ------------------- dsp audrec event handler--------------------- */ -static void audrec_dsp_event(void *data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - struct audio_a2dp_in *audio = data; - - switch (id) { - case AUDREC_CMD_MEM_CFG_DONE_MSG: { - MM_DBG("CMD_MEM_CFG_DONE MSG DONE\n"); - audio->running = 1; - if (audio->dev_cnt > 0) - auda2dp_in_record_config(audio, 1); - break; - } - case AUDREC_FATAL_ERR_MSG: { - struct audrec_fatal_err_msg fatal_err_msg; - - getevent(&fatal_err_msg, AUDREC_FATAL_ERR_MSG_LEN); - MM_ERR("FATAL_ERR_MSG: err id %d\n", - fatal_err_msg.audrec_err_id); - /* Error stop the encoder */ - audio->stopped = 1; - wake_up(&audio->wait); - break; - } - case AUDREC_UP_PACKET_READY_MSG: { - struct audrec_up_pkt_ready_msg pkt_ready_msg; - - getevent(&pkt_ready_msg, AUDREC_UP_PACKET_READY_MSG_LEN); - MM_DBG("UP_PACKET_READY_MSG: write cnt lsw %d \ - write cnt msw %d read cnt lsw %d read cnt msw %d \n",\ - pkt_ready_msg.audrec_packet_write_cnt_lsw, \ - pkt_ready_msg.audrec_packet_write_cnt_msw, \ - pkt_ready_msg.audrec_up_prev_read_cnt_lsw, \ - pkt_ready_msg.audrec_up_prev_read_cnt_msw); - - auda2dp_in_get_dsp_frames(audio); - break; - } - case ADSP_MESSAGE_ID: { - MM_DBG("Received ADSP event: module audrectask\n"); - break; - } - default: - MM_ERR("Unknown Event id %d\n", id); - } -} - -static void auda2dp_in_get_dsp_frames(struct audio_a2dp_in *audio) -{ - struct audio_frame *frame; - uint32_t index; - unsigned long flags; - - index = audio->in_head; - - frame = (void *) (((char *)audio->in[index].data) - \ - sizeof(*frame)); - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (audio->enc_type == ENC_TYPE_WAV) - audio->in[index].size = frame->a2dp.wav.frame_length; - else if (audio->enc_type == ENC_TYPE_SBC) { - audio->in[index].size = frame->a2dp.sbc.frame_length * - frame->a2dp.sbc.frame_num; - audio->in[index].frame_num = frame->a2dp.sbc.frame_num; - audio->in[index].frame_len = frame->a2dp.sbc.frame_length; - } - - /* statistics of read */ - atomic_add(audio->in[index].size, &audio->in_bytes); - atomic_add(1, &audio->in_samples); - - audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1); - - /* If overflow, move the tail index foward. */ - if (audio->in_head == audio->in_tail) - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - else - audio->in_count++; - - auda2dp_dsp_read_buffer(audio, audio->dsp_cnt++); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - wake_up(&audio->wait); -} - -static struct msm_adsp_ops audrec_adsp_ops = { - .event = audrec_dsp_event, -}; - -static int auda2dp_in_enc_config(struct audio_a2dp_in *audio, int enable) -{ - struct audpreproc_audrec_cmd_enc_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - if (audio->build_id[17] == '1') { - cmd.cmd_id = AUDPREPROC_AUDREC_CMD_ENC_CFG_2; - } else { - cmd.cmd_id = AUDPREPROC_AUDREC_CMD_ENC_CFG; - } - cmd.stream_id = audio->enc_id; - - if (enable) - cmd.audrec_enc_type = audio->enc_type | ENCODE_ENABLE; - else - cmd.audrec_enc_type &= ~(ENCODE_ENABLE); - - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); -} - -static int auda2dp_in_param_config(struct audio_a2dp_in *audio) -{ - if (audio->enc_type == ENC_TYPE_WAV) { - struct audpreproc_audrec_cmd_parm_cfg_wav cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPREPROC_AUDREC_CMD_PARAM_CFG; - cmd.common.stream_id = audio->enc_id; - - cmd.aud_rec_samplerate_idx = audio->samp_rate; - cmd.aud_rec_stereo_mode = audio->channel_mode; - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); - } else if (audio->enc_type == ENC_TYPE_SBC) { - struct audpreproc_audrec_cmd_parm_cfg_sbc cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPREPROC_AUDREC_CMD_PARAM_CFG; - cmd.common.stream_id = audio->enc_id; - cmd.aud_rec_sbc_enc_param = - (audio->cfg.number_of_blocks << - AUDREC_SBC_ENC_PARAM_NUM_SUB_BLOCKS_MASK) | - (audio->cfg.number_of_subbands << - AUDREC_SBC_ENC_PARAM_NUM_SUB_BANDS_MASK) | - (audio->cfg.mode << - AUDREC_SBC_ENC_PARAM_MODE_MASK) | - (audio->cfg.bit_allocation << - AUDREC_SBC_ENC_PARAM_BIT_ALLOC_MASK); - cmd.aud_rec_sbc_bit_rate_msw = - (audio->cfg.bit_rate & 0xFFFF0000) >> 16; - cmd.aud_rec_sbc_bit_rate_lsw = - (audio->cfg.bit_rate & 0xFFFF); - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); - } - return 0; -} - -/* To Do: msm_snddev_route_enc(audio->enc_id); */ -static int auda2dp_in_record_config(struct audio_a2dp_in *audio, int enable) -{ - struct audpreproc_afe_cmd_audio_record_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG; - cmd.stream_id = audio->enc_id; - if (enable) - cmd.destination_activity = AUDIO_RECORDING_TURN_ON; - else - cmd.destination_activity = AUDIO_RECORDING_TURN_OFF; - - cmd.source_mix_mask = audio->source; - if (audio->enc_id == 2) { - if ((cmd.source_mix_mask & - INTERNAL_CODEC_TX_SOURCE_MIX_MASK) || - (cmd.source_mix_mask & AUX_CODEC_TX_SOURCE_MIX_MASK) || - (cmd.source_mix_mask & VOICE_UL_SOURCE_MIX_MASK) || - (cmd.source_mix_mask & VOICE_DL_SOURCE_MIX_MASK)) { - cmd.pipe_id = SOURCE_PIPE_1; - } - if (cmd.source_mix_mask & - AUDPP_A2DP_PIPE_SOURCE_MIX_MASK) - cmd.pipe_id |= SOURCE_PIPE_0; - } - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); -} - -static int auda2dp_in_mem_config(struct audio_a2dp_in *audio) -{ - struct audrec_cmd_arecmem_cfg cmd; - uint16_t *data = (void *) audio->data; - int n; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_MEM_CFG_CMD; - cmd.audrec_up_pkt_intm_count = 1; - cmd.audrec_ext_pkt_start_addr_msw = audio->phys >> 16; - cmd.audrec_ext_pkt_start_addr_lsw = audio->phys; - cmd.audrec_ext_pkt_buf_number = FRAME_NUM; - - /* prepare buffer pointers: - * Wav: - * Mono: 1024 samples + 4 halfword header - * Stereo: 2048 samples + 4 halfword header - * SBC: - * 768 + 4 halfword header - */ - if (audio->enc_type == ENC_TYPE_SBC) { - for (n = 0; n < FRAME_NUM; n++) { - audio->in[n].data = data + 4; - data += (4 + (FRAME_SIZE_SBC/2)); - MM_DBG("0x%8x\n", (int)(audio->in[n].data - 8)); - } - } else if (audio->enc_type == ENC_TYPE_WAV) { - for (n = 0; n < FRAME_NUM; n++) { - audio->in[n].data = data + 4; - data += (4 + (audio->channel_mode ? 2048 : 1024)); - MM_DBG("0x%8x\n", (int)(audio->in[n].data - 8)); - } - } - - return audrec_send_audrecqueue(audio, &cmd, sizeof(cmd)); -} - -static int auda2dp_dsp_read_buffer(struct audio_a2dp_in *audio, - uint32_t read_cnt) -{ - struct up_audrec_packet_ext_ptr cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = UP_AUDREC_PACKET_EXT_PTR; - cmd.audrec_up_curr_read_count_msw = read_cnt >> 16; - cmd.audrec_up_curr_read_count_lsw = read_cnt; - - return audrec_send_bitstreamqueue(audio, &cmd, sizeof(cmd)); -} - -/* must be called with audio->lock held */ -static int auda2dp_in_enable(struct audio_a2dp_in *audio) -{ - if (audio->enabled) - return 0; - - if (audpreproc_enable(audio->enc_id, &audpreproc_dsp_event, audio)) { - MM_ERR("msm_adsp_enable(audpreproc) failed\n"); - return -ENODEV; - } - - if (msm_adsp_enable(audio->audrec)) { - MM_ERR("msm_adsp_enable(audrec) failed\n"); - audpreproc_disable(audio->enc_id, audio); - return -ENODEV; - } - audio->enabled = 1; - auda2dp_in_enc_config(audio, 1); - - return 0; -} - -/* must be called with audio->lock held */ -static int auda2dp_in_disable(struct audio_a2dp_in *audio) -{ - if (audio->enabled) { - audio->enabled = 0; - auda2dp_in_enc_config(audio, 0); - wake_up(&audio->wait); - wait_event_interruptible_timeout(audio->wait_enable, - audio->running == 0, 1*HZ); - msm_adsp_disable(audio->audrec); - audpreproc_disable(audio->enc_id, audio); - } - return 0; -} - -static void auda2dp_in_flush(struct audio_a2dp_in *audio) -{ - int i; - - audio->dsp_cnt = 0; - audio->in_head = 0; - audio->in_tail = 0; - audio->in_count = 0; - for (i = 0; i < FRAME_NUM; i++) { - audio->in[i].size = 0; - audio->in[i].read = 0; - } - MM_DBG("in_bytes %d\n", atomic_read(&audio->in_bytes)); - MM_DBG("in_samples %d\n", atomic_read(&audio->in_samples)); - atomic_set(&audio->in_bytes, 0); - atomic_set(&audio->in_samples, 0); -} - -/* ------------------- device --------------------- */ -static long auda2dp_in_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct audio_a2dp_in *audio = file->private_data; - int rc = 0; - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = atomic_read(&audio->in_bytes); - stats.sample_count = atomic_read(&audio->in_samples); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return rc; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: { - uint32_t freq; - /* Poll at 48KHz always */ - freq = 48000; - MM_DBG("AUDIO_START\n"); - rc = msm_snddev_request_freq(&freq, audio->enc_id, - SNDDEV_CAP_TX, AUDDEV_CLNT_ENC); - MM_DBG("sample rate configured %d sample rate requested %d\n", - freq, audio->samp_rate); - if (rc < 0) { - MM_DBG("sample rate can not be set, return code %d\n",\ - rc); - msm_snddev_withdraw_freq(audio->enc_id, - SNDDEV_CAP_TX, AUDDEV_CLNT_ENC); - MM_DBG("msm_snddev_withdraw_freq\n"); - break; - } - /*update aurec session info in audpreproc layer*/ - audio->session_info.session_id = audio->enc_id; - audio->session_info.sampling_freq = audio->samp_rate; - audpreproc_update_audrec_info(&audio->session_info); - rc = auda2dp_in_enable(audio); - if (!rc) { - rc = - wait_event_interruptible_timeout(audio->wait_enable, - audio->running != 0, 1*HZ); - MM_DBG("state %d rc = %d\n", audio->running, rc); - - if (audio->running == 0) { - rc = -ENODEV; - msm_snddev_withdraw_freq(audio->enc_id, - SNDDEV_CAP_TX, AUDDEV_CLNT_ENC); - MM_DBG("msm_snddev_withdraw_freq\n"); - } else - rc = 0; - } - audio->stopped = 0; - break; - } - case AUDIO_STOP: { - /*reset the sampling frequency information at audpreproc layer*/ - audio->session_info.sampling_freq = 0; - audpreproc_update_audrec_info(&audio->session_info); - rc = auda2dp_in_disable(audio); - rc = msm_snddev_withdraw_freq(audio->enc_id, - SNDDEV_CAP_TX, AUDDEV_CLNT_ENC); - MM_DBG("msm_snddev_withdraw_freq\n"); - audio->stopped = 1; - audio->abort = 0; - break; - } - case AUDIO_FLUSH: { - if (audio->stopped) { - /* Make sure we're stopped and we wake any threads - * that might be blocked holding the read_lock. - * While audio->stopped read threads will always - * exit immediately. - */ - wake_up(&audio->wait); - mutex_lock(&audio->read_lock); - auda2dp_in_flush(audio); - mutex_unlock(&audio->read_lock); - } - break; - } - case AUDIO_SET_STREAM_CONFIG: { - struct msm_audio_stream_config cfg; - if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - /* Allow only single frame */ - if ((audio->enc_type == ENC_TYPE_SBC) && - (cfg.buffer_size != FRAME_SIZE_SBC)) - rc = -EINVAL; - else - audio->buffer_size = cfg.buffer_size; - break; - } - case AUDIO_GET_STREAM_CONFIG: { - struct msm_audio_stream_config cfg; - memset(&cfg, 0, sizeof(cfg)); - if (audio->enc_type == ENC_TYPE_SBC) - cfg.buffer_size = FRAME_SIZE_SBC; - else - cfg.buffer_size = MONO_DATA_SIZE; - cfg.buffer_count = FRAME_NUM; - if (copy_to_user((void *) arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - break; - } - case AUDIO_SET_SBC_ENC_CONFIG: { - if (copy_from_user(&audio->cfg, (void *) arg, - sizeof(audio->cfg))) { - rc = -EFAULT; - break; - } - audio->samp_rate = audio->cfg.sample_rate; - audio->channel_mode = audio->cfg.channels; - audio->enc_type = ENC_TYPE_SBC; - break; - } - case AUDIO_SET_CONFIG: { - struct msm_audio_config cfg; - if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - if (cfg.channel_count == 1) { - cfg.channel_count = AUDREC_CMD_MODE_MONO; - audio->buffer_size = MONO_DATA_SIZE; - } else if (cfg.channel_count == 2) { - cfg.channel_count = AUDREC_CMD_MODE_STEREO; - audio->buffer_size = STEREO_DATA_SIZE; - } else { - rc = -EINVAL; - break; - } - audio->samp_rate = cfg.sample_rate; - audio->channel_mode = cfg.channel_count; - audio->enc_type = ENC_TYPE_WAV; - break; - } - case AUDIO_GET_SBC_ENC_CONFIG: { - struct msm_audio_sbc_enc_config cfg; - memset(&cfg, 0, sizeof(cfg)); - cfg.bit_allocation = audio->cfg.bit_allocation; - cfg.mode = audio->cfg.mode; - cfg.number_of_subbands = audio->cfg.number_of_subbands; - cfg.number_of_blocks = audio->cfg.number_of_blocks; - cfg.sample_rate = audio->samp_rate; - cfg.channels = audio->channel_mode; - cfg.bit_rate = audio->cfg.bit_rate; - if (copy_to_user((void *) arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config cfg; - memset(&cfg, 0, sizeof(cfg)); - cfg.buffer_count = FRAME_NUM; - cfg.sample_rate = audio->samp_rate; - if (audio->channel_mode == AUDREC_CMD_MODE_MONO) { - cfg.channel_count = 1; - cfg.buffer_size = MONO_DATA_SIZE; - } else { - cfg.channel_count = 2; - cfg.buffer_size = STEREO_DATA_SIZE; - } - cfg.type = ENC_TYPE_WAV; - if (copy_to_user((void *) arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - break; - } - case AUDIO_GET_SESSION_ID: { - if (copy_to_user((void *) arg, &audio->enc_id, - sizeof(unsigned short))) { - rc = -EFAULT; - } - break; - } - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -static ssize_t auda2dp_in_read(struct file *file, - char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_a2dp_in *audio = file->private_data; - unsigned long flags; - const char __user *start = buf; - void *data; - uint32_t index; - uint32_t size; - int rc = 0; - uint32_t f_len = 0, f_num = 0; - int i = 0; - - mutex_lock(&audio->read_lock); - while (count > 0) { - rc = wait_event_interruptible( - audio->wait, (audio->in_count > 0) || audio->stopped || - audio->abort); - - if (rc < 0) - break; - - if (audio->stopped && !audio->in_count) { - MM_DBG("Driver in stop state, No more buffer to read"); - rc = 0;/* End of File */ - break; - } - - if (audio->abort) { - rc = -EPERM; /* Not permitted due to abort */ - break; - } - - index = audio->in_tail; - data = (uint8_t *) audio->in[index].data; - size = audio->in[index].size; - if (count >= size) { - if (audio->enc_type == ENC_TYPE_SBC && - (audio->in[index].frame_len % 2)) { - f_len = audio->in[index].frame_len; - f_num = audio->in[index].frame_num; - for (i = 0; i < f_num; i++) { - if (copy_to_user(&buf[i * f_len], - (uint8_t *) (data + (i * (f_len + 1))), - f_len)) { - rc = -EFAULT; - break; - } - } - } else { - if (copy_to_user(buf, data, size)) { - rc = -EFAULT; - break; - } - } - spin_lock_irqsave(&audio->dsp_lock, flags); - if (index != audio->in_tail) { - /* overrun -- data is - * invalid and we need to retry */ - spin_unlock_irqrestore(&audio->dsp_lock, flags); - continue; - } - audio->in[index].size = 0; - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - audio->in_count--; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - count -= size; - buf += size; - } else { - MM_ERR("short read\n"); - break; - } - } - mutex_unlock(&audio->read_lock); - if (buf > start) - return buf - start; - - return rc; -} - -static ssize_t auda2dp_in_write(struct file *file, - const char __user *buf, - size_t count, loff_t *pos) -{ - return -EINVAL; -} - -static int auda2dp_in_release(struct inode *inode, struct file *file) -{ - struct audio_a2dp_in *audio = file->private_data; - - mutex_lock(&audio->lock); - /* with draw frequency for session - incase not stopped the driver */ - msm_snddev_withdraw_freq(audio->enc_id, SNDDEV_CAP_TX, - AUDDEV_CLNT_ENC); - auddev_unregister_evt_listner(AUDDEV_CLNT_ENC, audio->enc_id); - /*reset the sampling frequency information at audpreproc layer*/ - audio->session_info.sampling_freq = 0; - audpreproc_update_audrec_info(&audio->session_info); - auda2dp_in_disable(audio); - auda2dp_in_flush(audio); - msm_adsp_put(audio->audrec); - audpreproc_aenc_free(audio->enc_id); - audio->audrec = NULL; - audio->opened = 0; - if (audio->data) { - iounmap(audio->msm_map); - free_contiguous_memory_by_paddr(audio->phys); - audio->data = NULL; - } - mutex_unlock(&audio->lock); - return 0; -} - -static int auda2dp_in_open(struct inode *inode, struct file *file) -{ - struct audio_a2dp_in *audio = &the_audio_a2dp_in; - int rc; - int encid; - - mutex_lock(&audio->lock); - if (audio->opened) { - rc = -EBUSY; - goto done; - } - - audio->phys = allocate_contiguous_ebi_nomap(DMASZ, SZ_4K); - if (audio->phys) { - audio->msm_map = ioremap(audio->phys, DMASZ); - if (IS_ERR(audio->msm_map)) { - MM_ERR("could not map the phys address to kernel" - "space\n"); - rc = -ENOMEM; - free_contiguous_memory_by_paddr(audio->phys); - goto done; - } - audio->data = (u8 *)audio->msm_map; - } else { - MM_ERR("could not allocate DMA buffers\n"); - rc = -ENOMEM; - goto done; - } - MM_DBG("Memory addr = 0x%8x phy addr = 0x%8x\n",\ - (int) audio->data, (int) audio->phys); - - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - rc = -EACCES; - MM_ERR("Non tunnel encoding is not supported\n"); - goto done; - } else if (!(file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - audio->mode = MSM_AUD_ENC_MODE_TUNNEL; - MM_DBG("Opened for Tunnel mode encoding\n"); - } else { - rc = -EACCES; - goto done; - } - /* Settings will be re-config at AUDIO_SET_CONFIG/SBC_ENC_CONFIG, - * but at least we need to have initial config - */ - audio->channel_mode = AUDREC_CMD_MODE_MONO; - audio->buffer_size = FRAME_SIZE_SBC; - audio->samp_rate = 48000; - audio->enc_type = ENC_TYPE_SBC | audio->mode; - audio->cfg.bit_allocation = AUDIO_SBC_BA_SNR; - audio->cfg.mode = AUDIO_SBC_MODE_JSTEREO; - audio->cfg.number_of_subbands = AUDIO_SBC_BANDS_8; - audio->cfg.number_of_blocks = AUDIO_SBC_BLOCKS_16; - audio->cfg.bit_rate = 320000; /* max 512kbps(mono), 320kbs(others) */ - - encid = audpreproc_aenc_alloc(audio->enc_type, &audio->module_name, - &audio->queue_ids); - if (encid < 0) { - MM_ERR("No free encoder available\n"); - rc = -ENODEV; - goto done; - } - audio->enc_id = encid; - - rc = msm_adsp_get(audio->module_name, &audio->audrec, - &audrec_adsp_ops, audio); - - if (rc) { - audpreproc_aenc_free(audio->enc_id); - goto done; - } - - audio->stopped = 0; - audio->source = 0; - audio->abort = 0; - auda2dp_in_flush(audio); - audio->device_events = AUDDEV_EVT_DEV_RDY | AUDDEV_EVT_DEV_RLS | - AUDDEV_EVT_FREQ_CHG; - - rc = auddev_register_evt_listner(audio->device_events, - AUDDEV_CLNT_ENC, audio->enc_id, - a2dp_in_listener, (void *) audio); - if (rc) { - MM_ERR("failed to register device event listener\n"); - goto evt_error; - } - audio->build_id = socinfo_get_build_id(); - MM_DBG("Modem build id = %s\n", audio->build_id); - file->private_data = audio; - audio->opened = 1; - rc = 0; -done: - mutex_unlock(&audio->lock); - return rc; -evt_error: - msm_adsp_put(audio->audrec); - audpreproc_aenc_free(audio->enc_id); - mutex_unlock(&audio->lock); - return rc; -} - -static const struct file_operations audio_a2dp_in_fops = { - .owner = THIS_MODULE, - .open = auda2dp_in_open, - .release = auda2dp_in_release, - .read = auda2dp_in_read, - .write = auda2dp_in_write, - .unlocked_ioctl = auda2dp_in_ioctl, -}; - -struct miscdevice audio_a2dp_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_a2dp_in", - .fops = &audio_a2dp_in_fops, -}; - -static int __init auda2dp_in_init(void) -{ - mutex_init(&the_audio_a2dp_in.lock); - mutex_init(&the_audio_a2dp_in.read_lock); - spin_lock_init(&the_audio_a2dp_in.dsp_lock); - spin_lock_init(&the_audio_a2dp_in.dev_lock); - init_waitqueue_head(&the_audio_a2dp_in.wait); - init_waitqueue_head(&the_audio_a2dp_in.wait_enable); - return misc_register(&audio_a2dp_in_misc); -} - -device_initcall(auda2dp_in_init); - -MODULE_DESCRIPTION("MSM SBC encode driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_aac.c b/arch/arm/mach-msm/qdsp5v2/audio_aac.c deleted file mode 100644 index 883da2b6db9d9529f2e5574ebb1b4ca29cdeaf53..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_aac.c +++ /dev/null @@ -1,2037 +0,0 @@ -/* - * aac audio decoder device - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define BUFSZ 32768 -#define DMASZ (BUFSZ * 2) -#define BUFSZ_MIN 4096 -#define DMASZ_MIN (BUFSZ_MIN * 2) - -#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF -#define AUDDEC_DEC_AAC 5 - -#define PCM_BUFSZ_MIN 9600 /* Hold one stereo AAC frame */ -#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most - but support 2 buffers currently */ -#define ROUTING_MODE_FTRT 1 -#define ROUTING_MODE_RT 2 -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDAAC_METAFIELD_MASK 0xFFFF0000 -#define AUDAAC_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */ -#define AUDAAC_EOS_FLG_MASK 0x01 -#define AUDAAC_EOS_NONE 0x0 /* No EOS detected */ -#define AUDAAC_EOS_SET 0x1 /* EOS set in meta field */ - -#define AUDAAC_EVENT_NUM 10 /* Default number of pre-allocated event packets */ - -#define BITSTREAM_ERROR_THRESHOLD_VALUE 0x1 /* DEFAULT THRESHOLD VALUE */ - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; - unsigned short mfield_sz; /*only useful for data has meta field */ -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audaac_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct audaac_event{ - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audio { - struct buffer out[2]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - unsigned out_dma_sz; - - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - /* Host PCM section */ - struct buffer in[PCM_BUF_MAX_COUNT]; - struct mutex read_lock; - wait_queue_head_t read_wait; /* Wait queue for read */ - char *read_data; /* pointer to reader buffer */ - int32_t read_phys; /* physical address of reader buffer */ - uint8_t read_next; /* index to input buffers to be read next */ - uint8_t fill_next; /* index to buffer that DSP should be filling */ - uint8_t pcm_buf_count; /* number of pcm buffer allocated */ - /* ---- End of Host PCM section */ - - struct msm_adsp_module *audplay; - - /* configuration to use on next enable */ - uint32_t out_sample_rate; - uint32_t out_channel_mode; - struct msm_audio_aac_config aac_config; - - /* AV sync Info */ - int avsync_flag; /* Flag to indicate feedback from DSP */ - wait_queue_head_t avsync_wait;/* Wait queue for AV Sync Message */ - /* 48 bits sample/bytes counter per channel */ - uint16_t avsync[AUDPP_AVSYNC_CH_COUNT * AUDPP_AVSYNC_NUM_WORDS + 1]; - - /* data allocated for various buffers */ - char *data; - int32_t phys; /* physical address of write buffer */ - void *map_v_read; - void *map_v_write; - - int mfield; /* meta field embedded in data */ - int rflush; /* Read flush */ - int wflush; /* Write flush */ - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - int pcm_feedback; - int buf_refresh; - int teos; /* valid only if tunnel mode & no data left for decoder */ - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - int reserved; /* A byte is being reserved */ - char rsv_byte; /* Handle odd length user data */ - - const char *module_name; - unsigned queue_id; - uint16_t dec_id; - uint32_t read_ptr_offset; - int16_t source; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audaac_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - uint32_t device_events; - - struct msm_audio_bitstream_info stream_info; - struct msm_audio_bitstream_error_info bitstream_error_info; - uint32_t bitstream_error_threshold_value; - - int eq_enable; - int eq_needs_commit; - struct audpp_cmd_cfg_object_params_eqalizer eq; - struct audpp_cmd_cfg_object_params_volume vol_pan; -}; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audpp_cmd_cfg_adec_params(struct audio *audio); -static void audpp_cmd_cfg_routing_mode(struct audio *audio); -static void audplay_send_data(struct audio *audio, unsigned needed); -static void audplay_error_threshold_config(struct audio *audio); -static void audplay_config_hostpcm(struct audio *audio); -static void audplay_buffer_refresh(struct audio *audio); -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg); -static void audaac_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); - -/* must be called with audio->lock held */ -static int audio_enable(struct audio *audio) -{ - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (audio->enabled) - return 0; - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_tail = 0; - audio->out_needed = 0; - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - return -ENODEV; - } - audio->enabled = 1; - return 0; -} - -static void aac_listner(u32 evt_id, union auddev_evt_data *evt_payload, - void *private_data) -{ - struct audio *audio = (struct audio *) private_data; - switch (evt_id) { - case AUDDEV_EVT_DEV_RDY: - MM_DBG(":AUDDEV_EVT_DEV_RDY\n"); - audio->source |= (0x1 << evt_payload->routing_id); - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - break; - case AUDDEV_EVT_DEV_RLS: - MM_DBG(":AUDDEV_EVT_DEV_RLS\n"); - audio->source &= ~(0x1 << evt_payload->routing_id); - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - break; - case AUDDEV_EVT_STREAM_VOL_CHG: - audio->vol_pan.volume = evt_payload->session_vol; - MM_DBG(":AUDDEV_EVT_STREAM_VOL_CHG, stream vol %d\n", - audio->vol_pan.volume); - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - break; - default: - MM_ERR(":ERROR:wrong event\n"); - break; - } -} -/* must be called with audio->lock held */ -static int audio_disable(struct audio *audio) -{ - int rc = 0; - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - wake_up(&audio->write_wait); - wake_up(&audio->read_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - audio->out_needed = 0; - } - return rc; -} - -/* ------------------- dsp --------------------- */ -static void audio_update_pcm_buf_entry(struct audio *audio, uint32_t *payload) -{ - uint8_t index; - unsigned long flags; - - if (audio->rflush) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < payload[1]; index++) { - if (audio->in[audio->fill_next].addr == - payload[2 + index * 2]) { - MM_DBG("in[%d] ready\n", audio->fill_next); - audio->in[audio->fill_next].used = - payload[3 + index * 2]; - if ((++audio->fill_next) == audio->pcm_buf_count) - audio->fill_next = 0; - - } else { - MM_ERR("expected=%x ret=%x\n", - audio->in[audio->fill_next].addr, - payload[1 + index * 2]); - break; - } - } - if (audio->in[audio->fill_next].used == 0) { - audplay_buffer_refresh(audio); - } else { - MM_DBG("read cannot keep up\n"); - audio->buf_refresh = 1; - } - wake_up(&audio->read_wait); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - -} - -static void audaac_bitstream_error_info(struct audio *audio, uint32_t *payload) -{ - unsigned long flags; - union msm_audio_event_payload e_payload; - - if (payload[0] != AUDDEC_DEC_AAC) { - MM_ERR("Unexpected bitstream error info from DSP:\ - Invalid decoder\n"); - return; - } - - /* get stream info from DSP msg */ - spin_lock_irqsave(&audio->dsp_lock, flags); - - audio->bitstream_error_info.dec_id = payload[0]; - audio->bitstream_error_info.err_msg_indicator = payload[1]; - audio->bitstream_error_info.err_type = payload[2]; - - spin_unlock_irqrestore(&audio->dsp_lock, flags); - MM_ERR("bit_stream_error_type=%d error_count=%d\n", - audio->bitstream_error_info.err_type, (0x0000FFFF & - audio->bitstream_error_info.err_msg_indicator)); - - /* send event to ARM to notify error info coming */ - e_payload.error_info = audio->bitstream_error_info; - audaac_post_event(audio, AUDIO_EVENT_BITSTREAM_ERROR_INFO, e_payload); -} - -static void audaac_update_stream_info(struct audio *audio, uint32_t *payload) -{ - unsigned long flags; - union msm_audio_event_payload e_payload; - - /* get stream info from DSP msg */ - spin_lock_irqsave(&audio->dsp_lock, flags); - - audio->stream_info.codec_type = AUDIO_CODEC_TYPE_AAC; - audio->stream_info.chan_info = (0x0000FFFF & payload[1]); - audio->stream_info.sample_rate = (0x0000FFFF & payload[2]); - audio->stream_info.bit_stream_info = (0x0000FFFF & payload[3]); - audio->stream_info.bit_rate = payload[4]; - - spin_unlock_irqrestore(&audio->dsp_lock, flags); - MM_DBG("chan_info=%d, sample_rate=%d, bit_stream_info=%d\n", - audio->stream_info.chan_info, - audio->stream_info.sample_rate, - audio->stream_info.bit_stream_info); - - /* send event to ARM to notify steam info coming */ - e_payload.stream_info = audio->stream_info; - audaac_post_event(audio, AUDIO_EVENT_STREAM_INFO, e_payload); -} -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - getevent(msg, sizeof(msg)); - - MM_DBG("msg_id=%x\n", id); - - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audplay_send_data(audio, 1); - break; - - case AUDPLAY_MSG_BUFFER_UPDATE: - audio_update_pcm_buf_entry(audio, msg); - break; - - case AUDPLAY_UP_STREAM_INFO: - if ((msg[1] & AUDPLAY_STREAM_INFO_MSG_MASK) == - AUDPLAY_STREAM_INFO_MSG_MASK) { - audaac_bitstream_error_info(audio, msg); - } else { - audaac_update_stream_info(audio, msg); - } - break; - - case AUDPLAY_UP_OUTPORT_FLUSH_ACK: - MM_DBG("OUTPORT_FLUSH_ACK\n"); - audio->rflush = 0; - wake_up(&audio->read_wait); - if (audio->pcm_feedback) - audplay_buffer_refresh(audio); - break; - - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audplaytask)\n"); - break; - - default: - MM_ERR("unexpected message from decoder \n"); - } -} - -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status: sleep reason = \ - 0x%04x\n", reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init \n"); - if (audio->pcm_feedback) - audpp_cmd_cfg_routing_mode(audio); - else - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg \n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play \n"); - /* send mixer command */ - audpp_route_stream(audio->dec_id, - audio->source); - if (audio->pcm_feedback) { - audplay_error_threshold_config(audio); - audplay_config_hostpcm(audio); - audplay_buffer_refresh(audio); - } - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - default: - MM_ERR("unknown decoder status \n"); - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - audpp_dsp_set_eq(audio->dec_id, audio->eq_enable, - &audio->eq, POPP); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audio->running = 0; - } else { - MM_DBG("CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_ROUTING_ACK: - MM_DBG("ROUTING_ACK mode=%d\n", msg[1]); - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - audio->rflush = 0; - wake_up(&audio->write_wait); - if (audio->pcm_feedback) - audplay_buffer_refresh(audio); - break; - - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - - case AUDPP_MSG_AVSYNC_MSG: - MM_DBG("AUDPP_MSG_AVSYNC_MSG\n"); - memcpy(&audio->avsync[0], msg, sizeof(audio->avsync)); - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); - break; - - default: - MM_ERR("UNKNOWN (%d)\n", id); - } - -} - -struct msm_adsp_ops audplay_adsp_ops_aac = { - .event = audplay_dsp_event, -}; - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id,\ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - struct audpp_cmd_cfg_dec_type cfg_dec_cmd; - - memset(&cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - - cfg_dec_cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE; - if (enable) - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_AAC; - else - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - cfg_dec_cmd.dm_mode = 0x0; - cfg_dec_cmd.stream_id = audio->dec_id; - - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} - -static void audpp_cmd_cfg_adec_params(struct audio *audio) -{ - struct audpp_cmd_cfg_adec_params_aac cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_AAC_LEN; - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = audio->out_sample_rate; - cmd.format = audio->aac_config.format; - cmd.audio_object = audio->aac_config.audio_object; - cmd.ep_config = audio->aac_config.ep_config; - cmd.aac_section_data_resilience_flag = - audio->aac_config.aac_section_data_resilience_flag; - cmd.aac_scalefactor_data_resilience_flag = - audio->aac_config.aac_scalefactor_data_resilience_flag; - cmd.aac_spectral_data_resilience_flag = - audio->aac_config.aac_spectral_data_resilience_flag; - cmd.sbr_on_flag = audio->aac_config.sbr_on_flag; - cmd.sbr_ps_on_flag = audio->aac_config.sbr_ps_on_flag; - cmd.channel_configuration = audio->aac_config.channel_configuration; - - audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static void audpp_cmd_cfg_routing_mode(struct audio *audio) -{ - struct audpp_cmd_routing_mode cmd; - MM_DBG("\n"); /* Macro prints the file name and function */ - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; - cmd.object_number = audio->dec_id; - if (audio->pcm_feedback) - cmd.routing_mode = ROUTING_MODE_FTRT; - else - cmd.routing_mode = ROUTING_MODE_RT; - - audpp_send_queue1(&cmd, sizeof(cmd)); -} - -static int audplay_dsp_send_data_avail(struct audio *audio, - unsigned idx, unsigned len) -{ - struct audplay_cmd_bitstream_data_avail_nt2 cmd; - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2; - if (audio->mfield) - cmd.decoder_id = AUDAAC_METAFIELD_MASK | - (audio->out[idx].mfield_sz >> 1); - else - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = audio->out[idx].addr; - cmd.buf_size = len / 2; - cmd.partition_number = 0; - return audplay_send_queue0(audio, &cmd, sizeof(cmd)); -} - -static void audplay_buffer_refresh(struct audio *audio) -{ - struct audplay_cmd_buffer_refresh refresh_cmd; - - refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; - refresh_cmd.num_buffers = 1; - refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; - /* AAC frame size */ - refresh_cmd.buf0_length = audio->in[audio->fill_next].size - - (audio->in[audio->fill_next].size % 1024) - + (audio->mfield ? 24 : 0); - refresh_cmd.buf_read_count = 0; - MM_DBG("buf0_addr=%x buf0_len=%d\n", refresh_cmd.buf0_address, - refresh_cmd.buf0_length); - (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); -} - -static void audplay_outport_flush(struct audio *audio) -{ - struct audplay_cmd_outport_flush op_flush_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - op_flush_cmd.cmd_id = AUDPLAY_CMD_OUTPORT_FLUSH; - (void)audplay_send_queue0(audio, &op_flush_cmd, sizeof(op_flush_cmd)); -} - -static void audplay_error_threshold_config(struct audio *audio) -{ - union audplay_cmd_channel_info ch_cfg_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - ch_cfg_cmd.thr_update.cmd_id = AUDPLAY_CMD_CHANNEL_INFO; - ch_cfg_cmd.thr_update.threshold_update = AUDPLAY_ERROR_THRESHOLD_ENABLE; - ch_cfg_cmd.thr_update.threshold_value = - audio->bitstream_error_threshold_value; - (void)audplay_send_queue0(audio, &ch_cfg_cmd, sizeof(ch_cfg_cmd)); -} - -static void audplay_config_hostpcm(struct audio *audio) -{ - struct audplay_cmd_hpcm_buf_cfg cfg_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; - cfg_cmd.max_buffers = audio->pcm_buf_count; - cfg_cmd.byte_swap = 0; - cfg_cmd.hostpcm_config = (0x8000) | (0x4000); - cfg_cmd.feedback_frequency = 1; - cfg_cmd.partition_number = 0; - (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); - -} - -static void audplay_send_data(struct audio *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - MM_DBG("frame %d busy\n", audio->out_tail); - audplay_dsp_send_data_avail(audio, audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } - done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ - -static void audio_flush(struct audio *audio) -{ - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->reserved = 0; - audio->out_needed = 0; - atomic_set(&audio->out_bytes, 0); -} - -static void audio_flush_pcm_buf(struct audio *audio) -{ - uint8_t index; - - for (index = 0; index < PCM_BUF_MAX_COUNT; index++) - audio->in[index].used = 0; - audio->buf_refresh = 0; - audio->read_next = 0; - audio->fill_next = 0; -} - -static int audaac_validate_usr_config(struct msm_audio_aac_config *config) -{ - int ret_val = -1; - - if (config->format != AUDIO_AAC_FORMAT_ADTS && - config->format != AUDIO_AAC_FORMAT_RAW && - config->format != AUDIO_AAC_FORMAT_PSUEDO_RAW && - config->format != AUDIO_AAC_FORMAT_LOAS) - goto done; - - if (config->audio_object != AUDIO_AAC_OBJECT_LC && - config->audio_object != AUDIO_AAC_OBJECT_LTP && - config->audio_object != AUDIO_AAC_OBJECT_BSAC && - config->audio_object != AUDIO_AAC_OBJECT_ERLC) - goto done; - - if (config->audio_object == AUDIO_AAC_OBJECT_ERLC) { - if (config->ep_config > 3) - goto done; - if (config->aac_scalefactor_data_resilience_flag != - AUDIO_AAC_SCA_DATA_RES_OFF && - config->aac_scalefactor_data_resilience_flag != - AUDIO_AAC_SCA_DATA_RES_ON) - goto done; - if (config->aac_section_data_resilience_flag != - AUDIO_AAC_SEC_DATA_RES_OFF && - config->aac_section_data_resilience_flag != - AUDIO_AAC_SEC_DATA_RES_ON) - goto done; - if (config->aac_spectral_data_resilience_flag != - AUDIO_AAC_SPEC_DATA_RES_OFF && - config->aac_spectral_data_resilience_flag != - AUDIO_AAC_SPEC_DATA_RES_ON) - goto done; - } else { - config->aac_section_data_resilience_flag = - AUDIO_AAC_SEC_DATA_RES_OFF; - config->aac_scalefactor_data_resilience_flag = - AUDIO_AAC_SCA_DATA_RES_OFF; - config->aac_spectral_data_resilience_flag = - AUDIO_AAC_SPEC_DATA_RES_OFF; - } - -#ifndef CONFIG_AUDIO_AAC_PLUS - if (AUDIO_AAC_SBR_ON_FLAG_OFF != config->sbr_on_flag) - goto done; -#else - if (config->sbr_on_flag != AUDIO_AAC_SBR_ON_FLAG_OFF && - config->sbr_on_flag != AUDIO_AAC_SBR_ON_FLAG_ON) - goto done; -#endif - -#ifndef CONFIG_AUDIO_ENHANCED_AAC_PLUS - if (AUDIO_AAC_SBR_PS_ON_FLAG_OFF != config->sbr_ps_on_flag) - goto done; -#else - if (config->sbr_ps_on_flag != AUDIO_AAC_SBR_PS_ON_FLAG_OFF && - config->sbr_ps_on_flag != AUDIO_AAC_SBR_PS_ON_FLAG_ON) - goto done; -#endif - - if (config->dual_mono_mode > AUDIO_AAC_DUAL_MONO_PL_SR) - goto done; - - if (config->channel_configuration > 2) - goto done; - - ret_val = 0; - done: - return ret_val; -} - -static void audio_ioport_reset(struct audio *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audio_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->read_wait); - mutex_lock(&audio->read_lock); - audio_flush_pcm_buf(audio); - mutex_unlock(&audio->read_lock); - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); - -} - -static int audaac_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audaac_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audaac_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audaac_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audaac_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - -static long audaac_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audaac_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - audio->event_wait, audaac_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audaac_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - rc = 0; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audaac_event, list); - list_del(&drv_evt->list); - } - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audio_enable_eq(struct audio *audio, int enable) -{ - if (audio->eq_enable == enable && !audio->eq_needs_commit) - return 0; - - audio->eq_enable = enable; - - if (audio->running) { - audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq, POPP); - audio->eq_needs_commit = 0; - } - return 0; -} - -static int audio_get_avsync_data(struct audio *audio, - struct msm_audio_stats *stats) -{ - int rc = -EINVAL; - unsigned long flags; - - local_irq_save(flags); - if (audio->dec_id == audio->avsync[0] && audio->avsync_flag) { - /* av_sync sample count */ - stats->sample_count = (audio->avsync[2] << 16) | - (audio->avsync[3]); - - /* av_sync byte_count */ - stats->byte_count = (audio->avsync[5] << 16) | - (audio->avsync[6]); - - audio->avsync_flag = 0; - rc = 0; - } - local_irq_restore(flags); - return rc; - -} - -static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - unsigned long flags = 0; - uint16_t enable_mask; - int enable; - int prev_state; - - MM_DBG("cmd = %d\n", cmd); - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - - audio->avsync_flag = 0; - memset(&stats, 0, sizeof(stats)); - if (audpp_query_avsync(audio->dec_id) < 0) - return rc; - - rc = wait_event_interruptible_timeout(audio->avsync_wait, - (audio->avsync_flag == 1), - msecs_to_jiffies(AUDPP_AVSYNC_EVENT_TIMEOUT)); - - if (rc < 0) - return rc; - else if ((rc > 0) || ((rc == 0) && (audio->avsync_flag == 1))) { - if (audio_get_avsync_data(audio, &stats) < 0) - return rc; - - if (copy_to_user((void *)arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } else - return -EAGAIN; - } - - switch (cmd) { - case AUDIO_ENABLE_AUDPP: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - spin_lock_irqsave(&audio->dsp_lock, flags); - enable = (enable_mask & EQ_ENABLE) ? 1 : 0; - audio_enable_eq(audio, enable); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - case AUDIO_SET_VOLUME: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.volume = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_PAN: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.pan = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_EQ: - prev_state = audio->eq_enable; - audio->eq_enable = 0; - if (copy_from_user(&audio->eq.num_bands, (void *) arg, - sizeof(audio->eq) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) { - rc = -EFAULT; - break; - } - audio->eq_enable = prev_state; - audio->eq_needs_commit = 1; - rc = 0; - break; - } - - if (-EINVAL != rc) - return rc; - - if (cmd == AUDIO_GET_EVENT) { - MM_DBG("AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audaac_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audio_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) - rc = -ENODEV; - else - rc = 0; - } - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audio_disable(audio); - audio->stopped = 1; - audio_ioport_reset(audio); - audio->stopped = 0; - break; - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH running=%d\n", audio->running); - audio->rflush = 1; - audio->wflush = 1; - audio_ioport_reset(audio); - if (audio->running) { - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - - case AUDIO_OUTPORT_FLUSH: - MM_DBG("AUDIO_OUTPORT_FLUSH\n"); - audio->rflush = 1; - wake_up(&audio->read_wait); - mutex_lock(&audio->read_lock); - audio_flush_pcm_buf(audio); - mutex_unlock(&audio->read_lock); - audplay_outport_flush(audio); - rc = wait_event_interruptible(audio->read_wait, - !audio->rflush); - if (rc < 0) { - MM_ERR("AUDPLAY_OUTPORT_FLUSH interrupted\n"); - rc = -EINTR; - } - break; - - case AUDIO_SET_CONFIG:{ - struct msm_audio_config config; - - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - - if (config.channel_count == 1) { - config.channel_count = - AUDPP_CMD_PCM_INTF_MONO_V; - } else if (config.channel_count == 2) { - config.channel_count = - AUDPP_CMD_PCM_INTF_STEREO_V; - } else { - rc = -EINVAL; - break; - } - - audio->out_sample_rate = config.sample_rate; - audio->out_channel_mode = config.channel_count; - audio->mfield = config.meta_field; - rc = 0; - break; - } - case AUDIO_GET_CONFIG:{ - struct msm_audio_config config; - config.buffer_size = (audio->out_dma_sz >> 1); - config.buffer_count = 2; - config.sample_rate = audio->out_sample_rate; - if (audio->out_channel_mode == - AUDPP_CMD_PCM_INTF_MONO_V) { - config.channel_count = 1; - } else { - config.channel_count = 2; - } - config.meta_field = 0; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - - break; - } - case AUDIO_GET_AAC_CONFIG:{ - if (copy_to_user((void *)arg, &audio->aac_config, - sizeof(audio->aac_config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_AAC_CONFIG:{ - struct msm_audio_aac_config usr_config; - - if (copy_from_user - (&usr_config, (void *)arg, - sizeof(usr_config))) { - rc = -EFAULT; - break; - } - - if (audaac_validate_usr_config(&usr_config) == 0) { - audio->aac_config = usr_config; - rc = 0; - } else - rc = -EINVAL; - - break; - } - case AUDIO_GET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - config.pcm_feedback = audio->pcm_feedback; - config.buffer_count = PCM_BUF_MAX_COUNT; - config.buffer_size = PCM_BUFSZ_MIN; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.pcm_feedback != audio->pcm_feedback) { - MM_ERR("Not sufficient permission to" - "change the playback mode\n"); - rc = -EACCES; - break; - } - if ((config.buffer_count > PCM_BUF_MAX_COUNT) || - (config.buffer_count == 1)) - config.buffer_count = PCM_BUF_MAX_COUNT; - - if (config.buffer_size < PCM_BUFSZ_MIN) - config.buffer_size = PCM_BUFSZ_MIN; - - /* Check if pcm feedback is required */ - if (config.pcm_feedback) { - audio->buf_refresh = 0; - audio->read_next = 0; - audio->fill_next = 0; - } - rc = 0; - break; - } - case AUDIO_PAUSE: - MM_DBG("AUDIO_PAUSE %ld\n", arg); - rc = audpp_pause(audio->dec_id, (int) arg); - break; - case AUDIO_GET_STREAM_INFO:{ - if (audio->stream_info.sample_rate == 0) { - /* haven't received DSP stream event, - the stream info is not updated */ - rc = -EPERM; - break; - } - if (copy_to_user((void *)arg, &audio->stream_info, - sizeof(struct msm_audio_bitstream_info))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_GET_BITSTREAM_ERROR_INFO:{ - if ((audio->bitstream_error_info.err_msg_indicator & - AUDPLAY_STREAM_INFO_MSG_MASK) == - AUDPLAY_STREAM_INFO_MSG_MASK) { - /* haven't received bitstream error info event, - the bitstream error info is not updated */ - rc = -EPERM; - break; - } - if (copy_to_user((void *)arg, &audio->bitstream_error_info, - sizeof(struct msm_audio_bitstream_error_info))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_GET_SESSION_ID: - if (copy_to_user((void *) arg, &audio->dec_id, - sizeof(unsigned short))) - rc = -EFAULT; - else - rc = 0; - break; - case AUDIO_SET_ERR_THRESHOLD_VALUE: - if (copy_from_user(&audio->bitstream_error_threshold_value, - (void *)arg, sizeof(uint32_t))) - rc = -EFAULT; - else - rc = 0; - break; - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} -/* Only useful in tunnel-mode */ -static int audaac_fsync(struct file *file, loff_t ppos1, loff_t ppos2, int datasync) -{ - struct audio *audio = file->private_data; - struct buffer *frame; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (!audio->running || audio->pcm_feedback) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (audio->reserved) { - MM_DBG("send reserved byte\n"); - frame = audio->out + audio->out_tail; - ((char *) frame->data)[0] = audio->rsv_byte; - ((char *) frame->data)[1] = 0; - frame->used = 2; - audplay_send_data(audio, 0); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - } - - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush); - - if (audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; -} - -static ssize_t audio_read(struct file *file, char __user *buf, size_t count, - loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - int rc = 0; - - if (!audio->pcm_feedback) - return 0; /* PCM feedback is not enabled. Nothing to read */ - - mutex_lock(&audio->read_lock); - MM_DBG("to read %d \n", count); - while (count > 0) { - rc = wait_event_interruptible_timeout(audio->read_wait, - (audio->in[audio->read_next]. - used > 0) || (audio->stopped) - || (audio->rflush), - msecs_to_jiffies(MSM_AUD_BUFFER_UPDATE_WAIT_MS)); - - if (rc == 0) { - rc = -ETIMEDOUT; - break; - } else if (rc < 0) - break; - - if (audio->stopped || audio->rflush) { - rc = -EBUSY; - break; - } - - if (count < audio->in[audio->read_next].used) { - /* Read must happen in frame boundary. Since driver - does not know frame size, read count must be greater - or equal to size of PCM samples */ - MM_DBG("no partial frame done reading\n"); - break; - } else { - MM_DBG("read from in[%d]\n", audio->read_next); - if (copy_to_user - (buf, audio->in[audio->read_next].data, - audio->in[audio->read_next].used)) { - MM_ERR("invalid addr %x\n", (unsigned int)buf); - rc = -EFAULT; - break; - } - count -= audio->in[audio->read_next].used; - buf += audio->in[audio->read_next].used; - audio->in[audio->read_next].used = 0; - if ((++audio->read_next) == audio->pcm_buf_count) - audio->read_next = 0; - break; - /* - * Force to exit while loop - * to prevent output thread - * sleep too long if data is not - * ready at this moment. - */ - } - } - - /* don't feed output buffer to HW decoder during flushing - * buffer refresh command will be sent once flush completes - * send buf refresh command here can confuse HW decoder - */ - if (audio->buf_refresh && !audio->rflush) { - audio->buf_refresh = 0; - MM_DBG("kick start pcm feedback again\n"); - audplay_buffer_refresh(audio); - } - - mutex_unlock(&audio->read_lock); - - if (buf > start) - rc = buf - start; - - MM_DBG("read %d bytes\n", rc); - return rc; -} - -static int audaac_process_eos(struct audio *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - struct buffer *frame; - char *buf_ptr; - int rc = 0; - - MM_DBG("signal input EOS reserved=%d\n", audio->reserved); - if (audio->reserved) { - MM_DBG("Pass reserve byte\n"); - frame = audio->out + audio->out_head; - buf_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - buf_ptr[0] = audio->rsv_byte; - buf_ptr[1] = 0; - audio->out_head ^= 1; - frame->mfield_sz = 0; - audio->reserved = 0; - frame->used = 2; - audplay_send_data(audio, 0); - } - MM_DBG("Now signal input EOS after reserved bytes %d %d %d\n", - audio->out[0].used, audio->out[1].used, audio->out_needed); - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - audplay_send_data(audio, 0); -done: - return rc; -} -static ssize_t audio_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - char *cpy_ptr; - int rc = 0, eos_condition = AUDAAC_EOS_NONE; - unsigned dsize; - - unsigned short mfield_size = 0; - MM_DBG("cnt=%d\n", count); - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - cpy_ptr = frame->data; - dsize = 0; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - break; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - break; - } - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - break; - } else if (mfield_size > count) { - rc = -EINVAL; - break; - } - MM_DBG("mf offset_val %x\n", mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - break; - } - /* Check if EOS flag is set and buffer has - * contains just meta field - */ - if (cpy_ptr[AUDAAC_EOS_FLG_OFFSET] & - AUDAAC_EOS_FLG_MASK) { - MM_DBG("eos set\n"); - eos_condition = AUDAAC_EOS_SET; - if (mfield_size == count) { - buf += mfield_size; - break; - } else - cpy_ptr[AUDAAC_EOS_FLG_OFFSET] &= - ~AUDAAC_EOS_FLG_MASK; - } - /* Check EOS to see if */ - cpy_ptr += mfield_size; - count -= mfield_size; - dsize += mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - - if (audio->reserved) { - MM_DBG("append reserved byte %x\n", - audio->rsv_byte); - *cpy_ptr = audio->rsv_byte; - xfer = (count > ((frame->size - mfield_size) - 1)) ? - (frame->size - mfield_size) - 1 : count; - cpy_ptr++; - dsize += 1; - audio->reserved = 0; - } else - xfer = (count > (frame->size - mfield_size)) ? - (frame->size - mfield_size) : count; - - if (copy_from_user(cpy_ptr, buf, xfer)) { - rc = -EFAULT; - break; - } - - dsize += xfer; - if (dsize & 1) { - audio->rsv_byte = ((char *) frame->data)[dsize - 1]; - MM_DBG("odd length buf reserve last byte %x\n", - audio->rsv_byte); - audio->reserved = 1; - dsize--; - } - count -= xfer; - buf += xfer; - - if (dsize > 0) { - audio->out_head ^= 1; - frame->used = dsize; - audplay_send_data(audio, 0); - } - } - MM_DBG("eos_condition %x buf[0x%x] start[0x%x]\n", eos_condition, - (int) buf, (int) start); - if (eos_condition == AUDAAC_EOS_SET) - rc = audaac_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - if (!rc) { - if (buf > start) - return buf - start; - } - return rc; -} - -static int audio_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_INFO("audio instance 0x%08x freeing\n", (int)audio); - - mutex_lock(&audio->lock); - auddev_unregister_evt_listner(AUDDEV_CLNT_DEC, audio->dec_id); - audio_disable(audio); - audio_flush(audio); - audio_flush_pcm_buf(audio); - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->event_abort = 1; - wake_up(&audio->event_wait); - audaac_reset_event_queue(audio); - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - iounmap(audio->map_v_read); - free_contiguous_memory_by_paddr(audio->read_phys); - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - kfree(audio); - return 0; -} - -static void audaac_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audaac_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audaac_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audaac_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audaac_suspend(struct early_suspend *h) -{ - struct audaac_suspend_ctl *ctl = - container_of(h, struct audaac_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audaac_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audaac_resume(struct early_suspend *h) -{ - struct audaac_suspend_ctl *ctl = - container_of(h, struct audaac_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audaac_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audaac_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audaac_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 1024; - static char buffer[1024]; - int n = 0, i; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_feedback %d\n", audio->pcm_feedback); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_buf_sz %d\n", audio->out[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_count %d \n", audio->pcm_buf_count); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_sz %d \n", audio->in[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %x \n", audio->vol_pan.volume); - n += scnprintf(buffer + n, debug_bufmax - n, - "sample rate %d \n", audio->out_sample_rate); - n += scnprintf(buffer + n, debug_bufmax - n, - "channel mode %d \n", audio->out_channel_mode); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "rflush %d\n", audio->rflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d \n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d \n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d \n", audio->out_needed); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_head %d \n", audio->out_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_tail %d \n", audio->out_tail); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[0].used %d \n", audio->out[0].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[1].used %d \n", audio->out[1].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "buffer_refresh %d \n", audio->buf_refresh); - n += scnprintf(buffer + n, debug_bufmax - n, - "read_next %d \n", audio->read_next); - n += scnprintf(buffer + n, debug_bufmax - n, - "fill_next %d \n", audio->fill_next); - for (i = 0; i < audio->pcm_buf_count; i++) - n += scnprintf(buffer + n, debug_bufmax - n, - "in[%d].used %d \n", i, audio->in[i].used); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audaac_debug_fops = { - .read = audaac_debug_read, - .open = audaac_debug_open, -}; -#endif - -static int audio_open(struct inode *inode, struct file *file) -{ - struct audio *audio = NULL; - int rc, dec_attrb, decid, index, offset = 0; - unsigned pmem_sz = DMASZ; - struct audaac_event *e_node = NULL; -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_aac_" + 5]; -#endif - - /* Allocate audio instance, set to zero */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("no memory to allocate audio instance \n"); - rc = -ENOMEM; - goto done; - } - MM_INFO("audio instance 0x%08x created\n", (int)audio); - - /* Allocate the decoder */ - dec_attrb = AUDDEC_DEC_AAC; - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_NONTUNNEL; - audio->pcm_feedback = NON_TUNNEL_MODE_PLAYBACK; - } else if ((file->f_mode & FMODE_WRITE) && - !(file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_TUNNEL; - audio->pcm_feedback = TUNNEL_MODE_PLAYBACK; - } else { - kfree(audio); - rc = -EACCES; - goto done; - } - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - - if (decid < 0) { - MM_ERR("No free decoder available, freeing instance 0x%08x\n", - (int)audio); - rc = -ENODEV; - kfree(audio); - goto done; - } - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - while (pmem_sz >= DMASZ_MIN) { - MM_DBG("pmemsz = %d\n", pmem_sz); - audio->phys = allocate_contiguous_ebi_nomap(pmem_sz, SZ_4K); - if (audio->phys) { - audio->map_v_write = - ioremap(audio->phys, - pmem_sz); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write phys address, \ - freeing instance 0x%08x\n", - (int)audio); - rc = -ENOMEM; - free_contiguous_memory_by_paddr(audio->phys); - audpp_adec_free(audio->dec_id); - kfree(audio); - goto done; - } - audio->data = (u8 *)audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr \ - 0x%08x\n", audio->phys, (int)audio->data); - break; - } else if (pmem_sz == DMASZ_MIN) { - MM_ERR("could not allocate write buffers, freeing \ - instance 0x%08x\n", (int)audio); - rc = -ENOMEM; - audpp_adec_free(audio->dec_id); - kfree(audio); - goto done; - } else - pmem_sz >>= 1; - } - audio->out_dma_sz = pmem_sz; - - audio->read_phys = allocate_contiguous_ebi_nomap(PCM_BUFSZ_MIN - * PCM_BUF_MAX_COUNT, SZ_4K); - if (!audio->read_phys) { - MM_ERR("could not allocate read buffers, freeing instance \ - 0x%08x\n", (int)audio); - rc = -ENOMEM; - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - audpp_adec_free(audio->dec_id); - kfree(audio); - goto done; - } - audio->map_v_read = ioremap(audio->read_phys, - PCM_BUFSZ_MIN * PCM_BUF_MAX_COUNT); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("could not map read phys address, freeing instance \ - 0x%08x\n", (int)audio); - rc = -ENOMEM; - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - free_contiguous_memory_by_paddr(audio->read_phys); - audpp_adec_free(audio->dec_id); - kfree(audio); - goto done; - } - audio->read_data = audio->map_v_read; - MM_DBG("read buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->read_phys, (int)audio->read_data); - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audplay_adsp_ops_aac, audio); - if (rc) { - MM_ERR("failed to get %s module, freeing instance 0x%08x\n", - audio->module_name, (int)audio); - goto err; - } - - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->read_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - spin_lock_init(&audio->event_queue_lock); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->write_wait); - init_waitqueue_head(&audio->read_wait); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - init_waitqueue_head(&audio->avsync_wait); - - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = audio->out_dma_sz >> 1; - - audio->out[1].data = audio->data + audio->out[0].size; - audio->out[1].addr = audio->phys + audio->out[0].size; - audio->out[1].size = audio->out[0].size; - - audio->pcm_buf_count = PCM_BUF_MAX_COUNT; - for (index = 0; index < PCM_BUF_MAX_COUNT; index++) { - audio->in[index].data = audio->read_data + offset; - audio->in[index].addr = audio->read_phys + offset; - audio->in[index].size = PCM_BUFSZ_MIN; - audio->in[index].used = 0; - offset += PCM_BUFSZ_MIN; - } - - audio->out_sample_rate = 44100; - audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V; - audio->aac_config.format = AUDIO_AAC_FORMAT_ADTS; - audio->aac_config.audio_object = AUDIO_AAC_OBJECT_LC; - audio->aac_config.ep_config = 0; - audio->aac_config.aac_section_data_resilience_flag = - AUDIO_AAC_SEC_DATA_RES_OFF; - audio->aac_config.aac_scalefactor_data_resilience_flag = - AUDIO_AAC_SCA_DATA_RES_OFF; - audio->aac_config.aac_spectral_data_resilience_flag = - AUDIO_AAC_SPEC_DATA_RES_OFF; -#ifdef CONFIG_AUDIO_AAC_PLUS - audio->aac_config.sbr_on_flag = AUDIO_AAC_SBR_ON_FLAG_ON; -#else - audio->aac_config.sbr_on_flag = AUDIO_AAC_SBR_ON_FLAG_OFF; -#endif -#ifdef CONFIG_AUDIO_ENHANCED_AAC_PLUS - audio->aac_config.sbr_ps_on_flag = AUDIO_AAC_SBR_PS_ON_FLAG_ON; -#else - audio->aac_config.sbr_ps_on_flag = AUDIO_AAC_SBR_PS_ON_FLAG_OFF; -#endif - audio->aac_config.dual_mono_mode = AUDIO_AAC_DUAL_MONO_PL_SR; - audio->aac_config.channel_configuration = 2; - audio->vol_pan.volume = 0x2000; - audio->bitstream_error_threshold_value = - BITSTREAM_ERROR_THRESHOLD_VALUE; - - audio_flush(audio); - - file->private_data = audio; - audio->opened = 1; - - audio->device_events = AUDDEV_EVT_DEV_RDY - |AUDDEV_EVT_DEV_RLS| - AUDDEV_EVT_STREAM_VOL_CHG; - - rc = auddev_register_evt_listner(audio->device_events, - AUDDEV_CLNT_DEC, - audio->dec_id, - aac_listner, - (void *)audio); - if (rc) { - MM_ERR("%s: failed to register listner\n", __func__); - goto event_err; - } - -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_aac_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, - &audaac_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audaac_resume; - audio->suspend_ctl.node.suspend = audaac_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (index = 0; index < AUDAAC_EVENT_NUM; index++) { - e_node = kmalloc(sizeof(struct audaac_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } - memset(&audio->stream_info, 0, sizeof(struct msm_audio_bitstream_info)); - memset(&audio->bitstream_error_info, 0, - sizeof(struct msm_audio_bitstream_info)); -done: - return rc; -event_err: - msm_adsp_put(audio->audplay); -err: - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - iounmap(audio->map_v_read); - free_contiguous_memory_by_paddr(audio->read_phys); - audpp_adec_free(audio->dec_id); - kfree(audio); - return rc; -} - -static const struct file_operations audio_aac_fops = { - .owner = THIS_MODULE, - .open = audio_open, - .release = audio_release, - .read = audio_read, - .write = audio_write, - .unlocked_ioctl = audio_ioctl, - .fsync = audaac_fsync -}; - -struct miscdevice audio_aac_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_aac", - .fops = &audio_aac_fops, -}; - -static int __init audio_init(void) -{ - return misc_register(&audio_aac_misc); -} - -static void __exit audio_exit(void) -{ - misc_deregister(&audio_aac_misc); -} - -module_init(audio_init); -module_exit(audio_exit); - -MODULE_DESCRIPTION("MSM AAC driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_aac_in.c b/arch/arm/mach-msm/qdsp5v2/audio_aac_in.c deleted file mode 100644 index a878e129dbe5bf6c7028073e351e3beaa997c395..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_aac_in.c +++ /dev/null @@ -1,1482 +0,0 @@ -/* - * aac audio input device - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* FRAME_NUM must be a power of two */ -#define FRAME_NUM (8) -#define FRAME_SIZE (772 * 2) /* 1536 bytes data */ -#define NT_FRAME_SIZE (780 * 2) /* 1536 bytes data + 24 meta field*/ -#define AAC_FRAME_SIZE 1536 -#define DMASZ (FRAME_SIZE * FRAME_NUM) -#define OUT_FRAME_NUM (2) -#define META_OUT_SIZE (24) -#define META_IN_SIZE (14) -#define OUT_BUFFER_SIZE (32 * 1024 + META_OUT_SIZE) -#define BUFFER_SIZE (OUT_BUFFER_SIZE * OUT_FRAME_NUM) - -#define AUDPREPROC_AAC_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */ -#define AUDPREPROC_AAC_EOS_FLG_MASK 0x01 -#define AUDPREPROC_AAC_EOS_NONE 0x0 /* No EOS detected */ -#define AUDPREPROC_AAC_EOS_SET 0x1 /* EOS set in meta field */ - -#define PCM_CONFIG_UPDATE_FLAG_ENABLE -1 -#define PCM_CONFIG_UPDATE_FLAG_DISABLE 0 - -#define ENABLE_FLAG_VALUE -1 -#define DISABLE_FLAG_VALUE 0 - -struct buffer { - void *data; - uint32_t size; - uint32_t read; - uint32_t addr; - uint32_t used; - uint32_t mfield_sz; -}; - -struct audio_in { - struct buffer in[FRAME_NUM]; - - spinlock_t dsp_lock; - - atomic_t in_bytes; - atomic_t in_samples; - - struct mutex lock; - struct mutex read_lock; - wait_queue_head_t wait; - wait_queue_head_t wait_enable; - /*write section*/ - struct buffer out[OUT_FRAME_NUM]; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - uint32_t out_count; - - struct mutex write_lock; - wait_queue_head_t write_wait; - int32_t out_phys; /* physical address of write buffer */ - char *out_data; - void *map_v_read; - void *map_v_write; - - int mfield; /* meta field embedded in data */ - int wflush; /*write flush */ - int rflush; /*read flush*/ - int out_frame_cnt; - - struct msm_adsp_module *audrec; - - /* configuration to use on next enable */ - uint32_t buffer_size; /* Frame size (36 bytes) */ - uint32_t samp_rate; - uint32_t channel_mode; - uint32_t bit_rate; /* bit rate for AAC */ - uint32_t record_quality; /* record quality (bits/sample/channel) */ - uint32_t enc_type; - - uint32_t dsp_cnt; - uint32_t in_head; /* next buffer dsp will write */ - uint32_t in_tail; /* next buffer read() will read */ - uint32_t in_count; /* number of buffers available to read() */ - uint32_t mode; - uint32_t eos_ack; - uint32_t flush_ack; - - const char *module_name; - unsigned queue_ids; - uint16_t enc_id; - - struct audrec_session_info session_info; /*audrec session info*/ - uint16_t source; /* Encoding source bit mask */ - uint32_t device_events; /* device events interested in */ - uint32_t dev_cnt; - spinlock_t dev_lock; - - /* data allocated for various buffers */ - char *data; - dma_addr_t phys; - - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - int abort; /* set when error, like sample rate mismatch */ - char *build_id; -}; - -struct audio_frame { - uint16_t frame_count_lsw; - uint16_t frame_count_msw; - uint16_t frame_length; - uint16_t erased_pcm; - unsigned char raw_bitstream[]; /* samples */ -} __attribute__((packed)); - -struct audio_frame_nt { - uint16_t metadata_len; - uint16_t frame_count_lsw; - uint16_t frame_count_msw; - uint16_t frame_length; - uint16_t erased_pcm; - uint16_t reserved; - uint16_t time_stamp_dword_lsw; - uint16_t time_stamp_dword_msw; - uint16_t time_stamp_lsw; - uint16_t time_stamp_msw; - uint16_t nflag_lsw; - uint16_t nflag_msw; - unsigned char raw_bitstream[]; /* samples */ -} __attribute__((packed)); - -struct aac_encoded_meta_in { - uint16_t metadata_len; - uint16_t time_stamp_dword_lsw; - uint16_t time_stamp_dword_msw; - uint16_t time_stamp_lsw; - uint16_t time_stamp_msw; - uint16_t nflag_lsw; - uint16_t nflag_msw; -}; - -/* Audrec Queue command sent macro's */ -#define audrec_send_bitstreamqueue(audio, cmd, len) \ - msm_adsp_write(audio->audrec, ((audio->queue_ids & 0xFFFF0000) >> 16),\ - cmd, len) - -#define audrec_send_audrecqueue(audio, cmd, len) \ - msm_adsp_write(audio->audrec, (audio->queue_ids & 0x0000FFFF),\ - cmd, len) - -/* DSP command send functions */ -static int audaac_in_enc_config(struct audio_in *audio, int enable); -static int audaac_in_param_config(struct audio_in *audio); -static int audaac_in_mem_config(struct audio_in *audio); -static int audaac_in_record_config(struct audio_in *audio, int enable); -static int audaac_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt); - -static void audaac_in_get_dsp_frames(struct audio_in *audio); -static int audpcm_config(struct audio_in *audio); -static void audaac_out_flush(struct audio_in *audio); -static int audpreproc_cmd_cfg_routing_mode(struct audio_in *audio); -static void audpreproc_pcm_send_data(struct audio_in *audio, unsigned needed); -static void audaac_nt_in_get_dsp_frames(struct audio_in *audio); - -static void audaac_in_flush(struct audio_in *audio); - -static void aac_in_listener(u32 evt_id, union auddev_evt_data *evt_payload, - void *private_data) -{ - struct audio_in *audio = (struct audio_in *) private_data; - unsigned long flags; - - MM_DBG("evt_id = 0x%8x\n", evt_id); - switch (evt_id) { - case AUDDEV_EVT_DEV_RDY: { - MM_DBG("AUDDEV_EVT_DEV_RDY\n"); - spin_lock_irqsave(&audio->dev_lock, flags); - audio->dev_cnt++; - audio->source |= (0x1 << evt_payload->routing_id); - spin_unlock_irqrestore(&audio->dev_lock, flags); - - if ((audio->running == 1) && (audio->enabled == 1) && - (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)) - audaac_in_record_config(audio, 1); - - break; - } - case AUDDEV_EVT_DEV_RLS: { - MM_DBG("AUDDEV_EVT_DEV_RLS\n"); - spin_lock_irqsave(&audio->dev_lock, flags); - audio->dev_cnt--; - audio->source &= ~(0x1 << evt_payload->routing_id); - spin_unlock_irqrestore(&audio->dev_lock, flags); - - if ((!audio->running) || (!audio->enabled)) - break; - - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - /* Turn of as per source */ - if (audio->source) - audaac_in_record_config(audio, 1); - else - /* Turn off all */ - audaac_in_record_config(audio, 0); - } - break; - } - case AUDDEV_EVT_FREQ_CHG: { - MM_DBG("Encoder Driver got sample rate change event\n"); - MM_DBG("sample rate %d\n", evt_payload->freq_info.sample_rate); - MM_DBG("dev_type %d\n", evt_payload->freq_info.dev_type); - MM_DBG("acdb_dev_id %d\n", evt_payload->freq_info.acdb_dev_id); - if ((audio->running == 1) && (audio->enabled == 1)) { - /* Stop Recording sample rate does not match - with device sample rate */ - if (evt_payload->freq_info.sample_rate != - audio->samp_rate) { - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - audaac_in_record_config(audio, 0); - audio->abort = 1; - wake_up(&audio->wait); - } - } - break; - } - default: - MM_ERR("wrong event %d\n", evt_id); - break; - } -} - -/* Convert Bit Rate to Record Quality field of DSP */ -static unsigned int bitrate_to_record_quality(unsigned int sample_rate, - unsigned int channel, unsigned int bit_rate) { - unsigned int temp; - - temp = sample_rate * channel; - MM_DBG(" sample rate * channel = %d \n", temp); - /* To represent in Q12 fixed format */ - temp = (bit_rate * 4096) / temp; - MM_DBG(" Record Quality = 0x%8x \n", temp); - return temp; -} - -/* ------------------- dsp preproc event handler--------------------- */ -static void audpreproc_dsp_event(void *data, unsigned id, void *msg) -{ - struct audio_in *audio = data; - - switch (id) { - case AUDPREPROC_ERROR_MSG: { - struct audpreproc_err_msg *err_msg = msg; - - MM_ERR("ERROR_MSG: stream id %d err idx %d\n", - err_msg->stream_id, err_msg->aud_preproc_err_idx); - /* Error case */ - wake_up(&audio->wait_enable); - break; - } - case AUDPREPROC_CMD_CFG_DONE_MSG: { - MM_DBG("CMD_CFG_DONE_MSG \n"); - break; - } - case AUDPREPROC_CMD_ENC_CFG_DONE_MSG: { - struct audpreproc_cmd_enc_cfg_done_msg *enc_cfg_msg = msg; - - MM_DBG("CMD_ENC_CFG_DONE_MSG: stream id %d enc type \ - 0x%8x\n", enc_cfg_msg->stream_id, - enc_cfg_msg->rec_enc_type); - /* Encoder enable success */ - if (enc_cfg_msg->rec_enc_type & ENCODE_ENABLE) { - if(audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) { - MM_DBG("routing command\n"); - audpreproc_cmd_cfg_routing_mode(audio); - } else { - audaac_in_param_config(audio); - } - } else { /* Encoder disable success */ - audio->running = 0; - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - audaac_in_record_config(audio, 0); - else - wake_up(&audio->wait_enable); - } - break; - } - case AUDPREPROC_CMD_ENC_PARAM_CFG_DONE_MSG: { - MM_DBG("CMD_ENC_PARAM_CFG_DONE_MSG\n"); - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - audaac_in_mem_config(audio); - else - audpcm_config(audio); - break; - } - case AUDPREPROC_CMD_ROUTING_MODE_DONE_MSG: { - struct audpreproc_cmd_routing_mode_done\ - *routing_cfg_done_msg = msg; - if (routing_cfg_done_msg->configuration == 0) { - MM_INFO("routing configuration failed\n"); - audio->running = 0; - } else - audaac_in_param_config(audio); - break; - } - case AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG_DONE_MSG: { - MM_DBG("AFE_CMD_AUDIO_RECORD_CFG_DONE_MSG\n"); - wake_up(&audio->wait_enable); - break; - } - default: - MM_ERR("Unknown Event id %d\n", id); - } -} - -/* ------------------- dsp audrec event handler--------------------- */ -static void audrec_dsp_event(void *data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - struct audio_in *audio = data; - - switch (id) { - case AUDREC_CMD_MEM_CFG_DONE_MSG: { - MM_DBG("CMD_MEM_CFG_DONE MSG DONE\n"); - audio->running = 1; - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - if (audio->dev_cnt > 0) - audaac_in_record_config(audio, 1); - } else { - audpreproc_pcm_send_data(audio, 1); - wake_up(&audio->wait_enable); - } - break; - } - case AUDREC_FATAL_ERR_MSG: { - struct audrec_fatal_err_msg fatal_err_msg; - - getevent(&fatal_err_msg, AUDREC_FATAL_ERR_MSG_LEN); - MM_ERR("FATAL_ERR_MSG: err id %d\n", - fatal_err_msg.audrec_err_id); - /* Error stop the encoder */ - audio->stopped = 1; - wake_up(&audio->wait); - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) - wake_up(&audio->write_wait); - break; - } - case AUDREC_UP_PACKET_READY_MSG: { - struct audrec_up_pkt_ready_msg pkt_ready_msg; - - getevent(&pkt_ready_msg, AUDREC_UP_PACKET_READY_MSG_LEN); - MM_DBG("UP_PACKET_READY_MSG: write cnt lsw %d \ - write cnt msw %d read cnt lsw %d read cnt msw %d \n",\ - pkt_ready_msg.audrec_packet_write_cnt_lsw, \ - pkt_ready_msg.audrec_packet_write_cnt_msw, \ - pkt_ready_msg.audrec_up_prev_read_cnt_lsw, \ - pkt_ready_msg.audrec_up_prev_read_cnt_msw); - - audaac_in_get_dsp_frames(audio); - break; - } - case AUDREC_CMD_PCM_BUFFER_PTR_UPDATE_ARM_TO_ENC_MSG: { - MM_DBG("ptr_update recieved from DSP\n"); - audpreproc_pcm_send_data(audio, 1); - break; - } - case AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG: { - MM_ERR("AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG"); - audaac_in_mem_config(audio); - break; - } - case AUDREC_UP_NT_PACKET_READY_MSG: { - struct audrec_up_nt_packet_ready_msg pkt_ready_msg; - - getevent(&pkt_ready_msg, AUDREC_UP_NT_PACKET_READY_MSG_LEN); - MM_DBG("UP_NT_PACKET_READY_MSG: write cnt lsw %d \ - write cnt msw %d read cnt lsw %d read cnt msw %d \n",\ - pkt_ready_msg.audrec_packetwrite_cnt_lsw, \ - pkt_ready_msg.audrec_packetwrite_cnt_msw, \ - pkt_ready_msg.audrec_upprev_readcount_lsw, \ - pkt_ready_msg.audrec_upprev_readcount_msw); - - audaac_nt_in_get_dsp_frames(audio); - break; - } - case AUDREC_CMD_EOS_ACK_MSG: { - MM_DBG("eos ack recieved\n"); - break; - } - case AUDREC_CMD_FLUSH_DONE_MSG: { - audio->wflush = 0; - audio->rflush = 0; - audio->flush_ack = 1; - wake_up(&audio->write_wait); - MM_DBG("flush ack recieved\n"); - break; - } - case ADSP_MESSAGE_ID: { - MM_DBG("Received ADSP event:module audrectask\n"); - break; - } - default: - MM_ERR("Unknown Event id %d\n", id); - } -} - -static void audaac_in_get_dsp_frames(struct audio_in *audio) -{ - struct audio_frame *frame; - uint32_t index; - unsigned long flags; - - MM_DBG("head = %d\n", audio->in_head); - index = audio->in_head; - - frame = (void *) (((char *)audio->in[index].data) - \ - sizeof(*frame)); - - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->in[index].size = frame->frame_length; - - /* statistics of read */ - atomic_add(audio->in[index].size, &audio->in_bytes); - atomic_add(1, &audio->in_samples); - - audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1); - - /* If overflow, move the tail index foward. */ - if (audio->in_head == audio->in_tail) { - MM_ERR("Error! not able to keep up the read\n"); - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - } else - audio->in_count++; - - audaac_dsp_read_buffer(audio, audio->dsp_cnt++); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - - wake_up(&audio->wait); -} - -static void audaac_nt_in_get_dsp_frames(struct audio_in *audio) -{ - struct audio_frame_nt *nt_frame; - uint32_t index; - unsigned long flags; - MM_DBG("head = %d\n", audio->in_head); - index = audio->in_head; - nt_frame = (void *) (((char *)audio->in[index].data) - \ - sizeof(struct audio_frame_nt)); - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->in[index].size = nt_frame->frame_length; - /* statistics of read */ - atomic_add(audio->in[index].size, &audio->in_bytes); - atomic_add(1, &audio->in_samples); - - audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1); - - /* If overflow, move the tail index foward. */ - if (audio->in_head == audio->in_tail) - MM_DBG("Error! not able to keep up the read\n"); - else - audio->in_count++; - - spin_unlock_irqrestore(&audio->dsp_lock, flags); - wake_up(&audio->wait); -} - - -struct msm_adsp_ops audrec_aac_adsp_ops = { - .event = audrec_dsp_event, -}; - -static int audpreproc_pcm_buffer_ptr_refresh(struct audio_in *audio, - unsigned idx, unsigned len) -{ - struct audrec_cmd_pcm_buffer_ptr_refresh_arm_enc cmd; - - if (len == META_OUT_SIZE) - len = len / 2; - else - len = (len + META_OUT_SIZE) / 2; - MM_DBG("len = %d\n", len); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_PCM_BUFFER_PTR_REFRESH_ARM_TO_ENC; - cmd.num_buffers = 1; - if (cmd.num_buffers == 1) { - cmd.buf_address_length[0] = (audio->out[idx].addr & - 0xffff0000) >> 16; - cmd.buf_address_length[1] = (audio->out[idx].addr & - 0x0000ffff); - cmd.buf_address_length[2] = (len & 0xffff0000) >> 16; - cmd.buf_address_length[3] = (len & 0x0000ffff); - } - audio->out_frame_cnt++; - return audrec_send_audrecqueue(audio, (void *)&cmd, - (unsigned int)sizeof(cmd)); -} - - -static int audpcm_config(struct audio_in *audio) -{ - struct audrec_cmd_pcm_cfg_arm_to_enc cmd; - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_PCM_CFG_ARM_TO_ENC; - cmd.config_update_flag = PCM_CONFIG_UPDATE_FLAG_ENABLE; - cmd.enable_flag = ENABLE_FLAG_VALUE; - cmd.sampling_freq = audio->samp_rate; - if (!audio->channel_mode) - cmd.channels = 1; - else - cmd.channels = 2; - cmd.frequency_of_intimation = 1; - cmd.max_number_of_buffers = OUT_FRAME_NUM; - return audrec_send_audrecqueue(audio, (void *)&cmd, - (unsigned int)sizeof(cmd)); -} - - -static int audpreproc_cmd_cfg_routing_mode(struct audio_in *audio) -{ - struct audpreproc_audrec_cmd_routing_mode cmd; - - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPREPROC_AUDREC_CMD_ROUTING_MODE; - cmd.stream_id = audio->enc_id; - if (audio->mode == MSM_ADSP_ENC_MODE_NON_TUNNEL) - cmd.routing_mode = 1; - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); -} - - - -static int audaac_in_enc_config(struct audio_in *audio, int enable) -{ - struct audpreproc_audrec_cmd_enc_cfg cmd; - memset(&cmd, 0, sizeof(cmd)); - if (audio->build_id[17] == '1') { - cmd.cmd_id = AUDPREPROC_AUDREC_CMD_ENC_CFG_2; - MM_ERR("sending AUDPREPROC_AUDREC_CMD_ENC_CFG_2 command"); - } else { - cmd.cmd_id = AUDPREPROC_AUDREC_CMD_ENC_CFG; - MM_ERR("sending AUDPREPROC_AUDREC_CMD_ENC_CFG command"); - } - cmd.stream_id = audio->enc_id; - - if (enable) - cmd.audrec_enc_type = audio->enc_type | ENCODE_ENABLE; - else - cmd.audrec_enc_type &= ~(ENCODE_ENABLE); - - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); -} - -static int audaac_in_param_config(struct audio_in *audio) -{ - struct audpreproc_audrec_cmd_parm_cfg_aac cmd; - - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPREPROC_AUDREC_CMD_PARAM_CFG; - cmd.common.stream_id = audio->enc_id; - - cmd.aud_rec_samplerate_idx = audio->samp_rate; - cmd.aud_rec_stereo_mode = audio->channel_mode; - cmd.recording_quality = audio->record_quality; - - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); -} - -/* To Do: msm_snddev_route_enc(audio->enc_id); */ -static int audaac_in_record_config(struct audio_in *audio, int enable) -{ - struct audpreproc_afe_cmd_audio_record_cfg cmd; - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG; - cmd.stream_id = audio->enc_id; - if (enable) - cmd.destination_activity = AUDIO_RECORDING_TURN_ON; - else - cmd.destination_activity = AUDIO_RECORDING_TURN_OFF; - - cmd.source_mix_mask = audio->source; - if (audio->enc_id == 2) { - if ((cmd.source_mix_mask & INTERNAL_CODEC_TX_SOURCE_MIX_MASK) || - (cmd.source_mix_mask & AUX_CODEC_TX_SOURCE_MIX_MASK) || - (cmd.source_mix_mask & VOICE_UL_SOURCE_MIX_MASK) || - (cmd.source_mix_mask & VOICE_DL_SOURCE_MIX_MASK)) { - cmd.pipe_id = SOURCE_PIPE_1; - } - if (cmd.source_mix_mask & - AUDPP_A2DP_PIPE_SOURCE_MIX_MASK) - cmd.pipe_id |= SOURCE_PIPE_0; - } - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); -} - -static int audaac_in_mem_config(struct audio_in *audio) -{ - struct audrec_cmd_arecmem_cfg cmd; - uint16_t *data = (void *) audio->data; - int n; - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_MEM_CFG_CMD; - cmd.audrec_up_pkt_intm_count = 1; - cmd.audrec_ext_pkt_start_addr_msw = audio->phys >> 16; - cmd.audrec_ext_pkt_start_addr_lsw = audio->phys; - cmd.audrec_ext_pkt_buf_number = FRAME_NUM; - MM_DBG("audio->phys = %x\n", audio->phys); - /* prepare buffer pointers: - * 1536 bytes aac packet + 4 halfword header - */ - for (n = 0; n < FRAME_NUM; n++) { - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - audio->in[n].data = data + 4; - data += (FRAME_SIZE/2); - MM_DBG("0x%8x\n", (int)(audio->in[n].data - 8)); - } else { - audio->in[n].data = data + 12; - data += ((AAC_FRAME_SIZE) / 2) + 12; - MM_DBG("0x%8x\n", (int)(audio->in[n].data - 24)); - } - } - return audrec_send_audrecqueue(audio, &cmd, sizeof(cmd)); -} - -static int audaac_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt) -{ - struct up_audrec_packet_ext_ptr cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = UP_AUDREC_PACKET_EXT_PTR; - cmd.audrec_up_curr_read_count_msw = read_cnt >> 16; - cmd.audrec_up_curr_read_count_lsw = read_cnt; - - return audrec_send_bitstreamqueue(audio, &cmd, sizeof(cmd)); -} -static int audaac_flush_command(struct audio_in *audio) -{ - struct audrec_cmd_flush cmd; - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_FLUSH; - return audrec_send_audrecqueue(audio, &cmd, sizeof(cmd)); -} - -/* must be called with audio->lock held */ -static int audaac_in_enable(struct audio_in *audio) -{ - if (audio->enabled) - return 0; - - if (audpreproc_enable(audio->enc_id, &audpreproc_dsp_event, audio)) { - MM_ERR("msm_adsp_enable(audpreproc) failed\n"); - return -ENODEV; - } - - if (msm_adsp_enable(audio->audrec)) { - MM_ERR("msm_adsp_enable(audrec) failed\n"); - audpreproc_disable(audio->enc_id, audio); - return -ENODEV; - } - audio->enabled = 1; - audaac_in_enc_config(audio, 1); - - return 0; -} - -/* must be called with audio->lock held */ -static int audaac_in_disable(struct audio_in *audio) -{ - if (audio->enabled) { - audio->enabled = 0; - audaac_in_enc_config(audio, 0); - wake_up(&audio->wait); - wait_event_interruptible_timeout(audio->wait_enable, - audio->running == 0, 1*HZ); - msm_adsp_disable(audio->audrec); - audpreproc_disable(audio->enc_id, audio); - } - return 0; -} - -static void audaac_ioport_reset(struct audio_in *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audaac_in_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->wait); - mutex_lock(&audio->read_lock); - audaac_out_flush(audio); - mutex_unlock(&audio->read_lock); -} - -static void audaac_in_flush(struct audio_in *audio) -{ - int i; - - audio->dsp_cnt = 0; - audio->in_head = 0; - audio->in_tail = 0; - audio->in_count = 0; - audio->eos_ack = 0; - for (i = 0; i < FRAME_NUM; i++) { - audio->in[i].size = 0; - audio->in[i].read = 0; - } - MM_DBG("in_bytes %d\n", atomic_read(&audio->in_bytes)); - MM_DBG("in_samples %d\n", atomic_read(&audio->in_samples)); - atomic_set(&audio->in_bytes, 0); - atomic_set(&audio->in_samples, 0); -} - -static void audaac_out_flush(struct audio_in *audio) -{ - int i; - - audio->out_head = 0; - audio->out_tail = 0; - audio->out_count = 0; - for (i = 0; i < OUT_FRAME_NUM; i++) { - audio->out[i].size = 0; - audio->out[i].read = 0; - audio->out[i].used = 0; - } -} - -/* ------------------- device --------------------- */ -static long audaac_in_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct audio_in *audio = file->private_data; - int rc = 0; - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = atomic_read(&audio->in_bytes); - stats.sample_count = atomic_read(&audio->in_samples); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return rc; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: { - uint32_t freq; - /* Poll at 48KHz always */ - freq = 48000; - MM_DBG("AUDIO_START\n"); - rc = msm_snddev_request_freq(&freq, audio->enc_id, - SNDDEV_CAP_TX, AUDDEV_CLNT_ENC); - MM_DBG("sample rate configured %d sample rate requested %d\n", - freq, audio->samp_rate); - if (rc < 0) { - MM_DBG(" Sample rate can not be set, return code %d\n", - rc); - msm_snddev_withdraw_freq(audio->enc_id, - SNDDEV_CAP_TX, AUDDEV_CLNT_ENC); - MM_DBG("msm_snddev_withdraw_freq\n"); - break; - } - /*update aurec session info in audpreproc layer*/ - audio->session_info.session_id = audio->enc_id; - audio->session_info.sampling_freq = audio->samp_rate; - audpreproc_update_audrec_info(&audio->session_info); - rc = audaac_in_enable(audio); - if (!rc) { - rc = - wait_event_interruptible_timeout(audio->wait_enable, - audio->running != 0, 1*HZ); - MM_DBG("state %d rc = %d\n", audio->running, rc); - - if (audio->running == 0) - rc = -ENODEV; - else - rc = 0; - } - audio->stopped = 0; - break; - } - case AUDIO_STOP: { - audio->session_info.sampling_freq = 0; - audpreproc_update_audrec_info(&audio->session_info); - rc = audaac_in_disable(audio); - rc = msm_snddev_withdraw_freq(audio->enc_id, - SNDDEV_CAP_TX, AUDDEV_CLNT_ENC); - MM_DBG("msm_snddev_withdraw_freq\n"); - audio->stopped = 1; - audio->abort = 0; - break; - } - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audaac_ioport_reset(audio); - if (audio->running) { - audaac_flush_command(audio); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - case AUDIO_GET_STREAM_CONFIG: { - struct msm_audio_stream_config cfg; - memset(&cfg, 0, sizeof(cfg)); - cfg.buffer_size = audio->buffer_size; - cfg.buffer_count = FRAME_NUM; - if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - break; - } - case AUDIO_SET_STREAM_CONFIG: { - struct msm_audio_stream_config cfg; - if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - /* Allow only single frame */ - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - if (cfg.buffer_size != (FRAME_SIZE - 8)) { - rc = -EINVAL; - break; - } - } else { - if (cfg.buffer_size != (NT_FRAME_SIZE - 24)) { - rc = -EINVAL; - break; - } - } - audio->buffer_size = cfg.buffer_size; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_pcm_config cfg; - memset(&cfg, 0, sizeof(cfg)); - cfg.buffer_size = OUT_BUFFER_SIZE; - cfg.buffer_count = OUT_FRAME_NUM; - if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - break; - } - case AUDIO_GET_AAC_ENC_CONFIG: { - struct msm_audio_aac_enc_config cfg; - if (audio->channel_mode == AUDREC_CMD_MODE_MONO) - cfg.channels = 1; - else - cfg.channels = 2; - cfg.sample_rate = audio->samp_rate; - cfg.bit_rate = audio->bit_rate; - cfg.stream_format = AUDIO_AAC_FORMAT_RAW; - if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - break; - } - case AUDIO_SET_AAC_ENC_CONFIG: { - struct msm_audio_aac_enc_config cfg; - unsigned int record_quality; - if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - if (cfg.stream_format != AUDIO_AAC_FORMAT_RAW) { - MM_ERR("unsupported AAC format\n"); - rc = -EINVAL; - break; - } - record_quality = bitrate_to_record_quality(cfg.sample_rate, - cfg.channels, cfg.bit_rate); - /* Range of Record Quality Supported by DSP, Q12 format */ - if ((record_quality < 0x800) || (record_quality > 0x4000)) { - MM_ERR("Unsupported bit rate \n"); - rc = -EINVAL; - break; - } - MM_DBG("channels = %d\n", cfg.channels); - if (cfg.channels == 1) { - cfg.channels = AUDREC_CMD_MODE_MONO; - } else if (cfg.channels == 2) { - cfg.channels = AUDREC_CMD_MODE_STEREO; - } else { - rc = -EINVAL; - break; - } - MM_DBG("channels = %d\n", cfg.channels); - audio->samp_rate = cfg.sample_rate; - audio->channel_mode = cfg.channels; - audio->bit_rate = cfg.bit_rate; - audio->record_quality = record_quality; - MM_DBG(" Record Quality = 0x%8x \n", audio->record_quality); - break; - } - case AUDIO_GET_SESSION_ID: { - if (copy_to_user((void *) arg, &audio->enc_id, - sizeof(unsigned short))) { - rc = -EFAULT; - } - break; - } - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -static ssize_t audaac_in_read(struct file *file, - char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_in *audio = file->private_data; - unsigned long flags; - const char __user *start = buf; - void *data; - uint32_t index; - uint32_t size; - int rc = 0; - struct aac_encoded_meta_in meta_field; - struct audio_frame_nt *nt_frame; - MM_DBG(" count = %d\n", count); - mutex_lock(&audio->read_lock); - while (count > 0) { - rc = wait_event_interruptible( - audio->wait, (audio->in_count > 0) || audio->stopped || - audio->abort || audio->rflush); - - if (rc < 0) - break; - - if (audio->rflush) { - rc = -EBUSY; - break; - } - - if (audio->stopped && !audio->in_count) { - MM_DBG("Driver in stop state, No more buffer to read"); - rc = 0;/* End of File */ - break; - } - - if (audio->abort) { - rc = -EPERM; /* Not permitted due to abort */ - break; - } - - index = audio->in_tail; - data = (uint8_t *) audio->in[index].data; - size = audio->in[index].size; - - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) { - nt_frame = (struct audio_frame_nt *)(data - - sizeof(struct audio_frame_nt)); - memcpy((char *)&meta_field.time_stamp_dword_lsw, - (char *)&nt_frame->time_stamp_dword_lsw, 12); - meta_field.metadata_len = - sizeof(struct aac_encoded_meta_in); - if (copy_to_user((char *)start, (char *)&meta_field, - sizeof(struct aac_encoded_meta_in))) { - rc = -EFAULT; - break; - } - if (nt_frame->nflag_lsw & 0x0001) { - MM_ERR("recieved EOS in read call\n"); - audio->eos_ack = 1; - } - buf += sizeof(struct aac_encoded_meta_in); - count -= sizeof(struct aac_encoded_meta_in); - } - if (count >= size) { - if (copy_to_user(buf, data, size)) { - rc = -EFAULT; - break; - } - spin_lock_irqsave(&audio->dsp_lock, flags); - if (index != audio->in_tail) { - /* overrun -- data is - * invalid and we need to retry */ - spin_unlock_irqrestore(&audio->dsp_lock, flags); - continue; - } - audio->in[index].size = 0; - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - audio->in_count--; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - count -= size; - buf += size; - if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) && - (!audio->eos_ack)) { - MM_DBG("sending read ptr command %d %d\n", - audio->dsp_cnt, - audio->in_tail); - audaac_dsp_read_buffer(audio, - audio->dsp_cnt++); - break; - } - } else { - MM_ERR("short read\n"); - break; - } - break; - } - mutex_unlock(&audio->read_lock); - if (buf > start) - return buf - start; - - return rc; -} - -static void audpreproc_pcm_send_data(struct audio_in *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - MM_DBG("\n"); - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - MM_DBG("frame %d busy\n", audio->out_tail); - audpreproc_pcm_buffer_ptr_refresh(audio, - audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } - done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - - -static int audaac_in_fsync(struct file *file, loff_t ppos1, loff_t ppos2, int datasync) - -{ - struct audio_in *audio = file->private_data; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - if (!audio->running || (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - audio->wflush); - MM_DBG("waked on by some event audio->wflush = %d\n", audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; - -} - - int audpreproc_aac_process_eos(struct audio_in *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - struct buffer *frame; - int rc = 0; - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - MM_DBG("copying meta_out frame->used = %d\n", frame->used); - audpreproc_pcm_send_data(audio, 0); -done: - return rc; -} - -static ssize_t audaac_in_write(struct file *file, - const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_in *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - char *cpy_ptr; - int rc = 0, eos_condition = AUDPREPROC_AAC_EOS_NONE; - unsigned short mfield_size = 0; - int write_count = count; - MM_DBG("cnt=%d\n", count); - - if (count & 1) - return -EINVAL; - - mutex_lock(&audio->write_lock); - frame = audio->out + audio->out_head; - cpy_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - goto error; - - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto error; - } - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - goto error; - } else if (mfield_size > count) { - rc = -EINVAL; - goto error; - } - MM_DBG("mf offset_val %x\n", mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - goto error; - } - /* Check if EOS flag is set and buffer has - * contains just meta field - */ - if (cpy_ptr[AUDPREPROC_AAC_EOS_FLG_OFFSET] & - AUDPREPROC_AAC_EOS_FLG_MASK) { - MM_DBG("EOS SET\n"); - eos_condition = AUDPREPROC_AAC_EOS_SET; - if (mfield_size == count) { - buf += mfield_size; - if (audio->mode == - MSM_AUD_ENC_MODE_NONTUNNEL) { - eos_condition = 0; - goto exit; - } - goto error; - } else - cpy_ptr[AUDPREPROC_AAC_EOS_FLG_OFFSET] &= - ~AUDPREPROC_AAC_EOS_FLG_MASK; - } - cpy_ptr += mfield_size; - count -= mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - MM_DBG("copying the stream count = %d\n", count); - if (copy_from_user(cpy_ptr, buf, count)) { - rc = -EFAULT; - goto error; - } -exit: - frame->used = count; - audio->out_head ^= 1; - if (!audio->flush_ack) - audpreproc_pcm_send_data(audio, 0); - else { - audpreproc_pcm_send_data(audio, 1); - audio->flush_ack = 0; - } - if (eos_condition == AUDPREPROC_AAC_EOS_SET) - rc = audpreproc_aac_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - return write_count; -error: - mutex_unlock(&audio->write_lock); - return rc; -} - -static int audaac_in_release(struct inode *inode, struct file *file) -{ - struct audio_in *audio = file->private_data; - - mutex_lock(&audio->lock); - /* with draw frequency for session - incase not stopped the driver */ - msm_snddev_withdraw_freq(audio->enc_id, SNDDEV_CAP_TX, - AUDDEV_CLNT_ENC); - auddev_unregister_evt_listner(AUDDEV_CLNT_ENC, audio->enc_id); - /*reset the sampling frequency information at audpreproc layer*/ - audio->session_info.sampling_freq = 0; - audpreproc_update_audrec_info(&audio->session_info); - audaac_in_disable(audio); - audaac_in_flush(audio); - msm_adsp_put(audio->audrec); - audpreproc_aenc_free(audio->enc_id); - audio->audrec = NULL; - audio->opened = 0; - if (audio->data) { - iounmap(audio->map_v_read); - free_contiguous_memory_by_paddr(audio->phys); - audio->data = NULL; - } - if (audio->out_data) { - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->out_phys); - audio->out_data = NULL; - } - mutex_unlock(&audio->lock); - return 0; -} - -struct audio_in the_audio_aac_in; - -static int audaac_in_open(struct inode *inode, struct file *file) -{ - struct audio_in *audio = &the_audio_aac_in; - int rc; - int encid; - - mutex_lock(&audio->lock); - if (audio->opened) { - rc = -EBUSY; - goto done; - } - audio->phys = allocate_contiguous_ebi_nomap(DMASZ, SZ_4K); - if (audio->phys) { - audio->map_v_read = ioremap(audio->phys, DMASZ); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("could not map DMA buffers\n"); - rc = -ENOMEM; - free_contiguous_memory_by_paddr(audio->phys); - goto done; - } - audio->data = audio->map_v_read; - } else { - MM_ERR("could not allocate DMA buffers\n"); - rc = -ENOMEM; - goto done; - } - MM_DBG("Memory addr = 0x%8x phy addr = 0x%8x\n",\ - (int) audio->data, (int) audio->phys); - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - audio->mode = MSM_AUD_ENC_MODE_NONTUNNEL; - } else if (!(file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - audio->mode = MSM_AUD_ENC_MODE_TUNNEL; - MM_DBG("Opened for tunnel mode encoding\n"); - } else { - rc = -EACCES; - goto done; - } - - /* Settings will be re-config at AUDIO_SET_CONFIG, - * but at least we need to have initial config - */ - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) - audio->buffer_size = (NT_FRAME_SIZE - 24); - else - audio->buffer_size = (FRAME_SIZE - 8); - audio->enc_type = ENC_TYPE_AAC | audio->mode; - audio->samp_rate = 8000; - audio->channel_mode = AUDREC_CMD_MODE_MONO; - /* For AAC, bit rate hard coded, default settings is - * sample rate (8000) x channel count (1) x recording quality (1.75) - * = 14000 bps */ - audio->bit_rate = 14000; - audio->record_quality = 0x1c00; - MM_DBG("enc_type = %x\n", audio->enc_type); - encid = audpreproc_aenc_alloc(audio->enc_type, &audio->module_name, - &audio->queue_ids); - if (encid < 0) { - MM_ERR("No free encoder available\n"); - rc = -ENODEV; - goto done; - } - audio->enc_id = encid; - - rc = msm_adsp_get(audio->module_name, &audio->audrec, - &audrec_aac_adsp_ops, audio); - - if (rc) { - audpreproc_aenc_free(audio->enc_id); - goto done; - } - - audio->stopped = 0; - audio->source = 0; - audio->abort = 0; - audio->wflush = 0; - audio->rflush = 0; - audio->flush_ack = 0; - - audaac_in_flush(audio); - audaac_out_flush(audio); - - audio->out_phys = allocate_contiguous_ebi_nomap(BUFFER_SIZE, SZ_4K); - if (!audio->out_phys) { - MM_ERR("could not allocate write buffers\n"); - rc = -ENOMEM; - goto evt_error; - } else { - audio->map_v_write = ioremap( - audio->out_phys, BUFFER_SIZE); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write phys address\n"); - rc = -ENOMEM; - free_contiguous_memory_by_paddr(audio->out_phys); - goto evt_error; - } - audio->out_data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->out_phys, (int)audio->out_data); - } - audio->build_id = socinfo_get_build_id(); - MM_DBG("Modem build id = %s\n", audio->build_id); - - /* Initialize buffer */ - audio->out[0].data = audio->out_data + 0; - audio->out[0].addr = audio->out_phys + 0; - audio->out[0].size = OUT_BUFFER_SIZE; - - audio->out[1].data = audio->out_data + OUT_BUFFER_SIZE; - audio->out[1].addr = audio->out_phys + OUT_BUFFER_SIZE; - audio->out[1].size = OUT_BUFFER_SIZE; - - MM_DBG("audio->out[0].data = %d audio->out[1].data = %d", - (unsigned int)audio->out[0].data, - (unsigned int)audio->out[1].data); - audio->device_events = AUDDEV_EVT_DEV_RDY | AUDDEV_EVT_DEV_RLS | - AUDDEV_EVT_FREQ_CHG; - - rc = auddev_register_evt_listner(audio->device_events, - AUDDEV_CLNT_ENC, audio->enc_id, - aac_in_listener, (void *) audio); - if (rc) { - MM_ERR("failed to register device event listener\n"); - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->out_phys); - goto evt_error; - } - audio->mfield = META_OUT_SIZE; - file->private_data = audio; - audio->opened = 1; - audio->out_frame_cnt++; - rc = 0; -done: - mutex_unlock(&audio->lock); - return rc; -evt_error: - msm_adsp_put(audio->audrec); - audpreproc_aenc_free(audio->enc_id); - mutex_unlock(&audio->lock); - return rc; -} - -static const struct file_operations audio_in_fops = { - .owner = THIS_MODULE, - .open = audaac_in_open, - .release = audaac_in_release, - .read = audaac_in_read, - .write = audaac_in_write, - .fsync = audaac_in_fsync, - .unlocked_ioctl = audaac_in_ioctl, -}; - -struct miscdevice audio_aac_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_aac_in", - .fops = &audio_in_fops, -}; - -static int __init audaac_in_init(void) -{ - mutex_init(&the_audio_aac_in.lock); - mutex_init(&the_audio_aac_in.read_lock); - spin_lock_init(&the_audio_aac_in.dsp_lock); - spin_lock_init(&the_audio_aac_in.dev_lock); - init_waitqueue_head(&the_audio_aac_in.wait); - init_waitqueue_head(&the_audio_aac_in.wait_enable); - mutex_init(&the_audio_aac_in.write_lock); - init_waitqueue_head(&the_audio_aac_in.write_wait); - - return misc_register(&audio_aac_in_misc); -} - -device_initcall(audaac_in_init); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_acdb.c b/arch/arm/mach-msm/qdsp5v2/audio_acdb.c deleted file mode 100644 index 5d7cfd79ae73dc6f7da732b7648d6a089d297dfb..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_acdb.c +++ /dev/null @@ -1,3448 +0,0 @@ -/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* this is the ACDB device ID */ -#define DALDEVICEID_ACDB 0x02000069 -#define ACDB_PORT_NAME "DAL00" -#define ACDB_CPU SMD_APPS_MODEM -#define ACDB_BUF_SIZE 4096 -#define PBE_BUF_SIZE (33*1024) -#define FLUENCE_BUF_SIZE 498 - -#define ACDB_VALUES_NOT_FILLED 0 -#define ACDB_VALUES_FILLED 1 -#define MAX_RETRY 10 - -/*below macro is used to align the session info received from -Devctl driver with the state mentioned as not to alter the -Existing code*/ -#define AUDREC_OFFSET 2 -/* rpc table index */ -enum { - ACDB_DalACDB_ioctl = DALDEVICE_FIRST_DEVICE_API_IDX -}; - -enum { - CAL_DATA_READY = 0x1, - AUDPP_READY = 0x2, - AUDREC0_READY = 0x4, - AUDREC1_READY = 0x8, - AUDREC2_READY = 0x10, -}; - - -struct acdb_data { - void *handle; - - u32 phys_addr; - u8 *virt_addr; - - struct task_struct *cb_thread_task; - struct auddev_evt_audcal_info *device_info; - - u32 acdb_state; - struct audpp_event_callback audpp_cb; - struct audpreproc_event_callback audpreproc_cb; - - struct audpp_cmd_cfg_object_params_pcm *pp_iir; - struct audpp_cmd_cfg_cal_gain *calib_gain_rx; - struct audpp_cmd_cfg_pbe *pbe_block; - struct audpp_cmd_cfg_object_params_mbadrc *pp_mbadrc; - struct audpreproc_cmd_cfg_agc_params *preproc_agc; - struct audpreproc_cmd_cfg_iir_tuning_filter_params *preproc_iir; - struct audpreproc_cmd_cfg_cal_gain *calib_gain_tx; - struct acdb_mbadrc_block mbadrc_block; - struct audpreproc_cmd_cfg_lvnv_param preproc_lvnv; - - wait_queue_head_t wait; - struct mutex acdb_mutex; - u32 device_cb_compl; - u32 audpp_cb_compl; - u32 preproc_cb_compl; - u8 preproc_stream_id; - u8 audrec_applied; - u32 multiple_sessions; - u32 cur_tx_session; - struct acdb_result acdb_result; - u16 *pbe_extbuff; - u16 *pbe_enable_flag; - u32 fluence_extbuff; - u8 *fluence_extbuff_virt; - void *map_v_fluence; - - struct acdb_pbe_block *pbe_blk; - - spinlock_t dsp_lock; - int dec_id; - struct audpp_cmd_cfg_object_params_eqalizer eq; - /*status to enable or disable the fluence*/ - int fleuce_feature_status[MAX_AUDREC_SESSIONS]; - struct audrec_session_info session_info; - /*pmem info*/ - int pmem_fd; - unsigned long paddr; - unsigned long kvaddr; - unsigned long pmem_len; - struct file *file; - /* pmem for get acdb blk */ - unsigned long get_blk_paddr; - u8 *get_blk_kvaddr; - void *map_v_get_blk; - char *build_id; -}; - -static struct acdb_data acdb_data; - -struct acdb_cache_node { - u32 node_status; - s32 stream_id; - u32 phys_addr_acdb_values; - void *map_v_addr; - u8 *virt_addr_acdb_values; - struct auddev_evt_audcal_info device_info; -}; - -/*for RX devices acdb values are applied based on copp ID so -the depth of tx cache is MAX number of COPP supported in the system*/ -struct acdb_cache_node acdb_cache_rx[MAX_COPP_NODE_SUPPORTED]; - -/*for TX devices acdb values are applied based on AUDREC session and -the depth of the tx cache is define by number of AUDREC sessions supported*/ -struct acdb_cache_node acdb_cache_tx[MAX_AUDREC_SESSIONS]; - -/*Audrec session info includes Attributes Sampling frequency and enc_id */ -struct audrec_session_info session_info[MAX_AUDREC_SESSIONS]; -#ifdef CONFIG_DEBUG_FS - -#define RTC_MAX_TIMEOUT 500 /* 500 ms */ -#define PMEM_RTC_ACDB_QUERY_MEM 4096 -#define EXTRACT_HIGH_WORD(x) ((x & 0xFFFF0000)>>16) -#define EXTRACT_LOW_WORD(x) (0x0000FFFF & x) -#define ACDB_RTC_TX 0xF1 -#define ACDB_RTC_RX 0x1F - - -static u32 acdb_audpp_entry[][4] = { - - { ABID_AUDIO_RTC_VOLUME_PAN_RX,\ - IID_AUDIO_RTC_VOLUME_PAN_PARAMETERS,\ - AUDPP_CMD_VOLUME_PAN,\ - ACDB_RTC_RX - }, - { ABID_AUDIO_IIR_RX,\ - IID_AUDIO_IIR_COEFF,\ - AUDPP_CMD_IIR_TUNING_FILTER, - ACDB_RTC_RX - }, - { ABID_AUDIO_RTC_EQUALIZER_PARAMETERS,\ - IID_AUDIO_RTC_EQUALIZER_PARAMETERS,\ - AUDPP_CMD_EQUALIZER,\ - ACDB_RTC_RX - }, - { ABID_AUDIO_RTC_SPA,\ - IID_AUDIO_RTC_SPA_PARAMETERS,\ - AUDPP_CMD_SPECTROGRAM, - ACDB_RTC_RX - }, - { ABID_AUDIO_STF_RX,\ - IID_AUDIO_IIR_COEFF,\ - AUDPP_CMD_SIDECHAIN_TUNING_FILTER,\ - ACDB_RTC_RX - }, - { - ABID_AUDIO_MBADRC_RX,\ - IID_AUDIO_RTC_MBADRC_PARAMETERS,\ - AUDPP_CMD_MBADRC,\ - ACDB_RTC_RX - }, - { - ABID_AUDIO_AGC_TX,\ - IID_AUDIO_AGC_PARAMETERS,\ - AUDPREPROC_CMD_CFG_AGC_PARAMS,\ - ACDB_RTC_TX - }, - { - ABID_AUDIO_AGC_TX,\ - IID_AUDIO_RTC_AGC_PARAMETERS,\ - AUDPREPROC_CMD_CFG_AGC_PARAMS,\ - ACDB_RTC_TX - }, - { - ABID_AUDIO_NS_TX,\ - IID_NS_PARAMETERS,\ - AUDPREPROC_CMD_CFG_NS_PARAMS,\ - ACDB_RTC_TX - }, - { - ABID_AUDIO_IIR_TX,\ - IID_AUDIO_RTC_TX_IIR_COEFF,\ - AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS,\ - ACDB_RTC_TX - }, - { - ABID_AUDIO_IIR_TX,\ - IID_AUDIO_IIR_COEFF,\ - AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS,\ - ACDB_RTC_TX - } - /*Any new entries should be added here*/ -}; - -static struct dentry *get_set_abid_dentry; -static struct dentry *get_set_abid_data_dentry; - -struct rtc_acdb_pmem { - u8 *viraddr; - int32_t phys; - void *map_v_rtc; -}; - -struct rtc_acdb_data { - u32 acdb_id; - u32 cmd_id; - u32 set_abid; - u32 set_iid; - u32 abid; - u32 err; - bool valid_abid; - u32 tx_rx_ctl; - struct rtc_acdb_pmem rtc_read; - struct rtc_acdb_pmem rtc_write; - wait_queue_head_t wait; -}; - -struct get_abid { - u32 cmd_id; - u32 acdb_id; - u32 set_abid; - u32 set_iid; -}; - -struct acdb_block_mbadrc_rtc { - u16 enable; - u16 num_bands; - u16 down_samp_level; - u16 adrc_delay; - u16 ext_buf_size; - u16 ext_partition; - u16 ext_buf_msw; - u16 ext_buf_lsw; - struct adrc_config adrc_band[AUDPP_MAX_MBADRC_BANDS]; - signed int ExtBuff[196]; -} __attribute__((packed)); - -enum { - ACDB_RTC_SUCCESS, - ACDB_RTC_ERR_INVALID_DEVICE, - ACDB_RTC_ERR_DEVICE_INACTIVE, - ACDB_RTC_ERR_INVALID_ABID, - ACDB_RTC_DSP_FAILURE, - ACDB_RTC_DSP_FEATURE_NOT_AVAILABLE, - ACDB_RTC_ERR_INVALID_LEN, - ACDB_RTC_ERR_UNKNOWN_FAILURE, - ACDB_RTC_PENDING_RESPONSE, - ACDB_RTC_INIT_FAILURE, -}; - -static struct rtc_acdb_data rtc_acdb; - -static int rtc_getsetabid_dbg_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - MM_INFO("GET-SET ABID Open debug intf %s\n", - (char *) file->private_data); - return 0; -} - -static bool get_feature_id(u32 set_abid, u32 iid, unsigned short *feature_id) -{ - bool ret_value = false; - int i = 0; - - for (; i < (sizeof(acdb_audpp_entry) / sizeof(acdb_audpp_entry[0]));\ - i++) { - if (acdb_audpp_entry[i][0] == set_abid && - acdb_audpp_entry[i][1] == iid) { - *feature_id = acdb_audpp_entry[i][2]; - rtc_acdb.tx_rx_ctl = acdb_audpp_entry[i][3]; - ret_value = true; - break; - } - } - return ret_value; -} -static ssize_t rtc_getsetabid_dbg_write(struct file *filp, - const char __user *ubuf, - size_t cnt, loff_t *ppos) -{ - struct get_abid write_abid; - unsigned short feat_id = 0; - rtc_acdb.valid_abid = false; - - if (copy_from_user(&write_abid, \ - (void *)ubuf, sizeof(struct get_abid))) { - MM_ERR("ACDB DATA WRITE - INVALID READ LEN\n"); - rtc_acdb.err = ACDB_RTC_ERR_INVALID_LEN; - return cnt; - } - MM_INFO("SET ABID : Cmd ID: %d Device:%d ABID:%d IID : %d cnt: %d\n",\ - write_abid.cmd_id, write_abid.acdb_id, - write_abid.set_abid, write_abid.set_iid, cnt); - if (write_abid.acdb_id > ACDB_ID_MAX || - write_abid.acdb_id < ACDB_ID_HANDSET_SPKR){ - rtc_acdb.err = ACDB_RTC_ERR_INVALID_DEVICE; - return cnt; - } - if (!is_dev_opened(write_abid.acdb_id)) { - rtc_acdb.err = ACDB_RTC_ERR_DEVICE_INACTIVE; - return cnt; - } - rtc_acdb.err = ACDB_RTC_ERR_INVALID_ABID; - rtc_acdb.abid = write_abid.set_abid; - if (get_feature_id(write_abid.set_abid, \ - write_abid.set_iid, &feat_id)) { - rtc_acdb.err = ACDB_RTC_SUCCESS; - rtc_acdb.cmd_id = write_abid.cmd_id; - rtc_acdb.acdb_id = write_abid.acdb_id; - rtc_acdb.set_abid = feat_id; - rtc_acdb.valid_abid = true; - rtc_acdb.set_iid = write_abid.set_iid; - } - return cnt; -} -static ssize_t rtc_getsetabid_dbg_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - static char buffer[1024]; - int n = 0; - u32 msg = rtc_acdb.err; - memcpy(buffer, &rtc_acdb.cmd_id, sizeof(struct get_abid)); - memcpy(buffer+16, &msg, 4); - n = 20; - MM_INFO("SET ABID : Cmd ID: %x Device:%x ABID:%x IID : %x Err: %d\n",\ - rtc_acdb.cmd_id, rtc_acdb.acdb_id, rtc_acdb.set_abid,\ - rtc_acdb.set_iid, rtc_acdb.err); - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static int rtc_getsetabid_data_dbg_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - MM_INFO("GET-SET ABID DATA Open debug intf %s\n", - (char *) file->private_data); - return 0; -} - -void acdb_rtc_set_err(u32 ErrCode) -{ - if (rtc_acdb.err == ACDB_RTC_PENDING_RESPONSE) { - if (ErrCode == 0xFFFF) { - rtc_acdb.err = ACDB_RTC_SUCCESS; - MM_INFO("RTC READ SUCCESS---\n"); - } else if (ErrCode == 0) { - rtc_acdb.err = ACDB_RTC_DSP_FAILURE; - MM_INFO("RTC READ FAIL---\n"); - } else if (ErrCode == 1) { - rtc_acdb.err = ACDB_RTC_DSP_FEATURE_NOT_AVAILABLE; - MM_INFO("RTC READ FEAT UNAVAILABLE---\n"); - } else { - rtc_acdb.err = ACDB_RTC_DSP_FAILURE; - MM_ERR("RTC Err CODE---\n"); - } - } else { - rtc_acdb.err = ACDB_RTC_DSP_FAILURE; - MM_ERR("RTC Err code Invalid State\n"); - } - wake_up(&rtc_acdb.wait); -} -static ssize_t rtc_getsetabid_data_dbg_read(struct file *file, - char __user *buf, size_t count, - loff_t *ppos) -{ - static char buffer[PMEM_RTC_ACDB_QUERY_MEM]; - int rc, n = 0; - int counter = 0; - struct rtc_acdb_pmem *rtc_read = &rtc_acdb.rtc_read; - memset(&buffer, 0, PMEM_RTC_ACDB_QUERY_MEM); - - if (rtc_acdb.valid_abid != true) { - MM_ERR("ACDB DATA READ ---INVALID ABID\n"); - n = 0; - rtc_acdb.err = ACDB_RTC_ERR_INVALID_ABID; - } else { - if (PMEM_RTC_ACDB_QUERY_MEM < count) { - MM_ERR("ACDB DATA READ ---\ - INVALID READ LEN %x\n", count); - n = 0; - rtc_acdb.err = ACDB_RTC_ERR_INVALID_LEN; - } else { - rtc_acdb.err = ACDB_RTC_PENDING_RESPONSE; - if (rtc_read->viraddr != NULL) { - memset(rtc_read->viraddr, - 0, PMEM_RTC_ACDB_QUERY_MEM); - } - if (rtc_acdb.tx_rx_ctl == ACDB_RTC_RX) { - struct rtc_audpp_read_data rtc_read_cmd; - rtc_read_cmd.cmd_id = - AUDPP_CMD_PP_FEAT_QUERY_PARAMS; - rtc_read_cmd.obj_id = - AUDPP_CMD_COPP_STREAM; - rtc_read_cmd.route_id = - acdb_data.device_info->dev_id; - rtc_read_cmd.feature_id = rtc_acdb.set_abid; - rtc_read_cmd.extbufsizemsw = - EXTRACT_HIGH_WORD(\ - PMEM_RTC_ACDB_QUERY_MEM); - rtc_read_cmd.extbufsizelsw = - EXTRACT_LOW_WORD(\ - PMEM_RTC_ACDB_QUERY_MEM); - rtc_read_cmd.extpart = 0x0000; - rtc_read_cmd.extbufstartmsw = - EXTRACT_HIGH_WORD(rtc_read->phys); - rtc_read_cmd.extbufstartlsw = - EXTRACT_LOW_WORD(rtc_read->phys); - rc = audpp_send_queue2(&rtc_read_cmd, - sizeof(rtc_read_cmd)); - MM_INFO("ACDB READ Command RC --->%x\ - Route ID=%x\n", rc,\ - acdb_data.device_info->dev_id); - } else if (rtc_acdb.tx_rx_ctl == ACDB_RTC_TX) { - struct rtc_audpreproc_read_data rtc_audpreproc; - rtc_audpreproc.cmd_id = - AUDPREPROC_CMD_FEAT_QUERY_PARAMS; - rtc_audpreproc.stream_id = - acdb_data.preproc_stream_id; - rtc_audpreproc.feature_id = rtc_acdb.set_abid; - rtc_audpreproc.extbufsizemsw = - EXTRACT_HIGH_WORD(\ - PMEM_RTC_ACDB_QUERY_MEM); - rtc_audpreproc.extbufsizelsw = - EXTRACT_LOW_WORD(\ - PMEM_RTC_ACDB_QUERY_MEM); - rtc_audpreproc.extpart = 0x0000; - rtc_audpreproc.extbufstartmsw = - EXTRACT_HIGH_WORD(rtc_read->phys); - rtc_audpreproc.extbufstartlsw = - EXTRACT_LOW_WORD(rtc_read->phys); - rc = audpreproc_send_preproccmdqueue( - &rtc_audpreproc,\ - sizeof(rtc_audpreproc)); - MM_INFO("ACDB READ Command RC --->%x,\ - stream_id %x\n", rc,\ - acdb_data.preproc_stream_id); - } - rc = wait_event_timeout(rtc_acdb.wait, - (rtc_acdb.err != - ACDB_RTC_PENDING_RESPONSE), - msecs_to_jiffies(RTC_MAX_TIMEOUT)); - MM_INFO("ACDB READ ACK Count = %x Err = %x\n", - count, rtc_acdb.err); - { - if (rtc_acdb.err == ACDB_RTC_SUCCESS - && rtc_read->viraddr != NULL) { - memcpy(buffer, rtc_read->viraddr, count); - n = count; - while (counter < count) { - MM_DBG("%x", \ - rtc_read->viraddr[counter]); - counter++; - } - } - } - } - } - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static bool acdb_set_tx_rtc(const char *ubuf, size_t writecount) -{ - struct audpreproc_cmd_cfg_iir_tuning_filter_params *preproc_iir; - struct audpreproc_cmd_cfg_agc_params *preproc_agc; - struct audpreproc_cmd_cfg_ns_params *preproc_ns; - s32 result = 0; - bool retval = false; - unsigned short iircmdsize = - sizeof(struct audpreproc_cmd_cfg_iir_tuning_filter_params); - unsigned short iircmdid = AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS; - - rtc_acdb.err = ACDB_RTC_ERR_UNKNOWN_FAILURE; - - switch (rtc_acdb.set_abid) { - - case AUDPREPROC_CMD_CFG_AGC_PARAMS: - case AUDPREPROC_CMD_CFG_AGC_PARAMS_2: - { - preproc_agc = kmalloc(sizeof(\ - struct audpreproc_cmd_cfg_agc_params),\ - GFP_KERNEL); - if ((sizeof(struct audpreproc_cmd_cfg_agc_params) -\ - (2*sizeof(unsigned short))) - < writecount) { - MM_ERR("ACDB DATA WRITE --\ - AGC TX writecount > DSP struct\n"); - } else { - if (preproc_agc != NULL) { - char *base; unsigned short offset; - unsigned short *offset_addr; - base = (char *)preproc_agc; - offset = offsetof(struct \ - audpreproc_cmd_cfg_agc_params,\ - tx_agc_param_mask); - offset_addr = (unsigned short *)(base + offset); - if ((copy_from_user(offset_addr,\ - (void *)ubuf, writecount)) == 0x00) { - preproc_agc->cmd_id = - AUDPREPROC_CMD_CFG_AGC_PARAMS; - preproc_agc->stream_id = - acdb_data.preproc_stream_id; - result = audpreproc_dsp_set_agc( - preproc_agc, - sizeof(struct \ - audpreproc_cmd_cfg_agc_params)); - if (result) { - MM_ERR("ACDB=> Failed to \ - send AGC data to \ - preproc)\n"); - } else { - retval = true; - } - } else { - MM_ERR("ACDB DATA WRITE ---\ - GC Tx copy_from_user Fail\n"); - } - } else { - MM_ERR("ACDB DATA WRITE --\ - AGC TX kalloc Failed LEN\n"); - } - } - if (preproc_agc != NULL) - kfree(preproc_agc); - break; - } - case AUDPREPROC_CMD_CFG_NS_PARAMS: - { - - preproc_ns = kmalloc(sizeof(struct \ - audpreproc_cmd_cfg_ns_params),\ - GFP_KERNEL); - if ((sizeof(struct audpreproc_cmd_cfg_ns_params) -\ - (2 * sizeof(unsigned short))) - < writecount) { - MM_ERR("ACDB DATA WRITE --\ - NS TX writecount > DSP struct\n"); - } else { - if (preproc_ns != NULL) { - char *base; unsigned short offset; - unsigned short *offset_addr; - base = (char *)preproc_ns; - offset = offsetof(struct \ - audpreproc_cmd_cfg_ns_params,\ - ec_mode_new); - offset_addr = (unsigned short *)(base + offset); - if ((copy_from_user(offset_addr,\ - (void *)ubuf, writecount)) == 0x00) { - preproc_ns->cmd_id = - AUDPREPROC_CMD_CFG_NS_PARAMS; - preproc_ns->stream_id = - acdb_data.preproc_stream_id; - result = audpreproc_dsp_set_ns( - preproc_ns, - sizeof(struct \ - audpreproc_cmd_cfg_ns_params)); - if (result) { - MM_ERR("ACDB=> Failed to send \ - NS data to preproc\n"); - } else { - retval = true; - } - } else { - MM_ERR("ACDB DATA WRITE ---NS Tx \ - copy_from_user Fail\n"); - } - } else { - MM_ERR("ACDB DATA WRITE --NS TX\ - kalloc Failed LEN\n"); - } - } - if (preproc_ns != NULL) - kfree(preproc_ns); - break; - } - case AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS: - { - - preproc_iir = kmalloc(sizeof(struct \ - audpreproc_cmd_cfg_iir_tuning_filter_params),\ - GFP_KERNEL); - if ((sizeof(struct \ - audpreproc_cmd_cfg_iir_tuning_filter_params)-\ - (2 * sizeof(unsigned short))) - < writecount) { - MM_ERR("ACDB DATA WRITE --IIR TX writecount\ - > DSP struct\n"); - } else { - if (preproc_iir != NULL) { - char *base; unsigned short offset; - unsigned short *offset_addr; - base = (char *)preproc_iir; - offset = offsetof(struct \ - audpreproc_cmd_cfg_iir_tuning_filter_params,\ - active_flag); - offset_addr = (unsigned short *)(base + \ - offset); - if ((copy_from_user(offset_addr,\ - (void *)ubuf, writecount)) == 0x00) { - preproc_iir->cmd_id = iircmdid; - preproc_iir->stream_id = - acdb_data.preproc_stream_id; - result = audpreproc_dsp_set_iir(\ - preproc_iir, - iircmdsize); - if (result) { - MM_ERR("ACDB=> Failed to send\ - IIR data to preproc\n"); - } else { - retval = true; - } - } else { - MM_ERR("ACDB DATA WRITE ---IIR Tx \ - copy_from_user Fail\n"); - } - } else { - MM_ERR("ACDB DATA WRITE --IIR TX kalloc \ - Failed LEN\n"); - } - } - if (preproc_iir != NULL) - kfree(preproc_iir); - break; - } - } - return retval; -} - -static bool acdb_set_rx_rtc(const char *ubuf, size_t writecount) -{ - - struct audpp_cmd_cfg_object_params_volpan *volpan_config; - struct audpp_cmd_cfg_object_params_mbadrc *mbadrc_config; - struct acdb_block_mbadrc_rtc *acdb_mbadrc_rtc; - struct audpp_cmd_cfg_object_params_sidechain *stf_config; - struct audpp_cmd_cfg_object_params_spectram *spa_config; - struct audpp_cmd_cfg_object_params_eqalizer *eq_config; - struct audpp_cmd_cfg_object_params_pcm *iir_config; - unsigned short temp_spa[34]; - struct rtc_acdb_pmem *rtc_write = &rtc_acdb.rtc_write; - s32 result = 0; - bool retval = false; - - switch (rtc_acdb.set_abid) { - case AUDPP_CMD_VOLUME_PAN: - { - volpan_config = kmalloc(sizeof(struct \ - audpp_cmd_cfg_object_params_volpan),\ - GFP_KERNEL); - if ((sizeof(struct audpp_cmd_cfg_object_params_volpan) -\ - sizeof(struct audpp_cmd_cfg_object_params_common)) - < writecount) { - MM_ERR("ACDB DATA WRITE --\ - VolPan writecount > DSP struct\n"); - } else { - if (volpan_config != NULL) { - char *base; unsigned short offset; - unsigned short *offset_addr; - base = (char *)volpan_config; - offset = offsetof(struct \ - audpp_cmd_cfg_object_params_volpan,\ - volume); - offset_addr = (unsigned short *)(base+offset); - if ((copy_from_user(offset_addr,\ - (void *)ubuf, writecount)) == 0x00) { - MM_ERR("ACDB RX WRITE DATA:\ - AUDPP_CMD_VOLUME_PAN\n"); - result = audpp_set_volume_and_pan( - acdb_data.device_info->dev_id,\ - volpan_config->volume, - volpan_config->pan, - COPP); - if (result) { - MM_ERR("ACDB=> Failed to \ - send VOLPAN data to" - " postproc\n"); - } else { - retval = true; - } - } else { - MM_ERR("ACDB DATA WRITE ---\ - copy_from_user Fail\n"); - } - } else { - MM_ERR("ACDB DATA WRITE --\ - Vol Pan kalloc Failed LEN\n"); - } - } - if (volpan_config != NULL) - kfree(volpan_config); - break; - } - - case AUDPP_CMD_IIR_TUNING_FILTER: - { - iir_config = kmalloc(sizeof(struct \ - audpp_cmd_cfg_object_params_pcm),\ - GFP_KERNEL); - if ((sizeof(struct audpp_cmd_cfg_object_params_pcm) -\ - sizeof(struct audpp_cmd_cfg_object_params_common)) - < writecount) { - MM_ERR("ACDB DATA WRITE --\ - IIR RX writecount > DSP struct\n"); - } else { - if (iir_config != NULL) { - char *base; unsigned short offset; - unsigned short *offset_addr; - base = (char *)iir_config; - offset = offsetof(struct \ - audpp_cmd_cfg_object_params_pcm,\ - active_flag); - offset_addr = (unsigned short *)(base+offset); - if ((copy_from_user(offset_addr,\ - (void *)ubuf, writecount)) == 0x00) { - - iir_config->common.cmd_id = - AUDPP_CMD_CFG_OBJECT_PARAMS; - iir_config->common.stream = - AUDPP_CMD_COPP_STREAM; - iir_config->common.stream_id = 0; - iir_config->common.obj_cfg = - AUDPP_CMD_OBJ0_UPDATE; - iir_config->common.command_type = 0; - MM_ERR("ACDB RX WRITE DATA:\ - AUDPP_CMD_IIR_TUNING_FILTER\n"); - result = audpp_dsp_set_rx_iir( - acdb_data.device_info->dev_id, - iir_config->active_flag,\ - iir_config, COPP); - if (result) { - MM_ERR("ACDB=> Failed to send\ - IIR data to\ - postproc\n"); - } else { - retval = true; - } - } else { - MM_ERR("ACDB DATA WRITE ---\ - IIR Rx copy_from_user Fail\n"); - } - } else { - MM_ERR("ACDB DATA WRITE --\ - acdb_iir_block kalloc Failed LEN\n"); - } - } - if (iir_config != NULL) - kfree(iir_config); - break; - } - case AUDPP_CMD_EQUALIZER: - { - eq_config = kmalloc(sizeof(struct \ - audpp_cmd_cfg_object_params_eqalizer),\ - GFP_KERNEL); - if ((sizeof(struct audpp_cmd_cfg_object_params_eqalizer) -\ - sizeof(struct audpp_cmd_cfg_object_params_common)) - < writecount) { - MM_ERR("ACDB DATA WRITE --\ - EQ RX writecount > DSP struct\n"); - } else { - if (eq_config != NULL) { - char *base; unsigned short offset; - unsigned short *offset_addr; - base = (char *)eq_config; - offset = offsetof(struct \ - audpp_cmd_cfg_object_params_eqalizer,\ - eq_flag); - offset_addr = (unsigned short *)(base+offset); - if ((copy_from_user(offset_addr,\ - (void *)ubuf, writecount)) == 0x00) { - eq_config->common.cmd_id = - AUDPP_CMD_CFG_OBJECT_PARAMS; - eq_config->common.stream = - AUDPP_CMD_COPP_STREAM; - eq_config->common.stream_id = 0; - eq_config->common.obj_cfg = - AUDPP_CMD_OBJ0_UPDATE; - eq_config->common.command_type = 0; - MM_ERR("ACDB RX WRITE\ - DATA:AUDPP_CMD_EQUALIZER\n"); - result = audpp_dsp_set_eq( - acdb_data.device_info->dev_id, - eq_config->eq_flag,\ - eq_config, - COPP); - if (result) { - MM_ERR("ACDB=> Failed to \ - send EQ data to postproc\n"); - } else { - retval = true; - } - } else { - MM_ERR("ACDB DATA WRITE ---\ - EQ Rx copy_from_user Fail\n"); - } - } else { - MM_ERR("ACDB DATA WRITE --\ - EQ kalloc Failed LEN\n"); - } - } - if (eq_config != NULL) - kfree(eq_config); - break; - } - - case AUDPP_CMD_SPECTROGRAM: - { - spa_config = kmalloc(sizeof(struct \ - audpp_cmd_cfg_object_params_spectram),\ - GFP_KERNEL); - if ((sizeof(struct audpp_cmd_cfg_object_params_spectram)-\ - sizeof(struct \ - audpp_cmd_cfg_object_params_common)) - < (2 * sizeof(unsigned short))) { - MM_ERR("ACDB DATA WRITE --SPA \ - RX writecount > DSP struct\n"); - } else { - if (spa_config != NULL) { - if ((copy_from_user(&temp_spa[0],\ - (void *)ubuf, - (34 * sizeof(unsigned short)))) - == 0x00) { - spa_config->common.cmd_id = - AUDPP_CMD_CFG_OBJECT_PARAMS; - spa_config->common.stream = - AUDPP_CMD_COPP_STREAM; - spa_config->common.stream_id = 0; - spa_config->common.obj_cfg = - AUDPP_CMD_OBJ0_UPDATE; - spa_config->common.command_type = 0; - spa_config->sample_interval = - temp_spa[0]; - spa_config->num_coeff = temp_spa[1]; - MM_ERR("ACDB RX WRITE DATA:\ - AUDPP_CMD_SPECTROGRAM\n"); - result = audpp_dsp_set_spa( - acdb_data.device_info->dev_id,\ - spa_config, COPP); - if (result) { - MM_ERR("ACDB=> Failed to \ - send SPA data \ - to postproc\n"); - } else { - retval = true; - } - } else { - MM_ERR("ACDB DATA WRITE \ - ---SPA Rx copy_from_user\ - Fail\n"); - } - } else { - MM_ERR("ACDB DATA WRITE --\ - SPA kalloc Failed LEN\n"); - } - } - if (spa_config != NULL) - kfree(spa_config); - break; - } - case AUDPP_CMD_MBADRC: - { - acdb_mbadrc_rtc = kmalloc(sizeof(struct \ - acdb_block_mbadrc_rtc),\ - GFP_KERNEL); - mbadrc_config = kmalloc(sizeof(struct \ - audpp_cmd_cfg_object_params_mbadrc),\ - GFP_KERNEL); - if (mbadrc_config != NULL && acdb_mbadrc_rtc != NULL) { - if ((copy_from_user(acdb_mbadrc_rtc,\ - (void *)ubuf, - sizeof(struct acdb_block_mbadrc_rtc))) - == 0x00) { - mbadrc_config->common.cmd_id = - AUDPP_CMD_CFG_OBJECT_PARAMS; - mbadrc_config->common.stream = - AUDPP_CMD_COPP_STREAM; - mbadrc_config->common.stream_id = 0; - mbadrc_config->common.obj_cfg = - AUDPP_CMD_OBJ0_UPDATE; - mbadrc_config->common.command_type = 0; - mbadrc_config->enable = - acdb_mbadrc_rtc->enable; - mbadrc_config->num_bands = - acdb_mbadrc_rtc->num_bands; - mbadrc_config->down_samp_level = - acdb_mbadrc_rtc->down_samp_level; - mbadrc_config->adrc_delay = - acdb_mbadrc_rtc->adrc_delay; - memcpy(mbadrc_config->adrc_band,\ - acdb_mbadrc_rtc->adrc_band,\ - AUDPP_MAX_MBADRC_BANDS *\ - sizeof(struct adrc_config)); - if (mbadrc_config->num_bands > 1) { - mbadrc_config->ext_buf_size = - (97 * 2) + (33 * 2 * \ - (mbadrc_config->num_bands - 2)); - } - mbadrc_config->ext_partition = 0; - mbadrc_config->ext_buf_lsw = - (u16) EXTRACT_LOW_WORD(\ - rtc_write->phys); - mbadrc_config->ext_buf_msw = - (u16) EXTRACT_HIGH_WORD(\ - rtc_write->phys); - memcpy(rtc_write->viraddr, - acdb_mbadrc_rtc->ExtBuff, - (196*sizeof(signed int))); - result = audpp_dsp_set_mbadrc( - acdb_data.device_info->dev_id, - mbadrc_config->enable, - mbadrc_config, COPP); - if (result) { - MM_ERR("ACDB=> Failed to \ - Send MBADRC data \ - to postproc\n"); - } else { - retval = true; - } - } else { - MM_ERR("ACDB DATA WRITE ---\ - MBADRC Rx copy_from_user Fail\n"); - } - } else { - MM_ERR("ACDB DATA WRITE --MBADRC kalloc Failed LEN\n"); - } - if (mbadrc_config != NULL) - kfree(mbadrc_config); - if (acdb_mbadrc_rtc != NULL) - kfree(acdb_mbadrc_rtc); - break; - } - case AUDPP_CMD_SIDECHAIN_TUNING_FILTER: - { - stf_config = kmalloc(sizeof(struct \ - audpp_cmd_cfg_object_params_sidechain),\ - GFP_KERNEL); - if ((sizeof(struct audpp_cmd_cfg_object_params_sidechain) -\ - sizeof(struct audpp_cmd_cfg_object_params_common)) - < writecount) { - MM_ERR("ACDB DATA WRITE --\ - STF RX writecount > DSP struct\n"); - } else { - if (stf_config != NULL) { - char *base; unsigned short offset; - unsigned short *offset_addr; - base = (char *)stf_config; - offset = offsetof(struct \ - audpp_cmd_cfg_object_params_sidechain,\ - active_flag); - offset_addr = (unsigned short *)(base+offset); - if ((copy_from_user(offset_addr,\ - (void *)ubuf, writecount)) == 0x00) { - stf_config->common.cmd_id = - AUDPP_CMD_CFG_OBJECT_PARAMS; - stf_config->common.stream = - AUDPP_CMD_COPP_STREAM; - stf_config->common.stream_id = 0; - stf_config->common.obj_cfg = - AUDPP_CMD_OBJ0_UPDATE; - stf_config->common.command_type = 0; - MM_ERR("ACDB RX WRITE DATA:\ - AUDPP_CMD_SIDECHAIN_TUNING_FILTER\n"); - result = audpp_dsp_set_stf( - acdb_data.device_info->dev_id,\ - stf_config->active_flag,\ - stf_config, COPP); - if (result) { - MM_ERR("ACDB=> Failed to send \ - STF data to postproc\n"); - } else { - retval = true; - } - } else { - MM_ERR("ACDB DATA WRITE ---\ - STF Rx copy_from_user Fail\n"); - } - } else { - MM_ERR("ACDB DATA WRITE \ - STF kalloc Failed LEN\n"); - } - } - if (stf_config != NULL) - kfree(stf_config); - break; - } - } - return retval; -} -static ssize_t rtc_getsetabid_data_dbg_write(struct file *filp, - const char __user *ubuf, - size_t cnt, loff_t *ppos) -{ - if (rtc_acdb.valid_abid != true) { - MM_INFO("ACDB DATA READ ---INVALID ABID\n"); - rtc_acdb.err = ACDB_RTC_ERR_INVALID_ABID; - } else { - if (rtc_acdb.tx_rx_ctl == ACDB_RTC_RX) { - if (acdb_set_rx_rtc(ubuf, cnt)) { - rtc_acdb.err = ACDB_RTC_SUCCESS; - } else { - rtc_acdb.err = ACDB_RTC_ERR_UNKNOWN_FAILURE; - cnt = 0; - } - } else if (rtc_acdb.tx_rx_ctl == ACDB_RTC_TX) { - if (acdb_set_tx_rtc(ubuf, cnt)) { - rtc_acdb.err = ACDB_RTC_SUCCESS; - } else { - rtc_acdb.err = ACDB_RTC_ERR_UNKNOWN_FAILURE; - cnt = 0; - } - } - } - return cnt; -} - - -static const struct file_operations rtc_acdb_data_debug_fops = { - .open = rtc_getsetabid_data_dbg_open, - .write = rtc_getsetabid_data_dbg_write, - .read = rtc_getsetabid_data_dbg_read -}; - -static const struct file_operations rtc_acdb_debug_fops = { - .open = rtc_getsetabid_dbg_open, - .write = rtc_getsetabid_dbg_write, - .read = rtc_getsetabid_dbg_read -}; - -static void rtc_acdb_deinit(void) -{ - struct rtc_acdb_pmem *rtc_read = &rtc_acdb.rtc_read; - struct rtc_acdb_pmem *rtc_write = &rtc_acdb.rtc_write; - if (get_set_abid_dentry) { - MM_DBG("GetSet ABID remove debugfs\n"); - debugfs_remove(get_set_abid_dentry); - } - - if (get_set_abid_data_dentry) { - MM_DBG("GetSet ABID remove debugfs\n"); - debugfs_remove(get_set_abid_data_dentry); - } - rtc_acdb.abid = 0; - rtc_acdb.acdb_id = 0; - rtc_acdb.cmd_id = 0; - rtc_acdb.err = 1; - rtc_acdb.set_abid = 0; - rtc_acdb.set_iid = 0; - rtc_acdb.tx_rx_ctl = 0; - rtc_acdb.valid_abid = false; - - if (rtc_read->viraddr != NULL || ((void *)rtc_read->phys) != NULL) { - iounmap(rtc_read->map_v_rtc); - free_contiguous_memory_by_paddr(rtc_read->phys); - } - if (rtc_write->viraddr != NULL || ((void *)rtc_write->phys) != NULL) { - iounmap(rtc_write->map_v_rtc); - free_contiguous_memory_by_paddr(rtc_write->phys); - } -} - -static bool rtc_acdb_init(void) -{ - struct rtc_acdb_pmem *rtc_read = &rtc_acdb.rtc_read; - struct rtc_acdb_pmem *rtc_write = &rtc_acdb.rtc_write; - s32 result = 0; - char name[sizeof "get_set_abid"+1]; - char name1[sizeof "get_set_abid_data"+1]; - rtc_acdb.abid = 0; - rtc_acdb.acdb_id = 0; - rtc_acdb.cmd_id = 0; - rtc_acdb.err = 1; - rtc_acdb.set_abid = 0; - rtc_acdb.set_iid = 0; - rtc_acdb.valid_abid = false; - rtc_acdb.tx_rx_ctl = 0; - if (acdb_data.build_id[17] == '1') { - snprintf(name, sizeof name, "get_set_abid"); - get_set_abid_dentry = debugfs_create_file(name, - S_IFREG | S_IRUGO | S_IWUGO, - NULL, NULL, &rtc_acdb_debug_fops); - if (IS_ERR(get_set_abid_dentry)) { - MM_ERR("SET GET ABID debugfs_create_file failed\n"); - return false; - } - - snprintf(name1, sizeof name1, "get_set_abid_data"); - get_set_abid_data_dentry = debugfs_create_file(name1, - S_IFREG | S_IRUGO | S_IWUGO, - NULL, NULL, - &rtc_acdb_data_debug_fops); - if (IS_ERR(get_set_abid_data_dentry)) { - MM_ERR("SET GET ABID DATA" - " debugfs_create_file failed\n"); - return false; - } - } - - rtc_read->phys = allocate_contiguous_ebi_nomap(PMEM_RTC_ACDB_QUERY_MEM, - SZ_4K); - - if (!rtc_read->phys) { - MM_ERR("ACDB Cannot allocate physical memory\n"); - result = -ENOMEM; - goto error; - } - rtc_read->map_v_rtc = ioremap(rtc_read->phys, - PMEM_RTC_ACDB_QUERY_MEM); - - if (IS_ERR(rtc_read->map_v_rtc)) { - MM_ERR("ACDB Could not map physical address\n"); - result = -ENOMEM; - goto error; - } - rtc_read->viraddr = rtc_read->map_v_rtc; - memset(rtc_read->viraddr, 0, PMEM_RTC_ACDB_QUERY_MEM); - - rtc_write->phys = allocate_contiguous_ebi_nomap(PMEM_RTC_ACDB_QUERY_MEM, - SZ_4K); - - if (!rtc_write->phys) { - MM_ERR("ACDB Cannot allocate physical memory\n"); - result = -ENOMEM; - goto error; - } - rtc_write->map_v_rtc = ioremap(rtc_write->phys, - PMEM_RTC_ACDB_QUERY_MEM); - - if (IS_ERR(rtc_write->map_v_rtc)) { - MM_ERR("ACDB Could not map physical address\n"); - result = -ENOMEM; - goto error; - } - rtc_write->viraddr = rtc_write->map_v_rtc; - memset(rtc_write->viraddr, 0, PMEM_RTC_ACDB_QUERY_MEM); - init_waitqueue_head(&rtc_acdb.wait); - return true; -error: - MM_DBG("INIT RTC FAILED REMOVING RTC DEBUG FS\n"); - if (get_set_abid_dentry) { - MM_DBG("GetSet ABID remove debugfs\n"); - debugfs_remove(get_set_abid_dentry); - } - - if (get_set_abid_data_dentry) { - MM_DBG("GetSet ABID remove debugfs\n"); - debugfs_remove(get_set_abid_data_dentry); - } - if (rtc_read->viraddr != NULL || ((void *)rtc_read->phys) != NULL) { - iounmap(rtc_read->map_v_rtc); - free_contiguous_memory_by_paddr(rtc_read->phys); - } - if (rtc_write->viraddr != NULL || ((void *)rtc_write->phys) != NULL) { - iounmap(rtc_write->map_v_rtc); - free_contiguous_memory_by_paddr(rtc_write->phys); - } - return false; -} -#endif /*CONFIG_DEBUG_FS*/ -static s32 acdb_set_calibration_blk(unsigned long arg) -{ - struct acdb_cmd_device acdb_cmd; - s32 result = 0; - - MM_DBG("acdb_set_calibration_blk\n"); - if (copy_from_user(&acdb_cmd, (struct acdb_cmd_device *)arg, - sizeof(acdb_cmd))) { - MM_ERR("Failed copy command struct from user in" - "acdb_set_calibration_blk\n"); - return -EFAULT; - } - acdb_cmd.phys_buf = (u32 *)acdb_data.paddr; - - MM_DBG("acdb_cmd.phys_buf %x\n", (u32)acdb_cmd.phys_buf); - - result = dalrpc_fcn_8(ACDB_DalACDB_ioctl, acdb_data.handle, - (const void *)&acdb_cmd, sizeof(acdb_cmd), - &acdb_data.acdb_result, - sizeof(acdb_data.acdb_result)); - - if (result < 0) { - MM_ERR("ACDB=> Device Set RPC failure" - " result = %d\n", result); - return -EINVAL; - } else { - MM_ERR("ACDB=> Device Set RPC success\n"); - if (acdb_data.acdb_result.result == ACDB_RES_SUCCESS) - MM_DBG("ACDB_SET_DEVICE Success\n"); - else if (acdb_data.acdb_result.result == ACDB_RES_FAILURE) - MM_ERR("ACDB_SET_DEVICE Failure\n"); - else if (acdb_data.acdb_result.result == ACDB_RES_BADPARM) - MM_ERR("ACDB_SET_DEVICE BadParams\n"); - else - MM_ERR("Unknown error\n"); - } - return result; -} - -static s32 acdb_get_calibration_blk(unsigned long arg) -{ - s32 result = 0; - struct acdb_cmd_device acdb_cmd; - - MM_DBG("acdb_get_calibration_blk\n"); - - if (copy_from_user(&acdb_cmd, (struct acdb_cmd_device *)arg, - sizeof(acdb_cmd))) { - MM_ERR("Failed copy command struct from user in" - "acdb_get_calibration_blk\n"); - return -EFAULT; - } - acdb_cmd.phys_buf = (u32 *)acdb_data.paddr; - MM_ERR("acdb_cmd.phys_buf %x\n", (u32)acdb_cmd.phys_buf); - - result = dalrpc_fcn_8(ACDB_DalACDB_ioctl, acdb_data.handle, - (const void *)&acdb_cmd, sizeof(acdb_cmd), - &acdb_data.acdb_result, - sizeof(acdb_data.acdb_result)); - - if (result < 0) { - MM_ERR("ACDB=> Device Get RPC failure" - " result = %d\n", result); - return -EINVAL; - } else { - MM_ERR("ACDB=> Device Get RPC Success\n"); - if (acdb_data.acdb_result.result == ACDB_RES_SUCCESS) - MM_DBG("ACDB_GET_DEVICE Success\n"); - else if (acdb_data.acdb_result.result == ACDB_RES_FAILURE) - MM_ERR("ACDB_GET_DEVICE Failure\n"); - else if (acdb_data.acdb_result.result == ACDB_RES_BADPARM) - MM_ERR("ACDB_GET_DEVICE BadParams\n"); - else - MM_ERR("Unknown error\n"); - } - return result; -} - -static int audio_acdb_open(struct inode *inode, struct file *file) -{ - MM_DBG("%s\n", __func__); - return 0; -} -static int audio_acdb_release(struct inode *inode, struct file *file) -{ - MM_DBG("%s\n", __func__); - return 0; -} - -static long audio_acdb_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - int rc = 0; - unsigned long flags = 0; - struct msm_audio_pmem_info info; - - MM_DBG("%s\n", __func__); - - switch (cmd) { - case AUDIO_SET_EQ: - MM_DBG("IOCTL SET_EQ_CONFIG\n"); - if (copy_from_user(&acdb_data.eq.num_bands, (void *) arg, - sizeof(acdb_data.eq) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) { - rc = -EFAULT; - break; - } - spin_lock_irqsave(&acdb_data.dsp_lock, flags); - acdb_data.dec_id = 0; - rc = audpp_dsp_set_eq(acdb_data.dec_id, 1, - &acdb_data.eq, COPP); - if (rc < 0) - MM_ERR("AUDPP returned err =%d\n", rc); - spin_unlock_irqrestore(&acdb_data.dsp_lock, flags); - break; - case AUDIO_REGISTER_PMEM: - MM_DBG("AUDIO_REGISTER_PMEM\n"); - if (copy_from_user(&info, (void *) arg, sizeof(info))) { - MM_ERR("Cannot copy from user\n"); - return -EFAULT; - } - rc = get_pmem_file(info.fd, &acdb_data.paddr, - &acdb_data.kvaddr, - &acdb_data.pmem_len, - &acdb_data.file); - if (rc == 0) - acdb_data.pmem_fd = info.fd; - break; - case AUDIO_DEREGISTER_PMEM: - if (acdb_data.pmem_fd) - put_pmem_file(acdb_data.file); - break; - case AUDIO_SET_ACDB_BLK: - MM_DBG("IOCTL AUDIO_SET_ACDB_BLK\n"); - rc = acdb_set_calibration_blk(arg); - break; - case AUDIO_GET_ACDB_BLK: - MM_DBG("IOiCTL AUDIO_GET_ACDB_BLK\n"); - rc = acdb_get_calibration_blk(arg); - break; - default: - MM_DBG("Unknown IOCTL%d\n", cmd); - rc = -EINVAL; - } - return rc; -} - -static const struct file_operations acdb_fops = { - .owner = THIS_MODULE, - .open = audio_acdb_open, - .release = audio_acdb_release, - .llseek = no_llseek, - .unlocked_ioctl = audio_acdb_ioctl -}; - -struct miscdevice acdb_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_acdb", - .fops = &acdb_fops, -}; - -static s32 acdb_get_calibration(void) -{ - struct acdb_cmd_get_device_table acdb_cmd; - s32 result = 0; - u32 iterations = 0; - - MM_DBG("acdb state = %d\n", acdb_data.acdb_state); - - acdb_cmd.command_id = ACDB_GET_DEVICE_TABLE; - acdb_cmd.device_id = acdb_data.device_info->acdb_id; - acdb_cmd.network_id = 0x0108B153; - acdb_cmd.sample_rate_id = acdb_data.device_info->sample_rate; - acdb_cmd.total_bytes = ACDB_BUF_SIZE; - acdb_cmd.phys_buf = (u32 *)acdb_data.phys_addr; - MM_DBG("device_id = %d, sampling_freq = %d\n", - acdb_cmd.device_id, acdb_cmd.sample_rate_id); - - do { - result = dalrpc_fcn_8(ACDB_DalACDB_ioctl, acdb_data.handle, - (const void *)&acdb_cmd, sizeof(acdb_cmd), - &acdb_data.acdb_result, - sizeof(acdb_data.acdb_result)); - - if (result < 0) { - MM_ERR("ACDB=> Device table RPC failure" - " result = %d\n", result); - goto error; - } - /*following check is introduced to handle boot up race - condition between AUDCAL SW peers running on apps - and modem (ACDB_RES_BADSTATE indicates modem AUDCAL SW is - not in initialized sate) we need to retry to get ACDB - values*/ - if (acdb_data.acdb_result.result == ACDB_RES_BADSTATE) { - msleep(500); - iterations++; - } else if (acdb_data.acdb_result.result == ACDB_RES_SUCCESS) { - MM_DBG("Modem query for acdb values is successful" - " (iterations = %d)\n", iterations); - acdb_data.acdb_state |= CAL_DATA_READY; - return result; - } else { - MM_ERR("ACDB=> modem failed to fill acdb values," - " reuslt = %d, (iterations = %d)\n", - acdb_data.acdb_result.result, - iterations); - goto error; - } - } while (iterations < MAX_RETRY); - MM_ERR("ACDB=> AUDCAL SW on modem is not in intiailized state (%d)\n", - acdb_data.acdb_result.result); -error: - result = -EINVAL; - return result; -} - -s32 acdb_get_calibration_data(struct acdb_get_block *get_block) -{ - s32 result = -EINVAL; - struct acdb_cmd_device acdb_cmd; - struct acdb_result acdb_result; - - MM_DBG("acdb_get_calibration_data\n"); - - acdb_cmd.command_id = ACDB_GET_DEVICE; - acdb_cmd.network_id = 0x0108B153; - acdb_cmd.device_id = get_block->acdb_id; - acdb_cmd.sample_rate_id = get_block->sample_rate_id; - acdb_cmd.interface_id = get_block->interface_id; - acdb_cmd.algorithm_block_id = get_block->algorithm_block_id; - acdb_cmd.total_bytes = get_block->total_bytes; - acdb_cmd.phys_buf = (u32 *)acdb_data.get_blk_paddr; - - result = dalrpc_fcn_8(ACDB_DalACDB_ioctl, acdb_data.handle, - (const void *)&acdb_cmd, sizeof(acdb_cmd), - &acdb_result, - sizeof(acdb_result)); - - if (result < 0) { - MM_ERR("ACDB=> Device Get RPC failure" - " result = %d\n", result); - goto err_state; - } else { - MM_DBG("ACDB=> Device Get RPC Success\n"); - if (acdb_result.result == ACDB_RES_SUCCESS) { - MM_DBG("ACDB_GET_DEVICE Success\n"); - result = 0; - memcpy(get_block->buf_ptr, acdb_data.get_blk_kvaddr, - get_block->total_bytes); - } else if (acdb_result.result == ACDB_RES_FAILURE) - MM_ERR("ACDB_GET_DEVICE Failure\n"); - else if (acdb_result.result == ACDB_RES_BADPARM) - MM_ERR("ACDB_GET_DEVICE BadParams\n"); - else - MM_ERR("Unknown error\n"); - } -err_state: - return result; -} -EXPORT_SYMBOL(acdb_get_calibration_data); - -static u8 check_device_info_already_present( - struct auddev_evt_audcal_info audcal_info, - struct acdb_cache_node *acdb_cache_free_node) -{ - if ((audcal_info.dev_id == - acdb_cache_free_node->device_info.dev_id) && - (audcal_info.sample_rate == - acdb_cache_free_node->device_info.\ - sample_rate) && - (audcal_info.acdb_id == - acdb_cache_free_node->device_info.acdb_id)) { - MM_DBG("acdb values are already present\n"); - /*if acdb state is not set for CAL_DATA_READY and node status - is filled, acdb state should be updated with CAL_DATA_READY - state*/ - acdb_data.acdb_state |= CAL_DATA_READY; - /*checking for cache node status if it is not filled then the - acdb values are not cleaned from node so update node status - with acdb value filled*/ - if ((acdb_cache_free_node->node_status != ACDB_VALUES_FILLED) && - ((audcal_info.dev_type & RX_DEVICE) == 1)) { - MM_DBG("device was released earlier\n"); - acdb_cache_free_node->node_status = ACDB_VALUES_FILLED; - return 2; /*node is presnet but status as not filled*/ - } - return 1; /*node is present but status as filled*/ - } - MM_DBG("copying device info into node\n"); - /*as device information is not present in cache copy - the current device information into the node*/ - memcpy(&acdb_cache_free_node->device_info, - &audcal_info, sizeof(audcal_info)); - return 0; /*cant find the node*/ -} - -static struct acdb_iir_block *get_audpp_irr_block(void) -{ - struct header *prs_hdr; - u32 index = 0; - - while (index < acdb_data.acdb_result.used_bytes) { - prs_hdr = (struct header *)(acdb_data.virt_addr + index); - if (prs_hdr->dbor_signature == DBOR_SIGNATURE) { - if (prs_hdr->abid == ABID_AUDIO_IIR_RX) { - if (prs_hdr->iid == IID_AUDIO_IIR_COEFF) - return (struct acdb_iir_block *) - (acdb_data.virt_addr + index - + sizeof(struct header)); - } else { - index += prs_hdr->data_len + - sizeof(struct header); - } - } else { - break; - } - } - return NULL; -} - - -static s32 acdb_fill_audpp_iir(void) -{ - struct acdb_iir_block *acdb_iir; - s32 i = 0; - - acdb_iir = get_audpp_irr_block(); - if (acdb_iir == NULL) { - MM_ERR("unable to find audpp iir block returning\n"); - return -1; - } - memset(acdb_data.pp_iir, 0, sizeof(*acdb_data.pp_iir)); - - acdb_data.pp_iir->common.cmd_id = AUDPP_CMD_CFG_OBJECT_PARAMS; - acdb_data.pp_iir->common.stream = AUDPP_CMD_COPP_STREAM; - acdb_data.pp_iir->common.stream_id = 0; - acdb_data.pp_iir->common.obj_cfg = AUDPP_CMD_OBJ0_UPDATE; - acdb_data.pp_iir->common.command_type = 0; - - acdb_data.pp_iir->active_flag = acdb_iir->enable_flag; - acdb_data.pp_iir->num_bands = acdb_iir->stage_count; - for (; i < acdb_iir->stage_count; i++) { - acdb_data.pp_iir->params_filter.filter_4_params. - numerator_filter[i].numerator_b0_filter_lsw = - acdb_iir->stages[i].b0_lo; - acdb_data.pp_iir->params_filter.filter_4_params. - numerator_filter[i].numerator_b0_filter_msw = - acdb_iir->stages[i].b0_hi; - acdb_data.pp_iir->params_filter.filter_4_params. - numerator_filter[i].numerator_b1_filter_lsw = - acdb_iir->stages[i].b1_lo; - acdb_data.pp_iir->params_filter.filter_4_params. - numerator_filter[i].numerator_b1_filter_msw = - acdb_iir->stages[i].b1_hi; - acdb_data.pp_iir->params_filter.filter_4_params. - numerator_filter[i].numerator_b2_filter_lsw = - acdb_iir->stages[i].b2_lo; - acdb_data.pp_iir->params_filter.filter_4_params. - numerator_filter[i].numerator_b2_filter_msw = - acdb_iir->stages[i].b2_hi; - acdb_data.pp_iir->params_filter.filter_4_params. - denominator_filter[i].denominator_a0_filter_lsw = - acdb_iir->stages_a[i].a1_lo; - acdb_data.pp_iir->params_filter.filter_4_params. - denominator_filter[i].denominator_a0_filter_msw = - acdb_iir->stages_a[i].a1_hi; - acdb_data.pp_iir->params_filter.filter_4_params. - denominator_filter[i].denominator_a1_filter_lsw = - acdb_iir->stages_a[i].a2_lo; - acdb_data.pp_iir->params_filter.filter_4_params. - denominator_filter[i].denominator_a1_filter_msw = - acdb_iir->stages_a[i].a2_hi; - acdb_data.pp_iir->params_filter.filter_4_params. - shift_factor_filter[i].shift_factor_0 = - acdb_iir->shift_factor[i]; - acdb_data.pp_iir->params_filter.filter_4_params.pan_filter[i]. - pan_filter_0 = acdb_iir->pan[i]; - } - return 0; -} - -static void extract_mbadrc(u32 *phy_addr, struct header *prs_hdr, u32 *index) -{ - if (prs_hdr->iid == IID_MBADRC_EXT_BUFF) { - MM_DBG("Got IID = IID_MBADRC_EXT_BUFF\n"); - *phy_addr = acdb_data.phys_addr + *index + - sizeof(struct header); - memcpy(acdb_data.mbadrc_block.ext_buf, - (acdb_data.virt_addr + *index + - sizeof(struct header)), 196*2); - MM_DBG("phy_addr = %x\n", *phy_addr); - *index += prs_hdr->data_len + sizeof(struct header); - } else if (prs_hdr->iid == IID_MBADRC_BAND_CONFIG) { - MM_DBG("Got IID == IID_MBADRC_BAND_CONFIG\n"); - memcpy(acdb_data.mbadrc_block.band_config, (acdb_data.virt_addr - + *index + sizeof(struct header)), - sizeof(struct mbadrc_band_config_type) * - acdb_data.mbadrc_block.parameters.\ - mbadrc_num_bands); - *index += prs_hdr->data_len + sizeof(struct header); - } else if (prs_hdr->iid == IID_MBADRC_PARAMETERS) { - struct mbadrc_parameter *tmp; - tmp = (struct mbadrc_parameter *)(acdb_data.virt_addr + *index - + sizeof(struct header)); - MM_DBG("Got IID == IID_MBADRC_PARAMETERS\n"); - acdb_data.mbadrc_block.parameters.mbadrc_enable = - tmp->mbadrc_enable; - acdb_data.mbadrc_block.parameters.mbadrc_num_bands = - tmp->mbadrc_num_bands; - acdb_data.mbadrc_block.parameters.mbadrc_down_sample_level = - tmp->mbadrc_down_sample_level; - acdb_data.mbadrc_block.parameters.mbadrc_delay = - tmp->mbadrc_delay; - *index += prs_hdr->data_len + sizeof(struct header); - } -} - -static void get_audpp_mbadrc_block(u32 *phy_addr) -{ - struct header *prs_hdr; - u32 index = 0; - - while (index < acdb_data.acdb_result.used_bytes) { - prs_hdr = (struct header *)(acdb_data.virt_addr + index); - - if (prs_hdr->dbor_signature == DBOR_SIGNATURE) { - if (prs_hdr->abid == ABID_AUDIO_MBADRC_RX) { - if ((prs_hdr->iid == IID_MBADRC_EXT_BUFF) - || (prs_hdr->iid == - IID_MBADRC_BAND_CONFIG) - || (prs_hdr->iid == - IID_MBADRC_PARAMETERS)) { - extract_mbadrc(phy_addr, prs_hdr, - &index); - } - } else { - index += prs_hdr->data_len + - sizeof(struct header); - } - } else { - break; - } - } -} - -static s32 acdb_fill_audpp_mbadrc(void) -{ - u32 mbadrc_phys_addr = -1; - get_audpp_mbadrc_block(&mbadrc_phys_addr); - if (IS_ERR_VALUE(mbadrc_phys_addr)) { - MM_ERR("failed to get mbadrc block\n"); - return -1; - } - - memset(acdb_data.pp_mbadrc, 0, sizeof(*acdb_data.pp_mbadrc)); - - acdb_data.pp_mbadrc->common.cmd_id = AUDPP_CMD_CFG_OBJECT_PARAMS; - acdb_data.pp_mbadrc->common.stream = AUDPP_CMD_COPP_STREAM; - acdb_data.pp_mbadrc->common.stream_id = 0; - acdb_data.pp_mbadrc->common.obj_cfg = AUDPP_CMD_OBJ0_UPDATE; - acdb_data.pp_mbadrc->common.command_type = 0; - - acdb_data.pp_mbadrc->enable = acdb_data.mbadrc_block.\ - parameters.mbadrc_enable; - acdb_data.pp_mbadrc->num_bands = - acdb_data.mbadrc_block.\ - parameters.mbadrc_num_bands; - acdb_data.pp_mbadrc->down_samp_level = - acdb_data.mbadrc_block.parameters.\ - mbadrc_down_sample_level; - acdb_data.pp_mbadrc->adrc_delay = - acdb_data.mbadrc_block.parameters.\ - mbadrc_delay; - - if (acdb_data.mbadrc_block.parameters.mbadrc_num_bands > 1) - acdb_data.pp_mbadrc->ext_buf_size = (97 * 2) + - (33 * 2 * (acdb_data.mbadrc_block.parameters.\ - mbadrc_num_bands - 2)); - - acdb_data.pp_mbadrc->ext_partition = 0; - acdb_data.pp_mbadrc->ext_buf_lsw = (u16)(mbadrc_phys_addr\ - & 0xFFFF); - acdb_data.pp_mbadrc->ext_buf_msw = (u16)((mbadrc_phys_addr\ - & 0xFFFF0000) >> 16); - memcpy(acdb_data.pp_mbadrc->adrc_band, acdb_data.mbadrc_block.\ - band_config, - sizeof(struct mbadrc_band_config_type) * - acdb_data.mbadrc_block.parameters.mbadrc_num_bands); - return 0; -} - -static struct acdb_calib_gain_rx *get_audpp_cal_gain(void) -{ - struct header *prs_hdr; - u32 index = 0; - - while (index < acdb_data.acdb_result.used_bytes) { - prs_hdr = (struct header *)(acdb_data.virt_addr + index); - if (prs_hdr->dbor_signature == DBOR_SIGNATURE) { - if (prs_hdr->abid == ABID_AUDIO_CALIBRATION_GAIN_RX) { - if (prs_hdr->iid == - IID_AUDIO_CALIBRATION_GAIN_RX) { - MM_DBG("Got audpp_calib_gain_rx" - " block\n"); - return (struct acdb_calib_gain_rx *) - (acdb_data.virt_addr + index - + sizeof(struct header)); - } - } else { - index += prs_hdr->data_len + - sizeof(struct header); - } - } else { - break; - } - } - return NULL; -} - -static s32 acdb_fill_audpp_cal_gain(void) -{ - struct acdb_calib_gain_rx *acdb_calib_gain_rx = NULL; - - acdb_calib_gain_rx = get_audpp_cal_gain(); - if (acdb_calib_gain_rx == NULL) { - MM_ERR("unable to find audpp" - " calibration gain block returning\n"); - return -1; - } - MM_DBG("Calibration value" - " for calib_gain_rx %d\n", acdb_calib_gain_rx->audppcalgain); - memset(acdb_data.calib_gain_rx, 0, sizeof(*acdb_data.calib_gain_rx)); - - acdb_data.calib_gain_rx->common.cmd_id = AUDPP_CMD_CFG_OBJECT_PARAMS; - acdb_data.calib_gain_rx->common.stream = AUDPP_CMD_COPP_STREAM; - acdb_data.calib_gain_rx->common.stream_id = 0; - acdb_data.calib_gain_rx->common.obj_cfg = AUDPP_CMD_OBJ0_UPDATE; - acdb_data.calib_gain_rx->common.command_type = 0; - - acdb_data.calib_gain_rx->audppcalgain = - acdb_calib_gain_rx->audppcalgain; - return 0; -} - -static void extract_pbe_block(struct header *prs_hdr, u32 *index) -{ - if (prs_hdr->iid == IID_AUDIO_PBE_RX_ENABLE_FLAG) { - MM_DBG("Got IID = IID_AUDIO_PBE_RX_ENABLE\n"); - acdb_data.pbe_enable_flag = (u16 *)(acdb_data.virt_addr + - *index + - sizeof(struct header)); - *index += prs_hdr->data_len + sizeof(struct header); - } else if (prs_hdr->iid == IID_PBE_CONFIG_PARAMETERS) { - MM_DBG("Got IID == IID_PBE_CONFIG_PARAMETERS\n"); - acdb_data.pbe_blk = (struct acdb_pbe_block *) - (acdb_data.virt_addr + *index - + sizeof(struct header)); - *index += prs_hdr->data_len + sizeof(struct header); - } -} - -static s32 get_audpp_pbe_block(void) -{ - struct header *prs_hdr; - u32 index = 0; - s32 result = -1; - - while (index < acdb_data.acdb_result.used_bytes) { - prs_hdr = (struct header *)(acdb_data.virt_addr + index); - - if (prs_hdr->dbor_signature == DBOR_SIGNATURE) { - if (prs_hdr->abid == ABID_AUDIO_PBE_RX) { - if ((prs_hdr->iid == IID_PBE_CONFIG_PARAMETERS) - || (prs_hdr->iid == - IID_AUDIO_PBE_RX_ENABLE_FLAG)) { - extract_pbe_block(prs_hdr, &index); - result = 0; - } - } else { - index += prs_hdr->data_len + - sizeof(struct header); - } - } else { - break; - } - } - return result; -} - -static s32 acdb_fill_audpp_pbe(void) -{ - s32 result = -1; - - result = get_audpp_pbe_block(); - if (IS_ERR_VALUE(result)) - return result; - memset(acdb_data.pbe_block, 0, sizeof(*acdb_data.pbe_block)); - - acdb_data.pbe_block->common.cmd_id = AUDPP_CMD_CFG_OBJECT_PARAMS; - acdb_data.pbe_block->common.stream = AUDPP_CMD_COPP_STREAM; - acdb_data.pbe_block->common.stream_id = 0; - acdb_data.pbe_block->common.obj_cfg = AUDPP_CMD_OBJ0_UPDATE; - acdb_data.pbe_block->common.command_type = 0; - acdb_data.pbe_block->pbe_enable = *acdb_data.pbe_enable_flag; - - acdb_data.pbe_block->realbassmix = acdb_data.pbe_blk->realbassmix; - acdb_data.pbe_block->basscolorcontrol = - acdb_data.pbe_blk->basscolorcontrol; - acdb_data.pbe_block->mainchaindelay = acdb_data.pbe_blk->mainchaindelay; - acdb_data.pbe_block->xoverfltorder = acdb_data.pbe_blk->xoverfltorder; - acdb_data.pbe_block->bandpassfltorder = - acdb_data.pbe_blk->bandpassfltorder; - acdb_data.pbe_block->adrcdelay = acdb_data.pbe_blk->adrcdelay; - acdb_data.pbe_block->downsamplelevel = - acdb_data.pbe_blk->downsamplelevel; - acdb_data.pbe_block->comprmstav = acdb_data.pbe_blk->comprmstav; - acdb_data.pbe_block->expthreshold = acdb_data.pbe_blk->expthreshold; - acdb_data.pbe_block->expslope = acdb_data.pbe_blk->expslope; - acdb_data.pbe_block->compthreshold = acdb_data.pbe_blk->compthreshold; - acdb_data.pbe_block->compslope = acdb_data.pbe_blk->compslope; - acdb_data.pbe_block->cpmpattack_lsw = acdb_data.pbe_blk->cpmpattack_lsw; - acdb_data.pbe_block->compattack_msw = acdb_data.pbe_blk->compattack_msw; - acdb_data.pbe_block->comprelease_lsw = - acdb_data.pbe_blk->comprelease_lsw; - acdb_data.pbe_block->comprelease_msw = - acdb_data.pbe_blk->comprelease_msw; - acdb_data.pbe_block->compmakeupgain = acdb_data.pbe_blk->compmakeupgain; - acdb_data.pbe_block->baselimthreshold = - acdb_data.pbe_blk->baselimthreshold; - acdb_data.pbe_block->highlimthreshold = - acdb_data.pbe_blk->highlimthreshold; - acdb_data.pbe_block->basslimmakeupgain = - acdb_data.pbe_blk->basslimmakeupgain; - acdb_data.pbe_block->highlimmakeupgain = - acdb_data.pbe_blk->highlimmakeupgain; - acdb_data.pbe_block->limbassgrc = acdb_data.pbe_blk->limbassgrc; - acdb_data.pbe_block->limhighgrc = acdb_data.pbe_blk->limhighgrc; - acdb_data.pbe_block->limdelay = acdb_data.pbe_blk->limdelay; - memcpy(acdb_data.pbe_block->filter_coeffs, - acdb_data.pbe_blk->filter_coeffs, sizeof(u16)*90); - acdb_data.pbe_block->extpartition = 0; - acdb_data.pbe_block->extbuffsize_lsw = PBE_BUF_SIZE; - acdb_data.pbe_block->extbuffsize_msw = 0; - acdb_data.pbe_block->extbuffstart_lsw = ((u32)acdb_data.pbe_extbuff - & 0xFFFF); - acdb_data.pbe_block->extbuffstart_msw = (((u32)acdb_data.pbe_extbuff - & 0xFFFF0000) >> 16); - return 0; -} - - -static s32 acdb_calibrate_audpp(void) -{ - s32 result = 0; - - result = acdb_fill_audpp_iir(); - if (!IS_ERR_VALUE(result)) { - result = audpp_dsp_set_rx_iir(acdb_data.device_info->dev_id, - acdb_data.pp_iir->active_flag, - acdb_data.pp_iir, COPP); - if (result) { - MM_ERR("ACDB=> Failed to send IIR data to postproc\n"); - result = -EINVAL; - goto done; - } else - MM_DBG("AUDPP is calibrated with IIR parameters" - " for COPP ID %d\n", - acdb_data.device_info->dev_id); - } - result = acdb_fill_audpp_mbadrc(); - if (!IS_ERR_VALUE(result)) { - result = audpp_dsp_set_mbadrc(acdb_data.device_info->dev_id, - acdb_data.pp_mbadrc->enable, - acdb_data.pp_mbadrc, COPP); - if (result) { - MM_ERR("ACDB=> Failed to send MBADRC data to" - " postproc\n"); - result = -EINVAL; - goto done; - } else - MM_DBG("AUDPP is calibrated with MBADRC parameters" - " for COPP ID %d\n", - acdb_data.device_info->dev_id); - } - result = acdb_fill_audpp_cal_gain(); - if (!(IS_ERR_VALUE(result))) { - result = audpp_dsp_set_gain_rx(acdb_data.device_info->dev_id, - acdb_data.calib_gain_rx, COPP); - if (result) { - MM_ERR("ACDB=> Failed to send gain_rx" - " data to postproc\n"); - result = -EINVAL; - goto done; - } else - MM_DBG("AUDPP is calibrated with calib_gain_rx\n"); - } - result = acdb_fill_audpp_pbe(); - if (!(IS_ERR_VALUE(result))) { - result = audpp_dsp_set_pbe(acdb_data.device_info->dev_id, - acdb_data.pbe_block->pbe_enable, - acdb_data.pbe_block, COPP); - if (result) { - MM_ERR("ACDB=> Failed to send pbe block" - "data to postproc\n"); - result = -EINVAL; - goto done; - } - MM_DBG("AUDPP is calibarted with PBE\n"); - } -done: - return result; -} - -static struct acdb_agc_block *get_audpreproc_agc_block(void) -{ - struct header *prs_hdr; - u32 index = 0; - - while (index < acdb_data.acdb_result.used_bytes) { - prs_hdr = (struct header *)(acdb_data.virt_addr + index); - if (prs_hdr->dbor_signature == DBOR_SIGNATURE) { - if (prs_hdr->abid == ABID_AUDIO_AGC_TX) { - if (prs_hdr->iid == IID_AUDIO_AGC_PARAMETERS) { - MM_DBG("GOT ABID_AUDIO_AGC_TX\n"); - return (struct acdb_agc_block *) - (acdb_data.virt_addr + index - + sizeof(struct header)); - } - } else { - index += prs_hdr->data_len + - sizeof(struct header); - } - } else { - break; - } - } - return NULL; -} - -static s32 acdb_fill_audpreproc_agc(void) -{ - struct acdb_agc_block *acdb_agc; - - acdb_agc = get_audpreproc_agc_block(); - if (!acdb_agc) { - MM_DBG("unable to find preproc agc parameters winding up\n"); - return -1; - } - memset(acdb_data.preproc_agc, 0, sizeof(*acdb_data.preproc_agc)); - acdb_data.preproc_agc->cmd_id = AUDPREPROC_CMD_CFG_AGC_PARAMS; - acdb_data.preproc_agc->stream_id = acdb_data.preproc_stream_id; - /* 0xFE00 to configure all parameters */ - acdb_data.preproc_agc->tx_agc_param_mask = 0xFFFF; - - if (acdb_agc->enable_status) - acdb_data.preproc_agc->tx_agc_enable_flag = - AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA; - else - acdb_data.preproc_agc->tx_agc_enable_flag = - AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS; - - acdb_data.preproc_agc->comp_rlink_static_gain = - acdb_agc->comp_rlink_static_gain; - acdb_data.preproc_agc->comp_rlink_aig_flag = - acdb_agc->comp_rlink_aig_flag; - acdb_data.preproc_agc->expander_rlink_th = - acdb_agc->exp_rlink_threshold; - acdb_data.preproc_agc->expander_rlink_slope = - acdb_agc->exp_rlink_slope; - acdb_data.preproc_agc->compressor_rlink_th = - acdb_agc->comp_rlink_threshold; - acdb_data.preproc_agc->compressor_rlink_slope = - acdb_agc->comp_rlink_slope; - - /* 0xFFF0 to configure all parameters */ - acdb_data.preproc_agc->tx_adc_agc_param_mask = 0xFFFF; - - acdb_data.preproc_agc->comp_rlink_aig_attackk = - acdb_agc->comp_rlink_aig_attack_k; - acdb_data.preproc_agc->comp_rlink_aig_leak_down = - acdb_agc->comp_rlink_aig_leak_down; - acdb_data.preproc_agc->comp_rlink_aig_leak_up = - acdb_agc->comp_rlink_aig_leak_up; - acdb_data.preproc_agc->comp_rlink_aig_max = - acdb_agc->comp_rlink_aig_max; - acdb_data.preproc_agc->comp_rlink_aig_min = - acdb_agc->comp_rlink_aig_min; - acdb_data.preproc_agc->comp_rlink_aig_releasek = - acdb_agc->comp_rlink_aig_release_k; - acdb_data.preproc_agc->comp_rlink_aig_leakrate_fast = - acdb_agc->comp_rlink_aig_sm_leak_rate_fast; - acdb_data.preproc_agc->comp_rlink_aig_leakrate_slow = - acdb_agc->comp_rlink_aig_sm_leak_rate_slow; - acdb_data.preproc_agc->comp_rlink_attackk_msw = - acdb_agc->comp_rlink_attack_k_msw; - acdb_data.preproc_agc->comp_rlink_attackk_lsw = - acdb_agc->comp_rlink_attack_k_lsw; - acdb_data.preproc_agc->comp_rlink_delay = - acdb_agc->comp_rlink_delay; - acdb_data.preproc_agc->comp_rlink_releasek_msw = - acdb_agc->comp_rlink_release_k_msw; - acdb_data.preproc_agc->comp_rlink_releasek_lsw = - acdb_agc->comp_rlink_release_k_lsw; - acdb_data.preproc_agc->comp_rlink_rms_tav = - acdb_agc->comp_rlink_rms_trav; - return 0; -} - -static struct acdb_iir_block *get_audpreproc_irr_block(void) -{ - - struct header *prs_hdr; - u32 index = 0; - - while (index < acdb_data.acdb_result.used_bytes) { - prs_hdr = (struct header *)(acdb_data.virt_addr + index); - - if (prs_hdr->dbor_signature == DBOR_SIGNATURE) { - if (prs_hdr->abid == ABID_AUDIO_IIR_TX) { - if (prs_hdr->iid == IID_AUDIO_IIR_COEFF) - return (struct acdb_iir_block *) - (acdb_data.virt_addr + index - + sizeof(struct header)); - } else { - index += prs_hdr->data_len + - sizeof(struct header); - } - } else { - break; - } - } - return NULL; -} - - -static s32 acdb_fill_audpreproc_iir(void) -{ - struct acdb_iir_block *acdb_iir; - - - acdb_iir = get_audpreproc_irr_block(); - if (!acdb_iir) { - MM_DBG("unable to find preproc iir parameters winding up\n"); - return -1; - } - memset(acdb_data.preproc_iir, 0, sizeof(*acdb_data.preproc_iir)); - - acdb_data.preproc_iir->cmd_id = - AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS; - acdb_data.preproc_iir->stream_id = acdb_data.preproc_stream_id; - acdb_data.preproc_iir->active_flag = acdb_iir->enable_flag; - acdb_data.preproc_iir->num_bands = acdb_iir->stage_count; - - acdb_data.preproc_iir->numerator_coeff_b0_filter0_lsw = - acdb_iir->stages[0].b0_lo; - acdb_data.preproc_iir->numerator_coeff_b0_filter0_msw = - acdb_iir->stages[0].b0_hi; - acdb_data.preproc_iir->numerator_coeff_b1_filter0_lsw = - acdb_iir->stages[0].b1_lo; - acdb_data.preproc_iir->numerator_coeff_b1_filter0_msw = - acdb_iir->stages[0].b1_hi; - acdb_data.preproc_iir->numerator_coeff_b2_filter0_lsw = - acdb_iir->stages[0].b2_lo; - acdb_data.preproc_iir->numerator_coeff_b2_filter0_msw = - acdb_iir->stages[0].b2_hi; - - acdb_data.preproc_iir->numerator_coeff_b0_filter1_lsw = - acdb_iir->stages[1].b0_lo; - acdb_data.preproc_iir->numerator_coeff_b0_filter1_msw = - acdb_iir->stages[1].b0_hi; - acdb_data.preproc_iir->numerator_coeff_b1_filter1_lsw = - acdb_iir->stages[1].b1_lo; - acdb_data.preproc_iir->numerator_coeff_b1_filter1_msw = - acdb_iir->stages[1].b1_hi; - acdb_data.preproc_iir->numerator_coeff_b2_filter1_lsw = - acdb_iir->stages[1].b2_lo; - acdb_data.preproc_iir->numerator_coeff_b2_filter1_msw = - acdb_iir->stages[1].b2_hi; - - acdb_data.preproc_iir->numerator_coeff_b0_filter2_lsw = - acdb_iir->stages[2].b0_lo; - acdb_data.preproc_iir->numerator_coeff_b0_filter2_msw = - acdb_iir->stages[2].b0_hi; - acdb_data.preproc_iir->numerator_coeff_b1_filter2_lsw = - acdb_iir->stages[2].b1_lo; - acdb_data.preproc_iir->numerator_coeff_b1_filter2_msw = - acdb_iir->stages[2].b1_hi; - acdb_data.preproc_iir->numerator_coeff_b2_filter2_lsw = - acdb_iir->stages[2].b2_lo; - acdb_data.preproc_iir->numerator_coeff_b2_filter2_msw = - acdb_iir->stages[2].b2_hi; - - acdb_data.preproc_iir->numerator_coeff_b0_filter3_lsw = - acdb_iir->stages[3].b0_lo; - acdb_data.preproc_iir->numerator_coeff_b0_filter3_msw = - acdb_iir->stages[3].b0_hi; - acdb_data.preproc_iir->numerator_coeff_b1_filter3_lsw = - acdb_iir->stages[3].b1_lo; - acdb_data.preproc_iir->numerator_coeff_b1_filter3_msw = - acdb_iir->stages[3].b1_hi; - acdb_data.preproc_iir->numerator_coeff_b2_filter3_lsw = - acdb_iir->stages[3].b2_lo; - acdb_data.preproc_iir->numerator_coeff_b2_filter3_msw = - acdb_iir->stages[3].b2_hi; - - acdb_data.preproc_iir->denominator_coeff_a0_filter0_lsw = - acdb_iir->stages_a[0].a1_lo; - acdb_data.preproc_iir->denominator_coeff_a0_filter0_msw = - acdb_iir->stages_a[0].a1_hi; - acdb_data.preproc_iir->denominator_coeff_a1_filter0_lsw = - acdb_iir->stages_a[0].a2_lo; - acdb_data.preproc_iir->denominator_coeff_a1_filter0_msw = - acdb_iir->stages_a[0].a2_hi; - - acdb_data.preproc_iir->denominator_coeff_a0_filter1_lsw = - acdb_iir->stages_a[1].a1_lo; - acdb_data.preproc_iir->denominator_coeff_a0_filter1_msw = - acdb_iir->stages_a[1].a1_hi; - acdb_data.preproc_iir->denominator_coeff_a1_filter1_lsw = - acdb_iir->stages_a[1].a2_lo; - acdb_data.preproc_iir->denominator_coeff_a1_filter1_msw = - acdb_iir->stages_a[1].a2_hi; - - acdb_data.preproc_iir->denominator_coeff_a0_filter2_lsw = - acdb_iir->stages_a[2].a1_lo; - acdb_data.preproc_iir->denominator_coeff_a0_filter2_msw = - acdb_iir->stages_a[2].a1_hi; - acdb_data.preproc_iir->denominator_coeff_a1_filter2_lsw = - acdb_iir->stages_a[2].a2_lo; - acdb_data.preproc_iir->denominator_coeff_a1_filter2_msw = - acdb_iir->stages_a[2].a2_hi; - - acdb_data.preproc_iir->denominator_coeff_a0_filter3_lsw = - acdb_iir->stages_a[3].a1_lo; - acdb_data.preproc_iir->denominator_coeff_a0_filter3_msw = - acdb_iir->stages_a[3].a1_hi; - acdb_data.preproc_iir->denominator_coeff_a1_filter3_lsw = - acdb_iir->stages_a[3].a2_lo; - acdb_data.preproc_iir->denominator_coeff_a1_filter3_msw = - acdb_iir->stages_a[3].a2_hi; - - acdb_data.preproc_iir->shift_factor_filter0 = - acdb_iir->shift_factor[0]; - acdb_data.preproc_iir->shift_factor_filter1 = - acdb_iir->shift_factor[1]; - acdb_data.preproc_iir->shift_factor_filter2 = - acdb_iir->shift_factor[2]; - acdb_data.preproc_iir->shift_factor_filter3 = - acdb_iir->shift_factor[3]; - - acdb_data.preproc_iir->pan_of_filter0 = - acdb_iir->pan[0]; - acdb_data.preproc_iir->pan_of_filter1 = - acdb_iir->pan[1]; - acdb_data.preproc_iir->pan_of_filter2 = - acdb_iir->pan[2]; - acdb_data.preproc_iir->pan_of_filter3 = - acdb_iir->pan[3]; - return 0; -} - -static struct acdb_calib_gain_tx *get_audpreproc_cal_gain(void) -{ - struct header *prs_hdr; - u32 index = 0; - - while (index < acdb_data.acdb_result.used_bytes) { - prs_hdr = (struct header *)(acdb_data.virt_addr + index); - if (prs_hdr->dbor_signature == DBOR_SIGNATURE) { - if (prs_hdr->abid == ABID_AUDIO_CALIBRATION_GAIN_TX) { - if (prs_hdr->iid == - IID_AUDIO_CALIBRATION_GAIN_TX) { - MM_DBG("Got audpreproc_calib_gain_tx" - " block\n"); - return (struct acdb_calib_gain_tx *) - (acdb_data.virt_addr + index - + sizeof(struct header)); - } - } else { - index += prs_hdr->data_len + - sizeof(struct header); - } - } else { - break; - } - } - return NULL; -} - -static s32 acdb_fill_audpreproc_cal_gain(void) -{ - struct acdb_calib_gain_tx *acdb_calib_gain_tx = NULL; - - acdb_calib_gain_tx = get_audpreproc_cal_gain(); - if (acdb_calib_gain_tx == NULL) { - MM_ERR("unable to find audpreproc" - " calibration block returning\n"); - return -1; - } - MM_DBG("Calibration value" - " for calib_gain_tx %d\n", acdb_calib_gain_tx->audprecalgain); - memset(acdb_data.calib_gain_tx, 0, sizeof(*acdb_data.calib_gain_tx)); - - acdb_data.calib_gain_tx->cmd_id = - AUDPREPROC_CMD_CFG_CAL_GAIN_PARAMS; - acdb_data.calib_gain_tx->stream_id = acdb_data.preproc_stream_id; - acdb_data.calib_gain_tx->audprecalgain = - acdb_calib_gain_tx->audprecalgain; - return 0; -} - -static struct acdb_rmc_block *get_rmc_blk(void) -{ - struct header *prs_hdr; - u32 index = 0; - - while (index < acdb_data.acdb_result.used_bytes) { - prs_hdr = (struct header *)(acdb_data.virt_addr + index); - if (prs_hdr->dbor_signature == DBOR_SIGNATURE) { - if (prs_hdr->abid == ABID_AUDIO_RMC_TX) { - if (prs_hdr->iid == - IID_AUDIO_RMC_PARAM) { - MM_DBG("Got afe_rmc block\n"); - return (struct acdb_rmc_block *) - (acdb_data.virt_addr + index - + sizeof(struct header)); - } - } else { - index += prs_hdr->data_len + - sizeof(struct header); - } - } else { - break; - } - } - return NULL; -} - -struct acdb_fluence_block *get_audpp_fluence_block(void) -{ - struct header *prs_hdr; - u32 index = 0; - - while (index < acdb_data.acdb_result.used_bytes) { - prs_hdr = (struct header *)(acdb_data.virt_addr + index); - - if (prs_hdr->dbor_signature == DBOR_SIGNATURE) { - if (prs_hdr->abid == ABID_AUDIO_FLUENCE_TX) { - if (prs_hdr->iid == IID_AUDIO_FLUENCE_TX) { - MM_DBG("got fluence block\n"); - return (struct acdb_fluence_block *) - (acdb_data.virt_addr + index - + sizeof(struct header)); - } - } else { - index += prs_hdr->data_len + - sizeof(struct header); - } - } else { - break; - } - } - return NULL; -} - -static s32 acdb_fill_audpreproc_fluence(void) -{ - struct acdb_fluence_block *fluence_block = NULL; - fluence_block = get_audpp_fluence_block(); - if (!fluence_block) { - MM_ERR("error in finding fluence block\n"); - return -EPERM; - } - memset(&acdb_data.preproc_lvnv, 0, sizeof( - struct audpreproc_cmd_cfg_lvnv_param)); - memcpy(acdb_data.fluence_extbuff_virt, - &fluence_block->cs_tuningMode, - (sizeof(struct acdb_fluence_block) - - sizeof(fluence_block->csmode))); - acdb_data.preproc_lvnv.cmd_id = AUDPREPROC_CMD_CFG_LVNV_PARMS; - acdb_data.preproc_lvnv.stream_id = acdb_data.preproc_stream_id; - acdb_data.preproc_lvnv.cs_mode = fluence_block->csmode; - acdb_data.preproc_lvnv.lvnv_ext_buf_size = FLUENCE_BUF_SIZE; - acdb_data.preproc_lvnv.lvnv_ext_buf_start_lsw =\ - ((u32)(acdb_data.fluence_extbuff)\ - & 0x0000FFFF); - acdb_data.preproc_lvnv.lvnv_ext_buf_start_msw =\ - (((u32)acdb_data.fluence_extbuff\ - & 0xFFFF0000) >> 16); - return 0; -} - -s32 acdb_calibrate_audpreproc(void) -{ - s32 result = 0; - struct acdb_rmc_block *acdb_rmc = NULL; - - result = acdb_fill_audpreproc_agc(); - if (!IS_ERR_VALUE(result)) { - result = audpreproc_dsp_set_agc(acdb_data.preproc_agc, sizeof( - struct audpreproc_cmd_cfg_agc_params)); - if (result) { - MM_ERR("ACDB=> Failed to send AGC data to preproc)\n"); - result = -EINVAL; - goto done; - } else - MM_DBG("AUDPREC is calibrated with AGC parameters" - " for COPP ID %d and AUDREC session %d\n", - acdb_data.device_info->dev_id, - acdb_data.preproc_stream_id); - } - result = acdb_fill_audpreproc_iir(); - if (!IS_ERR_VALUE(result)) { - result = audpreproc_dsp_set_iir(acdb_data.preproc_iir, - sizeof(struct\ - audpreproc_cmd_cfg_iir_tuning_filter_params)); - if (result) { - MM_ERR("ACDB=> Failed to send IIR data to preproc\n"); - result = -EINVAL; - goto done; - } else - MM_DBG("audpreproc is calibrated with iir parameters" - " for COPP ID %d and AUREC session %d\n", - acdb_data.device_info->dev_id, - acdb_data.preproc_stream_id); - } - result = acdb_fill_audpreproc_cal_gain(); - if (!(IS_ERR_VALUE(result))) { - result = audpreproc_dsp_set_gain_tx(acdb_data.calib_gain_tx, - sizeof(struct audpreproc_cmd_cfg_cal_gain)); - if (result) { - MM_ERR("ACDB=> Failed to send calib_gain_tx" - " data to preproc\n"); - result = -EINVAL; - goto done; - } else - MM_DBG("AUDPREPROC is calibrated" - " with calib_gain_tx\n"); - } - if (acdb_data.build_id[17] != '0') { - acdb_rmc = get_rmc_blk(); - if (acdb_rmc != NULL) { - result = afe_config_rmc_block(acdb_rmc); - if (result) { - MM_ERR("ACDB=> Failed to send rmc" - " data to afe\n"); - result = -EINVAL; - goto done; - } else - MM_DBG("AFE is calibrated with rmc params\n"); - } else - MM_DBG("RMC block was not found\n"); - } - if (!acdb_data.fleuce_feature_status[acdb_data.preproc_stream_id]) { - result = acdb_fill_audpreproc_fluence(); - if (!(IS_ERR_VALUE(result))) { - result = audpreproc_dsp_set_lvnv( - &acdb_data.preproc_lvnv, - sizeof(struct\ - audpreproc_cmd_cfg_lvnv_param)); - if (result) { - MM_ERR("ACDB=> Failed to send lvnv " - "data to preproc\n"); - result = -EINVAL; - goto done; - } else - MM_DBG("AUDPREPROC is calibrated" - " with lvnv parameters\n"); - } else - MM_ERR("fluence block is not found\n"); - } else - MM_DBG("fluence block override\n"); -done: - return result; -} - -static s32 acdb_send_calibration(void) -{ - s32 result = 0; - - if ((acdb_data.device_info->dev_type & RX_DEVICE) == 1) { - result = acdb_calibrate_audpp(); - if (result) - goto done; - } else if ((acdb_data.device_info->dev_type & TX_DEVICE) == 2) { - result = acdb_calibrate_audpreproc(); - if (result) - goto done; - if (acdb_data.preproc_stream_id == 0) - acdb_data.audrec_applied |= AUDREC0_READY; - else if (acdb_data.preproc_stream_id == 1) - acdb_data.audrec_applied |= AUDREC1_READY; - else if (acdb_data.preproc_stream_id == 2) - acdb_data.audrec_applied |= AUDREC2_READY; - MM_DBG("acdb_data.audrec_applied = %x\n", - acdb_data.audrec_applied); - } -done: - return result; -} - -static u8 check_tx_acdb_values_cached(void) -{ - u8 stream_id = acdb_data.preproc_stream_id; - - if ((acdb_data.device_info->dev_id == - acdb_cache_tx[stream_id].device_info.dev_id) && - (acdb_data.device_info->sample_rate == - acdb_cache_tx[stream_id].device_info.sample_rate) && - (acdb_data.device_info->acdb_id == - acdb_cache_tx[stream_id].device_info.acdb_id) && - (acdb_cache_tx[stream_id].node_status == - ACDB_VALUES_FILLED)) - return 0; - else - return 1; -} - -static void handle_tx_device_ready_callback(void) -{ - u8 i = 0; - u8 ret = 0; - u8 acdb_value_apply = 0; - u8 result = 0; - u8 stream_id = acdb_data.preproc_stream_id; - - if (acdb_data.multiple_sessions) { - for (i = 0; i < MAX_AUDREC_SESSIONS; i++) { - /*check is to exclude copying acdb values in the - current node pointed by acdb_data structure*/ - if (acdb_cache_tx[i].phys_addr_acdb_values != - acdb_data.phys_addr) { - ret = check_device_info_already_present(\ - *acdb_data.device_info, - &acdb_cache_tx[i]); - if (ret) { - memcpy((char *)acdb_cache_tx[i].\ - virt_addr_acdb_values, - (char *)acdb_data.virt_addr, - ACDB_BUF_SIZE); - acdb_cache_tx[i].node_status = - ACDB_VALUES_FILLED; - } - } - } - acdb_data.multiple_sessions = 0; - } - /*check wheather AUDREC enabled before device call backs*/ - if ((acdb_data.acdb_state & AUDREC0_READY) && - !(acdb_data.audrec_applied & AUDREC0_READY)) { - MM_DBG("AUDREC0 already enabled apply acdb values\n"); - acdb_value_apply |= AUDREC0_READY; - } else if ((acdb_data.acdb_state & AUDREC1_READY) && - !(acdb_data.audrec_applied & AUDREC1_READY)) { - MM_DBG("AUDREC1 already enabled apply acdb values\n"); - acdb_value_apply |= AUDREC1_READY; - } else if ((acdb_data.acdb_state & AUDREC2_READY) && - !(acdb_data.audrec_applied & AUDREC2_READY)) { - MM_DBG("AUDREC2 already enabled apply acdb values\n"); - acdb_value_apply |= AUDREC2_READY; - } - if (acdb_value_apply) { - if (session_info[stream_id].sampling_freq) - acdb_data.device_info->sample_rate = - session_info[stream_id].sampling_freq; - result = check_tx_acdb_values_cached(); - if (result) { - result = acdb_get_calibration(); - if (result < 0) { - MM_ERR("Not able to get calibration" - " data continue\n"); - return; - } - } - acdb_cache_tx[stream_id].node_status = ACDB_VALUES_FILLED; - acdb_send_calibration(); - } -} - -static struct acdb_cache_node *get_acdb_values_from_cache_tx(u32 stream_id) -{ - MM_DBG("searching node with stream_id %d\n", stream_id); - if ((acdb_cache_tx[stream_id].stream_id == stream_id) && - (acdb_cache_tx[stream_id].node_status == - ACDB_VALUES_NOT_FILLED)) { - return &acdb_cache_tx[stream_id]; - } - MM_DBG("Error! in finding node\n"); - return NULL; -} - -static void update_acdb_data_struct(struct acdb_cache_node *cur_node) -{ - if (cur_node) { - acdb_data.device_info = &cur_node->device_info; - acdb_data.virt_addr = cur_node->virt_addr_acdb_values; - acdb_data.phys_addr = cur_node->phys_addr_acdb_values; - } else - MM_ERR("error in curent node\n"); -} - -static void send_acdb_values_for_active_devices(void) -{ - u32 i = 0; - for (i = 0; i < MAX_COPP_NODE_SUPPORTED; i++) { - if (acdb_cache_rx[i].node_status == - ACDB_VALUES_FILLED) { - update_acdb_data_struct(&acdb_cache_rx[i]); - if (acdb_data.acdb_state & CAL_DATA_READY) - acdb_send_calibration(); - } - } -} - -static s32 initialize_rpc(void) -{ - s32 result = 0; - - result = daldevice_attach(DALDEVICEID_ACDB, ACDB_PORT_NAME, - ACDB_CPU, &acdb_data.handle); - - if (result) { - MM_ERR("ACDB=> Device Attach failed\n"); - result = -ENODEV; - goto done; - } -done: - return result; -} - -static u32 allocate_memory_acdb_cache_tx(void) -{ - u32 result = 0; - u32 i = 0; - u32 err = 0; - /*initialize local cache */ - for (i = 0; i < MAX_AUDREC_SESSIONS; i++) { - acdb_cache_tx[i].phys_addr_acdb_values = - allocate_contiguous_ebi_nomap(ACDB_BUF_SIZE, - SZ_4K); - - if (!acdb_cache_tx[i].phys_addr_acdb_values) { - MM_ERR("ACDB=> Cannot allocate physical memory\n"); - result = -ENOMEM; - goto error; - } - acdb_cache_tx[i].map_v_addr = ioremap( - acdb_cache_tx[i].phys_addr_acdb_values, - ACDB_BUF_SIZE); - if (IS_ERR(acdb_cache_tx[i].map_v_addr)) { - MM_ERR("ACDB=> Could not map physical address\n"); - result = -ENOMEM; - free_contiguous_memory_by_paddr( - acdb_cache_tx[i].phys_addr_acdb_values); - goto error; - } - acdb_cache_tx[i].virt_addr_acdb_values = - acdb_cache_tx[i].map_v_addr; - memset(acdb_cache_tx[i].virt_addr_acdb_values, 0, - ACDB_BUF_SIZE); - } - return result; -error: - for (err = 0; err < i; err++) { - iounmap(acdb_cache_tx[err].map_v_addr); - free_contiguous_memory_by_paddr( - acdb_cache_tx[err].phys_addr_acdb_values); - } - return result; -} - -static u32 allocate_memory_acdb_cache_rx(void) -{ - u32 result = 0; - u32 i = 0; - u32 err = 0; - - /*initialize local cache */ - for (i = 0; i < MAX_COPP_NODE_SUPPORTED; i++) { - acdb_cache_rx[i].phys_addr_acdb_values = - allocate_contiguous_ebi_nomap( - ACDB_BUF_SIZE, SZ_4K); - - if (!acdb_cache_rx[i].phys_addr_acdb_values) { - MM_ERR("ACDB=> Can not allocate physical memory\n"); - result = -ENOMEM; - goto error; - } - acdb_cache_rx[i].map_v_addr = - ioremap(acdb_cache_rx[i].phys_addr_acdb_values, - ACDB_BUF_SIZE); - if (IS_ERR(acdb_cache_rx[i].map_v_addr)) { - MM_ERR("ACDB=> Could not map physical address\n"); - result = -ENOMEM; - free_contiguous_memory_by_paddr( - acdb_cache_rx[i].phys_addr_acdb_values); - goto error; - } - acdb_cache_rx[i].virt_addr_acdb_values = - acdb_cache_rx[i].map_v_addr; - memset(acdb_cache_rx[i].virt_addr_acdb_values, 0, - ACDB_BUF_SIZE); - } - return result; -error: - for (err = 0; err < i; err++) { - iounmap(acdb_cache_rx[err].map_v_addr); - free_contiguous_memory_by_paddr( - acdb_cache_rx[err].phys_addr_acdb_values); - } - return result; -} - -static u32 allocate_memory_acdb_get_blk(void) -{ - u32 result = 0; - acdb_data.get_blk_paddr = allocate_contiguous_ebi_nomap( - ACDB_BUF_SIZE, SZ_4K); - if (!acdb_data.get_blk_paddr) { - MM_ERR("ACDB=> Cannot allocate physical memory\n"); - result = -ENOMEM; - goto error; - } - acdb_data.map_v_get_blk = ioremap(acdb_data.get_blk_paddr, - ACDB_BUF_SIZE); - if (IS_ERR(acdb_data.map_v_get_blk)) { - MM_ERR("ACDB=> Could not map physical address\n"); - result = -ENOMEM; - free_contiguous_memory_by_paddr( - acdb_data.get_blk_paddr); - goto error; - } - acdb_data.get_blk_kvaddr = acdb_data.map_v_get_blk; - memset(acdb_data.get_blk_kvaddr, 0, ACDB_BUF_SIZE); -error: - return result; -} - -static void free_memory_acdb_cache_rx(void) -{ - u32 i = 0; - - for (i = 0; i < MAX_COPP_NODE_SUPPORTED; i++) { - iounmap(acdb_cache_rx[i].map_v_addr); - free_contiguous_memory_by_paddr( - acdb_cache_rx[i].phys_addr_acdb_values); - } -} - -static void free_memory_acdb_cache_tx(void) -{ - u32 i = 0; - - for (i = 0; i < MAX_AUDREC_SESSIONS; i++) { - iounmap(acdb_cache_tx[i].map_v_addr); - free_contiguous_memory_by_paddr( - acdb_cache_tx[i].phys_addr_acdb_values); - } -} - -static void free_memory_acdb_get_blk(void) -{ - iounmap(acdb_data.map_v_get_blk); - free_contiguous_memory_by_paddr(acdb_data.get_blk_paddr); -} - -static s32 initialize_memory(void) -{ - s32 result = 0; - - result = allocate_memory_acdb_get_blk(); - if (result < 0) { - MM_ERR("memory allocation for get blk failed\n"); - goto done; - } - - result = allocate_memory_acdb_cache_rx(); - if (result < 0) { - MM_ERR("memory allocation for rx cache is failed\n"); - free_memory_acdb_get_blk(); - goto done; - } - result = allocate_memory_acdb_cache_tx(); - if (result < 0) { - MM_ERR("memory allocation for tx cache is failed\n"); - free_memory_acdb_get_blk(); - free_memory_acdb_cache_rx(); - goto done; - } - acdb_data.pp_iir = kmalloc(sizeof(*acdb_data.pp_iir), - GFP_KERNEL); - if (acdb_data.pp_iir == NULL) { - MM_ERR("ACDB=> Could not allocate postproc iir memory\n"); - free_memory_acdb_get_blk(); - free_memory_acdb_cache_rx(); - free_memory_acdb_cache_tx(); - result = -ENOMEM; - goto done; - } - - acdb_data.pp_mbadrc = kmalloc(sizeof(*acdb_data.pp_mbadrc), GFP_KERNEL); - if (acdb_data.pp_mbadrc == NULL) { - MM_ERR("ACDB=> Could not allocate postproc mbadrc memory\n"); - free_memory_acdb_get_blk(); - free_memory_acdb_cache_rx(); - free_memory_acdb_cache_tx(); - kfree(acdb_data.pp_iir); - result = -ENOMEM; - goto done; - } - acdb_data.calib_gain_rx = kmalloc(sizeof(*acdb_data.calib_gain_rx), - GFP_KERNEL); - if (acdb_data.calib_gain_rx == NULL) { - MM_ERR("ACDB=> Could not allocate" - " postproc calib_gain_rx memory\n"); - free_memory_acdb_get_blk(); - free_memory_acdb_cache_rx(); - free_memory_acdb_cache_tx(); - kfree(acdb_data.pp_iir); - kfree(acdb_data.pp_mbadrc); - result = -ENOMEM; - goto done; - } - - acdb_data.preproc_agc = kmalloc(sizeof(*acdb_data.preproc_agc), - GFP_KERNEL); - if (acdb_data.preproc_agc == NULL) { - MM_ERR("ACDB=> Could not allocate preproc agc memory\n"); - free_memory_acdb_get_blk(); - free_memory_acdb_cache_rx(); - free_memory_acdb_cache_tx(); - kfree(acdb_data.pp_iir); - kfree(acdb_data.pp_mbadrc); - kfree(acdb_data.calib_gain_rx); - result = -ENOMEM; - goto done; - } - - acdb_data.preproc_iir = kmalloc(sizeof(*acdb_data.preproc_iir), - GFP_KERNEL); - if (acdb_data.preproc_iir == NULL) { - MM_ERR("ACDB=> Could not allocate preproc iir memory\n"); - free_memory_acdb_get_blk(); - free_memory_acdb_cache_rx(); - free_memory_acdb_cache_tx(); - kfree(acdb_data.pp_iir); - kfree(acdb_data.pp_mbadrc); - kfree(acdb_data.calib_gain_rx); - kfree(acdb_data.preproc_agc); - result = -ENOMEM; - goto done; - } - acdb_data.calib_gain_tx = kmalloc(sizeof(*acdb_data.calib_gain_tx), - GFP_KERNEL); - if (acdb_data.calib_gain_tx == NULL) { - MM_ERR("ACDB=> Could not allocate" - " preproc calib_gain_tx memory\n"); - free_memory_acdb_get_blk(); - free_memory_acdb_cache_rx(); - free_memory_acdb_cache_tx(); - kfree(acdb_data.pp_iir); - kfree(acdb_data.pp_mbadrc); - kfree(acdb_data.calib_gain_rx); - kfree(acdb_data.preproc_agc); - kfree(acdb_data.preproc_iir); - result = -ENOMEM; - goto done; - } - acdb_data.pbe_block = kmalloc(sizeof(*acdb_data.pbe_block), - GFP_KERNEL); - if (acdb_data.pbe_block == NULL) { - MM_ERR("ACDB=> Could not allocate pbe_block memory\n"); - free_memory_acdb_get_blk(); - free_memory_acdb_cache_rx(); - free_memory_acdb_cache_tx(); - kfree(acdb_data.pp_iir); - kfree(acdb_data.pp_mbadrc); - kfree(acdb_data.calib_gain_rx); - kfree(acdb_data.preproc_agc); - kfree(acdb_data.preproc_iir); - kfree(acdb_data.calib_gain_tx); - result = -ENOMEM; - goto done; - } - acdb_data.pbe_extbuff = (u16 *) allocate_contiguous_ebi_nomap( - PBE_BUF_SIZE, SZ_4K); - if (!acdb_data.pbe_extbuff) { - MM_ERR("ACDB=> Cannot allocate physical memory\n"); - free_memory_acdb_get_blk(); - free_memory_acdb_cache_rx(); - free_memory_acdb_cache_tx(); - kfree(acdb_data.pp_iir); - kfree(acdb_data.pp_mbadrc); - kfree(acdb_data.calib_gain_rx); - kfree(acdb_data.preproc_agc); - kfree(acdb_data.preproc_iir); - kfree(acdb_data.calib_gain_tx); - kfree(acdb_data.pbe_block); - result = -ENOMEM; - goto done; - } - acdb_data.fluence_extbuff = allocate_contiguous_ebi_nomap( - FLUENCE_BUF_SIZE, SZ_4K); - if (!acdb_data.fluence_extbuff) { - MM_ERR("ACDB=> cannot allocate physical memory for " - "fluence block\n"); - free_memory_acdb_get_blk(); - free_memory_acdb_cache_rx(); - free_memory_acdb_cache_tx(); - kfree(acdb_data.pp_iir); - kfree(acdb_data.pp_mbadrc); - kfree(acdb_data.calib_gain_rx); - kfree(acdb_data.preproc_agc); - kfree(acdb_data.preproc_iir); - kfree(acdb_data.calib_gain_tx); - kfree(acdb_data.pbe_block); - free_contiguous_memory_by_paddr((int32_t)acdb_data.pbe_extbuff); - result = -ENOMEM; - goto done; - } - acdb_data.map_v_fluence = ioremap( - acdb_data.fluence_extbuff, - FLUENCE_BUF_SIZE); - if (IS_ERR(acdb_data.map_v_fluence)) { - MM_ERR("ACDB=> Could not map physical address\n"); - free_memory_acdb_get_blk(); - free_memory_acdb_cache_rx(); - free_memory_acdb_cache_tx(); - kfree(acdb_data.pp_iir); - kfree(acdb_data.pp_mbadrc); - kfree(acdb_data.calib_gain_rx); - kfree(acdb_data.preproc_agc); - kfree(acdb_data.preproc_iir); - kfree(acdb_data.calib_gain_tx); - kfree(acdb_data.pbe_block); - free_contiguous_memory_by_paddr( - (int32_t)acdb_data.pbe_extbuff); - free_contiguous_memory_by_paddr( - (int32_t)acdb_data.fluence_extbuff); - result = -ENOMEM; - goto done; - } else - acdb_data.fluence_extbuff_virt = - acdb_data.map_v_fluence; -done: - return result; -} - -static u32 free_acdb_cache_node(union auddev_evt_data *evt) -{ - u32 session_id; - if ((evt->audcal_info.dev_type & TX_DEVICE) == 2) { - /*Second argument to find_first_bit should be maximum number - of bits interested - */ - session_id = find_first_bit( - (unsigned long *)&(evt->audcal_info.sessions), - sizeof(evt->audcal_info.sessions) * 8); - MM_DBG("freeing node %d for tx device", session_id); - acdb_cache_tx[session_id]. - node_status = ACDB_VALUES_NOT_FILLED; - } else { - MM_DBG("freeing rx cache node %d\n", - evt->audcal_info.dev_id); - acdb_cache_rx[evt->audcal_info.dev_id]. - node_status = ACDB_VALUES_NOT_FILLED; - } - return 0; -} - -static u8 check_device_change(struct auddev_evt_audcal_info audcal_info) -{ - if (!acdb_data.device_info) { - MM_ERR("not pointing to previous valid device detail\n"); - return 1; /*device info will not be pointing to*/ - /* valid device when acdb driver comes up*/ - } - if ((audcal_info.dev_id == acdb_data.device_info->dev_id) && - (audcal_info.sample_rate == - acdb_data.device_info->sample_rate) && - (audcal_info.acdb_id == acdb_data.device_info->acdb_id)) { - return 0; - } - return 1; -} - -static void device_cb(u32 evt_id, union auddev_evt_data *evt, void *private) -{ - struct auddev_evt_audcal_info audcal_info; - struct acdb_cache_node *acdb_cache_free_node = NULL; - u32 stream_id = 0; - u8 ret = 0; - u8 count = 0; - u8 i = 0; - u8 device_change = 0; - - if (!((evt_id == AUDDEV_EVT_DEV_RDY) || - (evt_id == AUDDEV_EVT_DEV_RLS))) { - goto done; - } - /*if session value is zero it indicates that device call back is for - voice call we will drop the request as acdb values for voice call is - not applied from acdb driver*/ - if (!evt->audcal_info.sessions) { - MM_DBG("no active sessions and call back is for" - " voice call\n"); - goto done; - } - if (evt_id == AUDDEV_EVT_DEV_RLS) { - MM_DBG("got release command for dev %d\n", - evt->audcal_info.dev_id); - acdb_data.acdb_state &= ~CAL_DATA_READY; - free_acdb_cache_node(evt); - /*reset the applied flag for the session routed to the device*/ - acdb_data.audrec_applied &= ~(evt->audcal_info.sessions - << AUDREC_OFFSET); - goto done; - } - if (((evt->audcal_info.dev_type & RX_DEVICE) == 1) && - (evt->audcal_info.acdb_id == PSEUDO_ACDB_ID)) { - MM_INFO("device cb is for rx device with pseudo acdb id\n"); - goto done; - } - audcal_info = evt->audcal_info; - MM_DBG("dev_id = %d\n", audcal_info.dev_id); - MM_DBG("sample_rate = %d\n", audcal_info.sample_rate); - MM_DBG("acdb_id = %d\n", audcal_info.acdb_id); - MM_DBG("sessions = %d\n", audcal_info.sessions); - MM_DBG("acdb_state = %x\n", acdb_data.acdb_state); - mutex_lock(&acdb_data.acdb_mutex); - device_change = check_device_change(audcal_info); - if (!device_change) { - if ((audcal_info.dev_type & TX_DEVICE) == 2) { - if (!(acdb_data.acdb_state & AUDREC0_READY)) - acdb_data.audrec_applied &= ~AUDREC0_READY; - if (!(acdb_data.acdb_state & AUDREC1_READY)) - acdb_data.audrec_applied &= ~AUDREC1_READY; - if (!(acdb_data.acdb_state & AUDREC2_READY)) - acdb_data.audrec_applied &= ~AUDREC2_READY; - acdb_data.acdb_state &= ~CAL_DATA_READY; - goto update_cache; - } - } else - /* state is updated to querry the modem for values */ - acdb_data.acdb_state &= ~CAL_DATA_READY; - -update_cache: - if ((audcal_info.dev_type & TX_DEVICE) == 2) { - /*loop is to take care of use case:- multiple Audrec - sessions are routed before enabling the device in this use - case we will get the sessions value as bits set for all the - sessions routed before device enable, so we should take care - of copying device info to all the sessions*/ - for (i = 0; i < MAX_AUDREC_SESSIONS; i++) { - stream_id = ((audcal_info.sessions >> i) & 0x01); - if (stream_id) { - acdb_cache_free_node = &acdb_cache_tx[i]; - ret = check_device_info_already_present( - audcal_info, - acdb_cache_free_node); - acdb_cache_free_node->stream_id = i; - acdb_data.cur_tx_session = i; - count++; - } - } - if (count > 1) - acdb_data.multiple_sessions = 1; - } else { - acdb_cache_free_node = &acdb_cache_rx[audcal_info.dev_id]; - ret = check_device_info_already_present(audcal_info, - acdb_cache_free_node); - if (ret == 1) { - MM_DBG("got device ready call back for another " - "audplay task sessions on same COPP\n"); - /*stream_id is used to keep track of number of active*/ - /*sessions active on this device*/ - acdb_cache_free_node->stream_id++; - mutex_unlock(&acdb_data.acdb_mutex); - goto done; - } - acdb_cache_free_node->stream_id++; - } - update_acdb_data_struct(acdb_cache_free_node); - acdb_data.device_cb_compl = 1; - mutex_unlock(&acdb_data.acdb_mutex); - wake_up(&acdb_data.wait); -done: - return; -} - - -static s32 register_device_cb(void) -{ - s32 result = 0; - - result = auddev_register_evt_listner((AUDDEV_EVT_DEV_RDY - | AUDDEV_EVT_DEV_RLS), - AUDDEV_CLNT_AUDIOCAL, 0, device_cb, (void *)&acdb_data); - - if (result) { - MM_ERR("ACDB=> Could not register device callback\n"); - result = -ENODEV; - goto done; - } -done: - return result; -} - -static void audpp_cb(void *private, u32 id, u16 *msg) -{ - MM_DBG("\n"); - if (id != AUDPP_MSG_CFG_MSG) - goto done; - - if (msg[0] == AUDPP_MSG_ENA_DIS) { - if (--acdb_cache_rx[acdb_data.\ - device_info->dev_id].stream_id <= 0) { - acdb_data.acdb_state &= ~AUDPP_READY; - acdb_cache_rx[acdb_data.device_info->dev_id]\ - .stream_id = 0; - MM_DBG("AUDPP_MSG_ENA_DIS\n"); - } - goto done; - } - - acdb_data.acdb_state |= AUDPP_READY; - acdb_data.audpp_cb_compl = 1; - wake_up(&acdb_data.wait); -done: - return; -} - -static s8 handle_audpreproc_cb(void) -{ - struct acdb_cache_node *acdb_cached_values; - s8 result = 0; - u8 stream_id = acdb_data.preproc_stream_id; - acdb_data.preproc_cb_compl = 0; - acdb_cached_values = get_acdb_values_from_cache_tx(stream_id); - if (acdb_cached_values == NULL) { - MM_DBG("ERROR: to get chached acdb values\n"); - return -EPERM; - } - update_acdb_data_struct(acdb_cached_values); - if (acdb_data.device_info->dev_id == PSEUDO_ACDB_ID) { - MM_INFO("audpreproc is routed to pseudo device\n"); - return result; - } - if (acdb_data.build_id[17] == '1') { - if (session_info[stream_id].sampling_freq) - acdb_data.device_info->sample_rate = - session_info[stream_id].sampling_freq; - } - if (!(acdb_data.acdb_state & CAL_DATA_READY)) { - result = check_tx_acdb_values_cached(); - if (result) { - result = acdb_get_calibration(); - if (result < 0) { - MM_ERR("failed to get calibration data\n"); - return result; - } - } - acdb_cached_values->node_status = ACDB_VALUES_FILLED; - } - return result; -} - -void fluence_feature_update(int enable, int stream_id) -{ - MM_INFO("Fluence feature over ride with = %d\n", enable); - acdb_data.fleuce_feature_status[stream_id] = enable; -} -EXPORT_SYMBOL(fluence_feature_update); - -static void audpreproc_cb(void *private, u32 id, void *msg) -{ - struct audpreproc_cmd_enc_cfg_done_msg *tmp; - u8 result = 0; - int stream_id = 0; - if (id != AUDPREPROC_CMD_ENC_CFG_DONE_MSG) - goto done; - - tmp = (struct audpreproc_cmd_enc_cfg_done_msg *)msg; - acdb_data.preproc_stream_id = tmp->stream_id; - stream_id = acdb_data.preproc_stream_id; - get_audrec_session_info(stream_id, &session_info[stream_id]); - MM_DBG("rec_enc_type = %x\n", tmp->rec_enc_type); - if ((tmp->rec_enc_type & 0x8000) == - AUD_PREPROC_CONFIG_DISABLED) { - if (acdb_data.preproc_stream_id == 0) { - acdb_data.acdb_state &= ~AUDREC0_READY; - acdb_data.audrec_applied &= ~AUDREC0_READY; - } else if (acdb_data.preproc_stream_id == 1) { - acdb_data.acdb_state &= ~AUDREC1_READY; - acdb_data.audrec_applied &= ~AUDREC1_READY; - } else if (acdb_data.preproc_stream_id == 2) { - acdb_data.acdb_state &= ~AUDREC2_READY; - acdb_data.audrec_applied &= ~AUDREC2_READY; - } - acdb_data.fleuce_feature_status[stream_id] = 0; - acdb_cache_tx[tmp->stream_id].node_status =\ - ACDB_VALUES_NOT_FILLED; - acdb_data.acdb_state &= ~CAL_DATA_READY; - goto done; - } - /*Following check is added to make sure that device info - is updated. audpre proc layer enabled without device - callback at this scenario we should not access - device information - */ - if (acdb_data.build_id[17] != '0') { - if (acdb_data.device_info && - session_info[stream_id].sampling_freq) { - acdb_data.device_info->sample_rate = - session_info[stream_id].sampling_freq; - result = check_tx_acdb_values_cached(); - if (!result) { - MM_INFO("acdb values for the stream is" \ - " querried from modem"); - acdb_data.acdb_state |= CAL_DATA_READY; - } else { - acdb_data.acdb_state &= ~CAL_DATA_READY; - } - } - } - if (acdb_data.preproc_stream_id == 0) - acdb_data.acdb_state |= AUDREC0_READY; - else if (acdb_data.preproc_stream_id == 1) - acdb_data.acdb_state |= AUDREC1_READY; - else if (acdb_data.preproc_stream_id == 2) - acdb_data.acdb_state |= AUDREC2_READY; - acdb_data.preproc_cb_compl = 1; - MM_DBG("acdb_data.acdb_state = %x\n", acdb_data.acdb_state); - wake_up(&acdb_data.wait); -done: - return; -} - -static s32 register_audpp_cb(void) -{ - s32 result = 0; - - acdb_data.audpp_cb.fn = audpp_cb; - acdb_data.audpp_cb.private = NULL; - result = audpp_register_event_callback(&acdb_data.audpp_cb); - if (result) { - MM_ERR("ACDB=> Could not register audpp callback\n"); - result = -ENODEV; - goto done; - } -done: - return result; -} - -static s32 register_audpreproc_cb(void) -{ - s32 result = 0; - - acdb_data.audpreproc_cb.fn = audpreproc_cb; - acdb_data.audpreproc_cb.private = NULL; - result = audpreproc_register_event_callback(&acdb_data.audpreproc_cb); - if (result) { - MM_ERR("ACDB=> Could not register audpreproc callback\n"); - result = -ENODEV; - goto done; - } - -done: - return result; -} - -static s32 acdb_initialize_data(void) -{ - s32 result = 0; - - mutex_init(&acdb_data.acdb_mutex); - - result = initialize_rpc(); - if (result) - goto err; - - result = initialize_memory(); - if (result) - goto err1; - - result = register_device_cb(); - if (result) - goto err2; - - result = register_audpp_cb(); - if (result) - goto err3; - - result = register_audpreproc_cb(); - if (result) - goto err4; - - - return result; - -err4: - result = audpreproc_unregister_event_callback(&acdb_data.audpreproc_cb); - if (result) - MM_ERR("ACDB=> Could not unregister audpreproc callback\n"); -err3: - result = audpp_unregister_event_callback(&acdb_data.audpp_cb); - if (result) - MM_ERR("ACDB=> Could not unregister audpp callback\n"); -err2: - result = auddev_unregister_evt_listner(AUDDEV_CLNT_AUDIOCAL, 0); - if (result) - MM_ERR("ACDB=> Could not unregister device callback\n"); -err1: - daldevice_detach(acdb_data.handle); - acdb_data.handle = NULL; -err: - return result; -} - -static s32 initialize_modem_acdb(void) -{ - struct acdb_cmd_init_adie acdb_cmd; - u8 codec_type = -1; - s32 result = 0; - u8 iterations = 0; - - codec_type = adie_get_detected_codec_type(); - if (codec_type == MARIMBA_ID) - acdb_cmd.adie_type = ACDB_CURRENT_ADIE_MODE_MARIMBA; - else if (codec_type == TIMPANI_ID) - acdb_cmd.adie_type = ACDB_CURRENT_ADIE_MODE_TIMPANI; - else - acdb_cmd.adie_type = ACDB_CURRENT_ADIE_MODE_UNKNOWN; - acdb_cmd.command_id = ACDB_CMD_INITIALIZE_FOR_ADIE; - do { - /*Initialize ACDB software on modem based on codec type*/ - result = dalrpc_fcn_8(ACDB_DalACDB_ioctl, acdb_data.handle, - (const void *)&acdb_cmd, sizeof(acdb_cmd), - &acdb_data.acdb_result, - sizeof(acdb_data.acdb_result)); - if (result < 0) { - MM_ERR("ACDB=> RPC failure result = %d\n", result); - goto error; - } - /*following check is introduced to handle boot up race - condition between AUDCAL SW peers running on apps - and modem (ACDB_RES_BADSTATE indicates modem AUDCAL SW is - not in initialized sate) we need to retry to get ACDB - initialized*/ - if (acdb_data.acdb_result.result == ACDB_RES_BADSTATE) { - msleep(500); - iterations++; - } else if (acdb_data.acdb_result.result == ACDB_RES_SUCCESS) { - MM_DBG("Modem ACDB SW initialized ((iterations = %d)\n", - iterations); - return result; - } else { - MM_ERR("ACDB=> Modem ACDB SW failed to initialize" - " reuslt = %d, (iterations = %d)\n", - acdb_data.acdb_result.result, - iterations); - goto error; - } - } while (iterations < MAX_RETRY); - MM_ERR("ACDB=> AUDCAL SW on modem is not in intiailized state (%d)\n", - acdb_data.acdb_result.result); -error: - result = -EINVAL; - return result; -} - -static s32 acdb_calibrate_device(void *data) -{ - s32 result = 0; - - /* initialize driver */ - result = acdb_initialize_data(); - if (result) - goto done; - if (acdb_data.build_id[17] != '0') { - result = initialize_modem_acdb(); - if (result < 0) - MM_ERR("failed to initialize modem ACDB\n"); - } - - while (!kthread_should_stop()) { - MM_DBG("Waiting for call back events\n"); - wait_event_interruptible(acdb_data.wait, - (acdb_data.device_cb_compl - | acdb_data.audpp_cb_compl - | acdb_data.preproc_cb_compl)); - mutex_lock(&acdb_data.acdb_mutex); - if (acdb_data.device_cb_compl) { - acdb_data.device_cb_compl = 0; - if (!(acdb_data.acdb_state & CAL_DATA_READY)) { - if ((acdb_data.device_info->dev_type - & RX_DEVICE) == 1) { - /*we need to get calibration values - only for RX device as resampler - moved to start of the pre - proc chain - tx calibration value will be based on - sampling frequency what audrec is - configured, calibration values for tx - device are fetch in audpreproc - callback*/ - result = acdb_get_calibration(); - if (result < 0) { - mutex_unlock( - &acdb_data.acdb_mutex); - MM_ERR("Not able to get " - "calibration " - "data continue\n"); - continue; - } - } - } - MM_DBG("acdb state = %d\n", - acdb_data.acdb_state); - if ((acdb_data.device_info->dev_type & TX_DEVICE) == 2) - handle_tx_device_ready_callback(); - else { - acdb_cache_rx[acdb_data.device_info->dev_id]\ - .node_status = - ACDB_VALUES_FILLED; - if (acdb_data.acdb_state & - AUDPP_READY) { - MM_DBG("AUDPP already enabled " - "apply acdb values\n"); - goto apply; - } - } - } - - if (!(acdb_data.audpp_cb_compl || - acdb_data.preproc_cb_compl)) { - MM_DBG("need to wait for either AUDPP / AUDPREPROC " - "Event\n"); - mutex_unlock(&acdb_data.acdb_mutex); - continue; - } else { - MM_DBG("got audpp / preproc call back\n"); - if (acdb_data.audpp_cb_compl) { - send_acdb_values_for_active_devices(); - acdb_data.audpp_cb_compl = 0; - mutex_unlock(&acdb_data.acdb_mutex); - continue; - } else { - result = handle_audpreproc_cb(); - if (result < 0) { - mutex_unlock(&acdb_data.acdb_mutex); - continue; - } - } - } -apply: - if (acdb_data.acdb_state & CAL_DATA_READY) - result = acdb_send_calibration(); - - mutex_unlock(&acdb_data.acdb_mutex); - } -done: - return 0; -} - -static int __init acdb_init(void) -{ - - s32 result = 0; - - memset(&acdb_data, 0, sizeof(acdb_data)); - spin_lock_init(&acdb_data.dsp_lock); - acdb_data.cb_thread_task = kthread_run(acdb_calibrate_device, - NULL, "acdb_cb_thread"); - - if (IS_ERR(acdb_data.cb_thread_task)) { - MM_ERR("ACDB=> Could not register cb thread\n"); - result = -ENODEV; - goto err; - } - - acdb_data.build_id = socinfo_get_build_id(); - MM_INFO("build id used is = %s\n", acdb_data.build_id); - -#ifdef CONFIG_DEBUG_FS - /*This is RTC specific INIT used only with debugfs*/ - if (!rtc_acdb_init()) - MM_ERR("RTC ACDB=>INIT Failure\n"); - -#endif - init_waitqueue_head(&acdb_data.wait); - - return misc_register(&acdb_misc); -err: - return result; -} - -static void __exit acdb_exit(void) -{ - s32 result = 0; - u32 i = 0; - - result = auddev_unregister_evt_listner(AUDDEV_CLNT_AUDIOCAL, 0); - if (result) - MM_ERR("ACDB=> Could not unregister device callback\n"); - - result = audpp_unregister_event_callback(&acdb_data.audpp_cb); - if (result) - MM_ERR("ACDB=> Could not unregister audpp callback\n"); - - result = audpreproc_unregister_event_callback(&acdb_data.\ - audpreproc_cb); - if (result) - MM_ERR("ACDB=> Could not unregister audpreproc callback\n"); - - result = kthread_stop(acdb_data.cb_thread_task); - if (result) - MM_ERR("ACDB=> Could not stop kthread\n"); - - free_memory_acdb_get_blk(); - - for (i = 0; i < MAX_COPP_NODE_SUPPORTED; i++) { - if (i < MAX_AUDREC_SESSIONS) { - iounmap(acdb_cache_tx[i].map_v_addr); - free_contiguous_memory_by_paddr( - acdb_cache_tx[i].phys_addr_acdb_values); - } - iounmap(acdb_cache_rx[i].map_v_addr); - free_contiguous_memory_by_paddr( - acdb_cache_rx[i].phys_addr_acdb_values); - } - kfree(acdb_data.device_info); - kfree(acdb_data.pp_iir); - kfree(acdb_data.pp_mbadrc); - kfree(acdb_data.preproc_agc); - kfree(acdb_data.preproc_iir); - free_contiguous_memory_by_paddr( - (int32_t)acdb_data.pbe_extbuff); - iounmap(acdb_data.map_v_fluence); - free_contiguous_memory_by_paddr( - (int32_t)acdb_data.fluence_extbuff); - mutex_destroy(&acdb_data.acdb_mutex); - memset(&acdb_data, 0, sizeof(acdb_data)); - #ifdef CONFIG_DEBUG_FS - rtc_acdb_deinit(); - #endif -} - -late_initcall(acdb_init); -module_exit(acdb_exit); - -MODULE_DESCRIPTION("MSM 7x30 Audio ACDB driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c b/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c deleted file mode 100644 index 7cc3e29f394cdb40168253b36da3b473c11c1fb3..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c +++ /dev/null @@ -1,1754 +0,0 @@ -/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. - * - * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * - * All source code in this file is licensed under the following license except - * where indicated. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* Size must be power of 2 */ -#define BUFSZ_MAX 32768 /* Includes meta in size */ -#define BUFSZ_MIN 4096 /* Includes meta in size */ -#define DMASZ_MAX (BUFSZ_MAX * 2) -#define DMASZ_MIN (BUFSZ_MIN * 2) - -#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF -#define AUDDEC_DEC_ADPCM 1 - -#define PCM_BUFSZ_MIN 8216 /* Hold one stereo ADPCM frame and meta out*/ -#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most - but support 2 buffers currently */ -#define ROUTING_MODE_FTRT 1 -#define ROUTING_MODE_RT 2 -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDADPCM_METAFIELD_MASK 0xFFFF0000 -#define AUDADPCM_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */ -#define AUDADPCM_EOS_FLG_MASK 0x01 -#define AUDADPCM_EOS_NONE 0x0 /* No EOS detected */ -#define AUDADPCM_EOS_SET 0x1 /* EOS set in meta field */ - -#define AUDADPCM_EVENT_NUM 10 /* Default no. of pre-allocated event packets */ - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; - unsigned short mfield_sz; /*only useful for data has meta field */ -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audadpcm_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct audadpcm_event{ - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audio { - struct buffer out[2]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - unsigned out_dma_sz; - - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - /* Host PCM section */ - struct buffer in[PCM_BUF_MAX_COUNT]; - struct mutex read_lock; - wait_queue_head_t read_wait; /* Wait queue for read */ - char *read_data; /* pointer to reader buffer */ - int32_t read_phys; /* physical address of reader buffer */ - uint8_t read_next; /* index to input buffers to be read next */ - uint8_t fill_next; /* index to buffer that DSP should be filling */ - uint8_t pcm_buf_count; /* number of pcm buffer allocated */ - /* ---- End of Host PCM section */ - - struct msm_adsp_module *audplay; - - /* configuration to use on next enable */ - uint32_t out_sample_rate; - uint32_t out_channel_mode; - uint32_t out_block_size; - - /* data allocated for various buffers */ - char *data; - int32_t phys; /* physical address of write buffer */ - void *map_v_read; - void *map_v_write; - int mfield; /* meta field embedded in data */ - int rflush; /* Read flush */ - int wflush; /* Write flush */ - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - int pcm_feedback; - int buf_refresh; - int teos; /* valid only if tunnel mode & no data left for decoder */ - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - int reserved; /* A byte is being reserved */ - char rsv_byte; /* Handle odd length user data */ - - const char *module_name; - unsigned queue_id; - uint16_t dec_id; - uint32_t read_ptr_offset; - int16_t source; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audadpcm_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - /* AV sync Info */ - int avsync_flag; /* Flag to indicate feedback from DSP */ - wait_queue_head_t avsync_wait;/* Wait queue for AV Sync Message */ - /* flags, 48 bits sample/bytes counter per channel */ - uint16_t avsync[AUDPP_AVSYNC_CH_COUNT * AUDPP_AVSYNC_NUM_WORDS + 1]; - uint32_t device_events; - - int eq_enable; - int eq_needs_commit; - struct audpp_cmd_cfg_object_params_eqalizer eq; - struct audpp_cmd_cfg_object_params_volume vol_pan; -}; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audpp_cmd_cfg_adec_params(struct audio *audio); -static void audpp_cmd_cfg_routing_mode(struct audio *audio); -static void audplay_send_data(struct audio *audio, unsigned needed); -static void audplay_config_hostpcm(struct audio *audio); -static void audplay_buffer_refresh(struct audio *audio); -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg); -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audadpcm_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); -#endif - -/* must be called with audio->lock held */ -static int audio_enable(struct audio *audio) -{ - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) - return 0; - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_tail = 0; - audio->out_needed = 0; - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - return -ENODEV; - } - - audio->enabled = 1; - return 0; -} - -static void adpcm_listner(u32 evt_id, union auddev_evt_data *evt_payload, - void *private_data) -{ - struct audio *audio = (struct audio *) private_data; - switch (evt_id) { - case AUDDEV_EVT_DEV_RDY: - MM_DBG(":AUDDEV_EVT_DEV_RDY\n"); - audio->source |= (0x1 << evt_payload->routing_id); - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - break; - case AUDDEV_EVT_DEV_RLS: - MM_DBG(":AUDDEV_EVT_DEV_RLS\n"); - if (audio->dec_state == MSM_AUD_DECODER_STATE_SUCCESS && - audio->enabled == 1) - audpp_route_stream(audio->dec_id, - msm_snddev_route_dec(audio->dec_id)); - break; - case AUDDEV_EVT_STREAM_VOL_CHG: - audio->vol_pan.volume = evt_payload->session_vol; - MM_DBG(":AUDDEV_EVT_STREAM_VOL_CHG, stream vol %d\n", - audio->vol_pan.volume); - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - break; - default: - MM_ERR(":ERROR:wrong event\n"); - break; - } -} -/* must be called with audio->lock held */ -static int audio_disable(struct audio *audio) -{ - int rc = 0; - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - wake_up(&audio->write_wait); - wake_up(&audio->read_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - audio->out_needed = 0; - } - return rc; -} - -/* ------------------- dsp --------------------- */ -static void audio_update_pcm_buf_entry(struct audio *audio, - uint32_t *payload) -{ - uint8_t index; - unsigned long flags; - - if (audio->rflush) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < payload[1]; index++) { - if (audio->in[audio->fill_next].addr == - payload[2 + index * 2]) { - MM_DBG("audio_update_pcm_buf_entry: \ - in[%d] ready\n", audio->fill_next); - audio->in[audio->fill_next].used = - payload[3 + index * 2]; - if ((++audio->fill_next) == audio->pcm_buf_count) - audio->fill_next = 0; - } else { - MM_ERR("audio_update_pcm_buf_entry: \ - expected=%x ret=%x\n", - audio->in[audio->fill_next].addr, - payload[1 + index * 2]); - break; - } - } - if (audio->in[audio->fill_next].used == 0) { - audplay_buffer_refresh(audio); - } else { - MM_DBG("read cannot keep up\n"); - audio->buf_refresh = 1; - } - wake_up(&audio->read_wait); - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - - getevent(msg, sizeof(msg)); - - MM_DBG("msg_id=%x\n", id); - - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audplay_send_data(audio, 1); - break; - - case AUDPLAY_MSG_BUFFER_UPDATE: - audio_update_pcm_buf_entry(audio, msg); - break; - - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audplaytask)\n"); - break; - - default: - MM_ERR("unexpected message from decoder \n"); - break; - } -} - -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status:sleep reason = \ - 0x%04x\n", reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init\n"); - if (audio->pcm_feedback) - audpp_cmd_cfg_routing_mode(audio); - else - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg\n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play \n"); - /* send mixer command */ - audpp_route_stream(audio->dec_id, - audio->source); - if (audio->pcm_feedback) { - audplay_config_hostpcm(audio); - audplay_buffer_refresh(audio); - } - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - default: - MM_ERR("unknown decoder status\n"); - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - audpp_dsp_set_eq(audio->dec_id, audio->eq_enable, - &audio->eq, POPP); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audio->running = 0; - } else { - MM_DBG("CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_ROUTING_ACK: - MM_DBG("ROUTING_ACK mode=%d\n", msg[1]); - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - audio->rflush = 0; - wake_up(&audio->write_wait); - if (audio->pcm_feedback) - audplay_buffer_refresh(audio); - break; - - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - - case AUDPP_MSG_AVSYNC_MSG: - MM_DBG("AUDPP_MSG_AVSYNC_MSG\n"); - memcpy(&audio->avsync[0], msg, sizeof(audio->avsync)); - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); - break; - - default: - MM_ERR("UNKNOWN (%d)\n", id); - } - -} - -static struct msm_adsp_ops audplay_adsp_ops_adpcm = { - .event = audplay_dsp_event, -}; - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id, \ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - struct audpp_cmd_cfg_dec_type cfg_dec_cmd; - - memset(&cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - - cfg_dec_cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE; - if (enable) - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_ADPCM; - else - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - cfg_dec_cmd.dm_mode = 0x0; - cfg_dec_cmd.stream_id = audio->dec_id; - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} - -static void audpp_cmd_cfg_adec_params(struct audio *audio) -{ - struct audpp_cmd_cfg_adec_params_adpcm cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_ADPCM_LEN; - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = audio->out_sample_rate; - - cmd.stereo_cfg = audio->out_channel_mode; - cmd.block_size = audio->out_block_size; - - audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static void audpp_cmd_cfg_routing_mode(struct audio *audio) -{ - struct audpp_cmd_routing_mode cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; - cmd.object_number = audio->dec_id; - if (audio->pcm_feedback) - cmd.routing_mode = ROUTING_MODE_FTRT; - else - cmd.routing_mode = ROUTING_MODE_RT; - - audpp_send_queue1(&cmd, sizeof(cmd)); -} - -static void audplay_buffer_refresh(struct audio *audio) -{ - struct audplay_cmd_buffer_refresh refresh_cmd; - - refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; - refresh_cmd.num_buffers = 1; - refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; - refresh_cmd.buf0_length = audio->in[audio->fill_next].size; - refresh_cmd.buf_read_count = 0; - - MM_DBG("buf0_addr=%x buf0_len=%d\n", - refresh_cmd.buf0_address, - refresh_cmd.buf0_length); - - (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); -} - -static void audplay_config_hostpcm(struct audio *audio) -{ - struct audplay_cmd_hpcm_buf_cfg cfg_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; - cfg_cmd.max_buffers = audio->pcm_buf_count; - cfg_cmd.byte_swap = 0; - cfg_cmd.hostpcm_config = (0x8000) | (0x4000); - cfg_cmd.feedback_frequency = 1; - cfg_cmd.partition_number = 0; - - (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); -} - - -static int audplay_dsp_send_data_avail(struct audio *audio, - unsigned idx, unsigned len) -{ - struct audplay_cmd_bitstream_data_avail_nt2 cmd; - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2; - if (audio->mfield) - cmd.decoder_id = AUDADPCM_METAFIELD_MASK | - (audio->out[idx].mfield_sz >> 1); - else - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = audio->out[idx].addr; - cmd.buf_size = len/2; - cmd.partition_number = 0; - return audplay_send_queue0(audio, &cmd, sizeof(cmd)); -} - -static void audplay_send_data(struct audio *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (audio->wflush) { - audio->out_needed = 1; - goto done; - } - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - MM_DBG("\n"); /* Macro prints the file name and function */ - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - MM_DBG("frame %d busy\n", audio->out_tail); - audplay_dsp_send_data_avail(audio, audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } -done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ - -static void audio_flush(struct audio *audio) -{ - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->reserved = 0; - atomic_set(&audio->out_bytes, 0); -} - -static void audio_flush_pcm_buf(struct audio *audio) -{ - uint8_t index; - - for (index = 0; index < PCM_BUF_MAX_COUNT; index++) - audio->in[index].used = 0; - audio->buf_refresh = 0; - audio->read_next = 0; - audio->fill_next = 0; -} - -static void audio_ioport_reset(struct audio *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audio_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->read_wait); - mutex_lock(&audio->read_lock); - audio_flush_pcm_buf(audio); - mutex_unlock(&audio->read_lock); - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); -} - -static int audadpcm_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audadpcm_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audadpcm_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audadpcm_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audadpcm_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - -static long audadpcm_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audadpcm_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - audio->event_wait, audadpcm_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audadpcm_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - rc = 0; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audadpcm_event, list); - list_del(&drv_evt->list); - } - - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audio_enable_eq(struct audio *audio, int enable) -{ - if (audio->eq_enable == enable && !audio->eq_needs_commit) - return 0; - - audio->eq_enable = enable; - - if (audio->running) { - audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq, POPP); - audio->eq_needs_commit = 0; - } - return 0; -} - -static int audio_get_avsync_data(struct audio *audio, - struct msm_audio_stats *stats) -{ - int rc = -EINVAL; - unsigned long flags; - - local_irq_save(flags); - if (audio->dec_id == audio->avsync[0] && audio->avsync_flag) { - /* av_sync sample count */ - stats->sample_count = (audio->avsync[2] << 16) | - (audio->avsync[3]); - - /* av_sync byte_count */ - stats->byte_count = (audio->avsync[5] << 16) | - (audio->avsync[6]); - - audio->avsync_flag = 0; - rc = 0; - } - local_irq_restore(flags); - return rc; - -} - -static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - unsigned long flags = 0; - uint16_t enable_mask; - int enable; - int prev_state; - - MM_DBG("cmd = %d\n", cmd); - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - - audio->avsync_flag = 0; - memset(&stats, 0, sizeof(stats)); - if (audpp_query_avsync(audio->dec_id) < 0) - return rc; - - rc = wait_event_interruptible_timeout(audio->avsync_wait, - (audio->avsync_flag == 1), - msecs_to_jiffies(AUDPP_AVSYNC_EVENT_TIMEOUT)); - - if (rc < 0) - return rc; - else if ((rc > 0) || ((rc == 0) && (audio->avsync_flag == 1))) { - if (audio_get_avsync_data(audio, &stats) < 0) - return rc; - - if (copy_to_user((void *)arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } else - return -EAGAIN; - } - - switch (cmd) { - case AUDIO_ENABLE_AUDPP: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - spin_lock_irqsave(&audio->dsp_lock, flags); - enable = (enable_mask & EQ_ENABLE) ? 1 : 0; - audio_enable_eq(audio, enable); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - case AUDIO_SET_VOLUME: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.volume = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_PAN: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.pan = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_EQ: - prev_state = audio->eq_enable; - audio->eq_enable = 0; - if (copy_from_user(&audio->eq.num_bands, (void *) arg, - sizeof(audio->eq) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) { - rc = -EFAULT; - break; - } - audio->eq_enable = prev_state; - audio->eq_needs_commit = 1; - rc = 0; - break; - } - - if (-EINVAL != rc) - return rc; - - if (cmd == AUDIO_GET_EVENT) { - MM_DBG("AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audadpcm_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audio_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) - rc = -ENODEV; - else - rc = 0; - } - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audio_disable(audio); - audio->stopped = 1; - audio_ioport_reset(audio); - audio->stopped = 0; - break; - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audio_ioport_reset(audio); - if (audio->running) { - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - case AUDIO_SET_CONFIG: { - struct msm_audio_config config; - if (copy_from_user(&config, (void *) arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.channel_count == 1) { - config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V; - } else if (config.channel_count == 2) { - config.channel_count = AUDPP_CMD_PCM_INTF_STEREO_V; - } else { - rc = -EINVAL; - break; - } - audio->mfield = config.meta_field; - audio->out_sample_rate = config.sample_rate; - audio->out_channel_mode = config.channel_count; - audio->out_block_size = config.bits; - rc = 0; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config config; - config.buffer_size = (audio->out_dma_sz >> 1); - config.buffer_count = 2; - config.sample_rate = audio->out_sample_rate; - if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) - config.channel_count = 1; - else - config.channel_count = 2; - config.meta_field = 0; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *) arg, &config, sizeof(config))) - rc = -EFAULT; - else - rc = 0; - - break; - } - case AUDIO_GET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - config.pcm_feedback = audio->pcm_feedback; - config.buffer_count = PCM_BUF_MAX_COUNT; - config.buffer_size = PCM_BUFSZ_MIN; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.pcm_feedback != audio->pcm_feedback) { - MM_ERR("Not sufficient permission to" - "change the playback mode\n"); - rc = -EACCES; - break; - } - if ((config.buffer_count > PCM_BUF_MAX_COUNT) || - (config.buffer_count == 1)) - config.buffer_count = PCM_BUF_MAX_COUNT; - - if (config.buffer_size < PCM_BUFSZ_MIN) - config.buffer_size = PCM_BUFSZ_MIN; - - /* Check if pcm feedback is required */ - if ((config.pcm_feedback) && (!audio->read_data)) { - MM_DBG("allocate PCM buffer %d\n", - config.buffer_count * - config.buffer_size); - audio->read_phys = - allocate_contiguous_ebi_nomap( - config.buffer_size * - config.buffer_count, - SZ_4K); - if (!audio->read_phys) { - rc = -ENOMEM; - break; - } - audio->map_v_read = ioremap( - audio->read_phys, - config.buffer_size * - config.buffer_count); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("read buf map fail\n"); - rc = -ENOMEM; - free_contiguous_memory_by_paddr( - audio->read_phys); - } else { - uint8_t index; - uint32_t offset = 0; - audio->read_data = - audio->map_v_read; - audio->buf_refresh = 0; - audio->pcm_buf_count = - config.buffer_count; - audio->read_next = 0; - audio->fill_next = 0; - - for (index = 0; - index < config.buffer_count; - index++) { - audio->in[index].data = - audio->read_data + offset; - audio->in[index].addr = - audio->read_phys + offset; - audio->in[index].size = - config.buffer_size; - audio->in[index].used = 0; - offset += config.buffer_size; - } - MM_DBG("read buf: phy addr \ - 0x%08x kernel addr 0x%08x\n", - audio->read_phys, - (int)audio->read_data); - rc = 0; - } - } else { - rc = 0; - } - break; - } - case AUDIO_PAUSE: - MM_DBG("AUDIO_PAUSE %ld\n", arg); - rc = audpp_pause(audio->dec_id, (int) arg); - break; - case AUDIO_GET_SESSION_ID: - if (copy_to_user((void *) arg, &audio->dec_id, - sizeof(unsigned short))) - rc = -EFAULT; - else - rc = 0; - break; - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -static int audio_fsync(struct file *file, loff_t ppos1, loff_t ppos2, int datasync) -{ - struct audio *audio = file->private_data; - struct buffer *frame; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (!audio->running || audio->pcm_feedback) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (audio->reserved) { - MM_DBG("send reserved byte\n"); - frame = audio->out + audio->out_tail; - ((char *) frame->data)[0] = audio->rsv_byte; - ((char *) frame->data)[1] = 0; - frame->used = 2; - audplay_send_data(audio, 0); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - } - - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush); - - if (audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; -} - -static ssize_t audio_read(struct file *file, char __user *buf, size_t count, - loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - int rc = 0; - - if (!audio->pcm_feedback) - return 0; /* PCM feedback is not enabled. Nothing to read */ - - mutex_lock(&audio->read_lock); - MM_DBG("%d \n", count); - while (count > 0) { - rc = wait_event_interruptible(audio->read_wait, - (audio->in[audio->read_next].used > 0) || - (audio->stopped) || (audio->rflush)); - - if (rc < 0) - break; - - if (audio->stopped || audio->rflush) { - rc = -EBUSY; - break; - } - - if (count < audio->in[audio->read_next].used) { - /* Read must happen in frame boundary. Since driver - does not know frame size, read count must be greater - or equal to size of PCM samples */ - MM_DBG("audio_read: no partial frame done reading\n"); - break; - } else { - MM_DBG("audio_read: read from in[%d]\n", - audio->read_next); - if (copy_to_user - (buf, audio->in[audio->read_next].data, - audio->in[audio->read_next].used)) { - MM_ERR("invalid addr %x \n", (unsigned int)buf); - rc = -EFAULT; - break; - } - count -= audio->in[audio->read_next].used; - buf += audio->in[audio->read_next].used; - audio->in[audio->read_next].used = 0; - if ((++audio->read_next) == audio->pcm_buf_count) - audio->read_next = 0; - break; /* Force to exit while loop - * to prevent output thread - * sleep too long if data is - * not ready at this moment. - */ - } - } - - /* don't feed output buffer to HW decoder during flushing - * buffer refresh command will be sent once flush completes - * send buf refresh command here can confuse HW decoder - */ - if (audio->buf_refresh && !audio->rflush) { - audio->buf_refresh = 0; - MM_DBG("kick start pcm feedback again\n"); - audplay_buffer_refresh(audio); - } - - mutex_unlock(&audio->read_lock); - - if (buf > start) - rc = buf - start; - - MM_DBG("read %d bytes\n", rc); - return rc; -} - -static int audadpcm_process_eos(struct audio *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - int rc = 0; - struct buffer *frame; - char *buf_ptr; - - if (audio->reserved) { - MM_DBG("flush reserve byte\n"); - frame = audio->out + audio->out_head; - buf_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - buf_ptr[0] = audio->rsv_byte; - buf_ptr[1] = 0; - audio->out_head ^= 1; - frame->mfield_sz = 0; - frame->used = 2; - audio->reserved = 0; - audplay_send_data(audio, 0); - } - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - audplay_send_data(audio, 0); -done: - return rc; -} - -static ssize_t audio_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - char *cpy_ptr; - int rc = 0, eos_condition = AUDADPCM_EOS_NONE; - unsigned dsize; - unsigned short mfield_size = 0; - - MM_DBG("cnt=%d\n", count); - - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - cpy_ptr = frame->data; - dsize = 0; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - break; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - break; - } - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - break; - } else if (mfield_size > count) { - rc = -EINVAL; - break; - } - MM_DBG("audio_write: mf offset_val %x\n", - mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - break; - } - /* Check if EOS flag is set and buffer has - * contains just meta field - */ - if (cpy_ptr[AUDADPCM_EOS_FLG_OFFSET] & - AUDADPCM_EOS_FLG_MASK) { - MM_DBG("audio_write: EOS SET\n"); - eos_condition = AUDADPCM_EOS_SET; - if (mfield_size == count) { - buf += mfield_size; - break; - } else - cpy_ptr[AUDADPCM_EOS_FLG_OFFSET] - &= ~AUDADPCM_EOS_FLG_MASK; - } - cpy_ptr += mfield_size; - count -= mfield_size; - dsize += mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("audio_write: continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - - if (audio->reserved) { - MM_DBG("append reserved byte %x\n", audio->rsv_byte); - *cpy_ptr = audio->rsv_byte; - xfer = (count > ((frame->size - mfield_size) - 1)) ? - (frame->size - mfield_size) - 1 : count; - cpy_ptr++; - dsize += 1; - audio->reserved = 0; - } else - xfer = (count > (frame->size - mfield_size)) ? - (frame->size - mfield_size) : count; - - if (copy_from_user(cpy_ptr, buf, xfer)) { - rc = -EFAULT; - break; - } - - dsize += xfer; - if (dsize & 1) { - audio->rsv_byte = ((char *) frame->data)[dsize - 1]; - MM_DBG("odd length buf reserve last byte %x\n", - audio->rsv_byte); - audio->reserved = 1; - dsize--; - } - count -= xfer; - buf += xfer; - - if (dsize > 0) { - audio->out_head ^= 1; - frame->used = dsize; - audplay_send_data(audio, 0); - } - } - if (eos_condition == AUDADPCM_EOS_SET) - rc = audadpcm_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - if (!rc) { - if (buf > start) - return buf - start; - } - return rc; -} - -static int audio_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_INFO("audio instance 0x%08x freeing\n", (int)audio); - - mutex_lock(&audio->lock); - auddev_unregister_evt_listner(AUDDEV_CLNT_DEC, audio->dec_id); - audio_disable(audio); - audio_flush(audio); - audio_flush_pcm_buf(audio); - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->event_abort = 1; - wake_up(&audio->event_wait); - audadpcm_reset_event_queue(audio); - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - if (audio->read_data) { - iounmap(audio->map_v_read); - free_contiguous_memory_by_paddr(audio->read_phys); - } - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - kfree(audio); - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audadpcm_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audadpcm_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audadpcm_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audadpcm_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -static void audadpcm_suspend(struct early_suspend *h) -{ - struct audadpcm_suspend_ctl *ctl = - container_of(h, struct audadpcm_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audadpcm_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audadpcm_resume(struct early_suspend *h) -{ - struct audadpcm_suspend_ctl *ctl = - container_of(h, struct audadpcm_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audadpcm_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audadpcm_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audadpcm_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 4096; - static char buffer[4096]; - int n = 0, i; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_feedback %d\n", audio->pcm_feedback); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_buf_sz %d\n", audio->out[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_count %d \n", audio->pcm_buf_count); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_sz %d \n", audio->in[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %x \n", audio->vol_pan.volume); - n += scnprintf(buffer + n, debug_bufmax - n, - "sample rate %d \n", audio->out_sample_rate); - n += scnprintf(buffer + n, debug_bufmax - n, - "channel mode %d \n", audio->out_channel_mode); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "rflush %d\n", audio->rflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d \n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d \n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d \n", audio->out_needed); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_head %d \n", audio->out_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_tail %d \n", audio->out_tail); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[0].used %d \n", audio->out[0].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[1].used %d \n", audio->out[1].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "buffer_refresh %d \n", audio->buf_refresh); - n += scnprintf(buffer + n, debug_bufmax - n, - "read_next %d \n", audio->read_next); - n += scnprintf(buffer + n, debug_bufmax - n, - "fill_next %d \n", audio->fill_next); - for (i = 0; i < audio->pcm_buf_count; i++) - n += scnprintf(buffer + n, debug_bufmax - n, - "in[%d].size %d \n", i, audio->in[i].used); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audadpcm_debug_fops = { - .read = audadpcm_debug_read, - .open = audadpcm_debug_open, -}; -#endif - -static int audio_open(struct inode *inode, struct file *file) -{ - struct audio *audio = NULL; - int rc, dec_attrb, decid, i; - unsigned pmem_sz = DMASZ_MAX; - struct audadpcm_event *e_node = NULL; -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_adpcm_" + 5]; -#endif - - /* Allocate Mem for audio instance */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("no memory to allocate audio instance \n"); - rc = -ENOMEM; - goto done; - } - MM_INFO("audio instance 0x%08x created\n", (int)audio); - - /* Allocate the decoder */ - dec_attrb = AUDDEC_DEC_ADPCM; - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_NONTUNNEL; - audio->pcm_feedback = NON_TUNNEL_MODE_PLAYBACK; - } else if ((file->f_mode & FMODE_WRITE) && - !(file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_TUNNEL; - audio->pcm_feedback = TUNNEL_MODE_PLAYBACK; - } else { - kfree(audio); - rc = -EACCES; - goto done; - } - - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - - if (decid < 0) { - MM_ERR("No free decoder available, freeing instance 0x%08x\n", - (int)audio); - rc = -ENODEV; - kfree(audio); - goto done; - } - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - while (pmem_sz >= DMASZ_MIN) { - MM_DBG("pmemsz = %d\n", pmem_sz); - audio->phys = allocate_contiguous_ebi_nomap(pmem_sz, - SZ_4K); - if (audio->phys) { - audio->map_v_write = ioremap(audio->phys, pmem_sz); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write phys address, \ - freeing instance 0x%08x\n", - (int)audio); - rc = -ENOMEM; - free_contiguous_memory_by_paddr(audio->phys); - audpp_adec_free(audio->dec_id); - kfree(audio); - goto done; - } - audio->data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr \ - 0x%08x\n", audio->phys, (int)audio->data); - break; - } else if (pmem_sz == DMASZ_MIN) { - MM_ERR("could not allocate write buffers, freeing \ - instance 0x%08x\n", (int)audio); - rc = -ENOMEM; - audpp_adec_free(audio->dec_id); - kfree(audio); - goto done; - } else - pmem_sz >>= 1; - } - audio->out_dma_sz = pmem_sz; - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audplay_adsp_ops_adpcm, audio); - if (rc) { - MM_ERR("failed to get %s module, freeing instance 0x%08x\n", - audio->module_name, (int)audio); - goto err; - } - - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->read_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - init_waitqueue_head(&audio->write_wait); - init_waitqueue_head(&audio->read_wait); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - spin_lock_init(&audio->event_queue_lock); - init_waitqueue_head(&audio->avsync_wait); - - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = audio->out_dma_sz >> 1; - - audio->out[1].data = audio->data + audio->out[0].size; - audio->out[1].addr = audio->phys + audio->out[0].size; - audio->out[1].size = audio->out[0].size; - - audio->out_sample_rate = 44100; - audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V; - - audio->vol_pan.volume = 0x2000; - - audio_flush(audio); - - file->private_data = audio; - audio->opened = 1; - - audio->device_events = AUDDEV_EVT_DEV_RDY - |AUDDEV_EVT_DEV_RLS| - AUDDEV_EVT_STREAM_VOL_CHG; - - rc = auddev_register_evt_listner(audio->device_events, - AUDDEV_CLNT_DEC, - audio->dec_id, - adpcm_listner, - (void *)audio); - if (rc) { - MM_ERR("%s: failed to register listner\n", __func__); - goto event_err; - } - -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_adpcm_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, - &audadpcm_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audadpcm_resume; - audio->suspend_ctl.node.suspend = audadpcm_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (i = 0; i < AUDADPCM_EVENT_NUM; i++) { - e_node = kmalloc(sizeof(struct audadpcm_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } -done: - return rc; -event_err: - msm_adsp_put(audio->audplay); -err: - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - audpp_adec_free(audio->dec_id); - kfree(audio); - return rc; -} - -static const struct file_operations audio_adpcm_fops = { - .owner = THIS_MODULE, - .open = audio_open, - .release = audio_release, - .read = audio_read, - .write = audio_write, - .unlocked_ioctl = audio_ioctl, - .fsync = audio_fsync, -}; - -struct miscdevice audio_adpcm_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_adpcm", - .fops = &audio_adpcm_fops, -}; - -static int __init audio_init(void) -{ - return misc_register(&audio_adpcm_misc); -} - -device_initcall(audio_init); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c b/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c deleted file mode 100644 index c8b41715541bebff94eb34b3ffee1b39a3d57af6..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c +++ /dev/null @@ -1,1645 +0,0 @@ -/* - * amrnb audio decoder device - * - * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved. - * - * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * - * All source code in this file is licensed under the following license except - * where indicated. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define BUFSZ 1024 /* Hold minimum 700ms voice data and 14 bytes of meta in*/ -#define DMASZ (BUFSZ * 2) - -#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF -#define AUDDEC_DEC_AMRNB 10 - -#define PCM_BUFSZ_MIN 1624 /* 100ms worth of data and 24 bytes of meta out*/ -#define AMRNB_DECODED_FRSZ 320 /* AMR-NB 20ms 8KHz mono PCM size */ -#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most - but support 2 buffers currently */ -#define ROUTING_MODE_FTRT 1 -#define ROUTING_MODE_RT 2 -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDAMRNB_METAFIELD_MASK 0xFFFF0000 -#define AUDAMRNB_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */ -#define AUDAMRNB_EOS_FLG_MASK 0x01 -#define AUDAMRNB_EOS_NONE 0x0 /* No EOS detected */ -#define AUDAMRNB_EOS_SET 0x1 /* EOS set in meta field */ - -#define AUDAMRNB_EVENT_NUM 10 /* Default number of pre-allocated event pkts */ - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; - unsigned short mfield_sz; /*only useful for data has meta field */ -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audamrnb_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct audamrnb_event{ - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audio { - struct buffer out[2]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - /* Host PCM section */ - struct buffer in[PCM_BUF_MAX_COUNT]; - struct mutex read_lock; - wait_queue_head_t read_wait; /* Wait queue for read */ - char *read_data; /* pointer to reader buffer */ - int32_t read_phys; /* physical address of reader buffer */ - uint8_t read_next; /* index to input buffers to be read next */ - uint8_t fill_next; /* index to buffer that DSP should be filling */ - uint8_t pcm_buf_count; /* number of pcm buffer allocated */ - /* ---- End of Host PCM section */ - - struct msm_adsp_module *audplay; - - /* data allocated for various buffers */ - char *data; - int32_t phys; /* physical address of write buffer */ - void *map_v_read; - void *map_v_write; - - int mfield; /* meta field embedded in data */ - int rflush; /* Read flush */ - int wflush; /* Write flush */ - uint8_t opened:1; - uint8_t enabled:1; - uint8_t running:1; - uint8_t stopped:1; /* set when stopped, cleared on flush */ - uint8_t pcm_feedback:1; - uint8_t buf_refresh:1; - int teos; /* valid only if tunnel mode & no data left for decoder */ - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - - const char *module_name; - unsigned queue_id; - uint16_t dec_id; - uint32_t read_ptr_offset; - int16_t source; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audamrnb_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - /* AV sync Info */ - int avsync_flag; /* Flag to indicate feedback from DSP */ - wait_queue_head_t avsync_wait;/* Wait queue for AV Sync Message */ - /* flags, 48 bits sample/bytes counter per channel */ - uint16_t avsync[AUDPP_AVSYNC_CH_COUNT * AUDPP_AVSYNC_NUM_WORDS + 1]; - - uint32_t device_events; - - int eq_enable; - int eq_needs_commit; - struct audpp_cmd_cfg_object_params_eqalizer eq; - struct audpp_cmd_cfg_object_params_volume vol_pan; -}; - -struct audpp_cmd_cfg_adec_params_amrnb { - struct audpp_cmd_cfg_adec_params_common common; - unsigned short stereo_cfg; -} __attribute__((packed)) ; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audpp_cmd_cfg_adec_params(struct audio *audio); -static void audpp_cmd_cfg_routing_mode(struct audio *audio); -static void audamrnb_send_data(struct audio *audio, unsigned needed); -static void audamrnb_config_hostpcm(struct audio *audio); -static void audamrnb_buffer_refresh(struct audio *audio); -static void audamrnb_dsp_event(void *private, unsigned id, uint16_t *msg); -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audamrnb_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); -#endif - -/* must be called with audio->lock held */ -static int audamrnb_enable(struct audio *audio) -{ - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) - return 0; - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_tail = 0; - audio->out_needed = 0; - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audamrnb_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - return -ENODEV; - } - audio->enabled = 1; - return 0; -} - -static void amrnb_listner(u32 evt_id, union auddev_evt_data *evt_payload, - void *private_data) -{ - struct audio *audio = (struct audio *) private_data; - switch (evt_id) { - case AUDDEV_EVT_DEV_RDY: - MM_DBG(":AUDDEV_EVT_DEV_RDY\n"); - audio->source |= (0x1 << evt_payload->routing_id); - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - break; - case AUDDEV_EVT_DEV_RLS: - MM_DBG(":AUDDEV_EVT_DEV_RLS\n"); - audio->source &= ~(0x1 << evt_payload->routing_id); - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - break; - case AUDDEV_EVT_STREAM_VOL_CHG: - audio->vol_pan.volume = evt_payload->session_vol; - MM_DBG(":AUDDEV_EVT_STREAM_VOL_CHG, stream vol %d\n", - audio->vol_pan.volume); - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - break; - default: - MM_ERR(":ERROR:wrong event\n"); - break; - } -} -/* must be called with audio->lock held */ -static int audamrnb_disable(struct audio *audio) -{ - int rc = 0; - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - wake_up(&audio->write_wait); - wake_up(&audio->read_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - audio->out_needed = 0; - } - return rc; -} - -/* ------------------- dsp --------------------- */ -static void audamrnb_update_pcm_buf_entry(struct audio *audio, - uint32_t *payload) -{ - uint8_t index; - unsigned long flags; - - if (audio->rflush) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < payload[1]; index++) { - if (audio->in[audio->fill_next].addr == - payload[2 + index * 2]) { - MM_DBG("in[%d] ready\n", audio->fill_next); - audio->in[audio->fill_next].used = - payload[3 + index * 2]; - if ((++audio->fill_next) == audio->pcm_buf_count) - audio->fill_next = 0; - - } else { - MM_ERR("expected=%x ret=%x\n", - audio->in[audio->fill_next].addr, - payload[1 + index * 2]); - break; - } - } - if (audio->in[audio->fill_next].used == 0) { - audamrnb_buffer_refresh(audio); - } else { - MM_DBG("read cannot keep up\n"); - audio->buf_refresh = 1; - } - wake_up(&audio->read_wait); - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - getevent(msg, sizeof(msg)); - - MM_DBG("msg_id=%x\n", id); - - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audamrnb_send_data(audio, 1); - break; - - case AUDPLAY_MSG_BUFFER_UPDATE: - audamrnb_update_pcm_buf_entry(audio, msg); - break; - - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audplaytask)\n"); - break; - - default: - MM_ERR("unexpected message from decoder\n"); - } -} - -static void audamrnb_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status:sleep reason = \ - 0x%04x\n", reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init \n"); - if (audio->pcm_feedback) - audpp_cmd_cfg_routing_mode(audio); - else - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg \n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play \n"); - /* send mixer command */ - audpp_route_stream(audio->dec_id, - audio->source); - if (audio->pcm_feedback) { - audamrnb_config_hostpcm(audio); - audamrnb_buffer_refresh(audio); - } - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - default: - MM_ERR("unknown decoder status \n"); - break; - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - audpp_dsp_set_eq(audio->dec_id, audio->eq_enable, - &audio->eq, POPP); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audio->running = 0; - } else { - MM_DBG("CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_ROUTING_ACK: - MM_DBG("ROUTING_ACK mode=%d\n", msg[1]); - audpp_cmd_cfg_adec_params(audio); - break; - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - audio->rflush = 0; - wake_up(&audio->write_wait); - if (audio->pcm_feedback) - audamrnb_buffer_refresh(audio); - break; - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - - case AUDPP_MSG_AVSYNC_MSG: - MM_DBG("AUDPP_MSG_AVSYNC_MSG\n"); - memcpy(&audio->avsync[0], msg, sizeof(audio->avsync)); - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); - break; - - default: - MM_ERR("UNKNOWN (%d)\n", id); - } - -} - -struct msm_adsp_ops audplay_adsp_ops_amrnb = { - .event = audplay_dsp_event, -}; - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id, \ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - struct audpp_cmd_cfg_dec_type cfg_dec_cmd; - - memset(&cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - - cfg_dec_cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE; - if (enable) - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_AMRNB; - else - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - cfg_dec_cmd.dm_mode = 0x0; - cfg_dec_cmd.stream_id = audio->dec_id; - - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} - -static void audpp_cmd_cfg_adec_params(struct audio *audio) -{ - struct audpp_cmd_cfg_adec_params_amrnb cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN; - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = 8000; - cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V; - - audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static void audpp_cmd_cfg_routing_mode(struct audio *audio) -{ - struct audpp_cmd_routing_mode cmd; - MM_DBG("\n"); /* Macro prints the file name and function */ - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; - cmd.object_number = audio->dec_id; - if (audio->pcm_feedback) - cmd.routing_mode = ROUTING_MODE_FTRT; - else - cmd.routing_mode = ROUTING_MODE_RT; - - audpp_send_queue1(&cmd, sizeof(cmd)); -} - -static int audplay_dsp_send_data_avail(struct audio *audio, - unsigned idx, unsigned len) -{ - struct audplay_cmd_bitstream_data_avail_nt2 cmd; - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2; - if (audio->mfield) - cmd.decoder_id = AUDAMRNB_METAFIELD_MASK | - (audio->out[idx].mfield_sz >> 1); - else - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = audio->out[idx].addr; - cmd.buf_size = len / 2; - cmd.partition_number = 0; - return audplay_send_queue0(audio, &cmd, sizeof(cmd)); -} - -static void audamrnb_buffer_refresh(struct audio *audio) -{ - struct audplay_cmd_buffer_refresh refresh_cmd; - - refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; - refresh_cmd.num_buffers = 1; - refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; - refresh_cmd.buf0_length = audio->in[audio->fill_next].size - - (audio->in[audio->fill_next].size % AMRNB_DECODED_FRSZ) + - (audio->mfield ? 24 : 0); - refresh_cmd.buf_read_count = 0; - MM_DBG("buf0_addr=%x buf0_len=%d\n", refresh_cmd.buf0_address, - refresh_cmd.buf0_length); - (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); -} - -static void audamrnb_config_hostpcm(struct audio *audio) -{ - struct audplay_cmd_hpcm_buf_cfg cfg_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; - cfg_cmd.max_buffers = audio->pcm_buf_count; - cfg_cmd.byte_swap = 0; - cfg_cmd.hostpcm_config = (0x8000) | (0x4000); - cfg_cmd.feedback_frequency = 1; - cfg_cmd.partition_number = 0; - (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); - -} - -static void audamrnb_send_data(struct audio *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - MM_DBG("frame %d busy\n", audio->out_tail); - audplay_dsp_send_data_avail(audio, audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } - done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ - -static void audamrnb_flush(struct audio *audio) -{ - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->out_needed = 0; - atomic_set(&audio->out_bytes, 0); -} - -static void audamrnb_flush_pcm_buf(struct audio *audio) -{ - uint8_t index; - - for (index = 0; index < PCM_BUF_MAX_COUNT; index++) - audio->in[index].used = 0; - - audio->buf_refresh = 0; - audio->read_next = 0; - audio->fill_next = 0; -} - -static void audamrnb_ioport_reset(struct audio *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audamrnb_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->read_wait); - mutex_lock(&audio->read_lock); - audamrnb_flush_pcm_buf(audio); - mutex_unlock(&audio->read_lock); - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); -} - -static int audamrnb_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audamrnb_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audamrnb_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audamrnb_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audamrnb_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - -static long audamrnb_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audamrnb_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - audio->event_wait, audamrnb_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audamrnb_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - rc = 0; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audamrnb_event, list); - list_del(&drv_evt->list); - } - - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audio_enable_eq(struct audio *audio, int enable) -{ - if (audio->eq_enable == enable && !audio->eq_needs_commit) - return 0; - - audio->eq_enable = enable; - - if (audio->running) { - audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq, POPP); - audio->eq_needs_commit = 0; - } - return 0; -} - -static int audio_get_avsync_data(struct audio *audio, - struct msm_audio_stats *stats) -{ - int rc = -EINVAL; - unsigned long flags; - - local_irq_save(flags); - if (audio->dec_id == audio->avsync[0] && audio->avsync_flag) { - /* av_sync sample count */ - stats->sample_count = (audio->avsync[2] << 16) | - (audio->avsync[3]); - - /* av_sync byte_count */ - stats->byte_count = (audio->avsync[5] << 16) | - (audio->avsync[6]); - - audio->avsync_flag = 0; - rc = 0; - } - local_irq_restore(flags); - return rc; - -} - -static long audamrnb_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - unsigned long flags = 0; - uint16_t enable_mask; - int enable; - int prev_state; - - MM_DBG("cmd = %d\n", cmd); - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - - audio->avsync_flag = 0; - memset(&stats, 0, sizeof(stats)); - if (audpp_query_avsync(audio->dec_id) < 0) - return rc; - - rc = wait_event_interruptible_timeout(audio->avsync_wait, - (audio->avsync_flag == 1), - msecs_to_jiffies(AUDPP_AVSYNC_EVENT_TIMEOUT)); - - if (rc < 0) - return rc; - else if ((rc > 0) || ((rc == 0) && (audio->avsync_flag == 1))) { - if (audio_get_avsync_data(audio, &stats) < 0) - return rc; - - if (copy_to_user((void *)arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } else - return -EAGAIN; - } - - switch (cmd) { - case AUDIO_ENABLE_AUDPP: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - spin_lock_irqsave(&audio->dsp_lock, flags); - enable = (enable_mask & EQ_ENABLE) ? 1 : 0; - audio_enable_eq(audio, enable); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - case AUDIO_SET_VOLUME: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.volume = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_PAN: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.pan = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_EQ: - prev_state = audio->eq_enable; - audio->eq_enable = 0; - if (copy_from_user(&audio->eq.num_bands, (void *) arg, - sizeof(audio->eq) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) { - rc = -EFAULT; - break; - } - audio->eq_enable = prev_state; - audio->eq_needs_commit = 1; - rc = 0; - break; - } - - if (-EINVAL != rc) - return rc; - - if (cmd == AUDIO_GET_EVENT) { - MM_DBG("AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audamrnb_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audamrnb_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) - rc = -ENODEV; - else - rc = 0; - } - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audamrnb_disable(audio); - audio->stopped = 1; - audamrnb_ioport_reset(audio); - audio->stopped = 0; - break; - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audamrnb_ioport_reset(audio); - if (audio->running) { - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - case AUDIO_SET_CONFIG:{ - struct msm_audio_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - audio->mfield = config.meta_field; - rc = 0; - break; - } - case AUDIO_GET_CONFIG:{ - struct msm_audio_config config; - config.buffer_size = BUFSZ; - config.buffer_count = 2; - config.sample_rate = 8000; - config.channel_count = 1; - config.meta_field = 0; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - - break; - } - case AUDIO_GET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - config.pcm_feedback = audio->pcm_feedback; - config.buffer_count = PCM_BUF_MAX_COUNT; - config.buffer_size = PCM_BUFSZ_MIN; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.pcm_feedback != audio->pcm_feedback) { - MM_ERR("Not sufficient permission to" - "change the playback mode\n"); - rc = -EACCES; - break; - } - if ((config.buffer_count > PCM_BUF_MAX_COUNT) || - (config.buffer_count == 1)) - config.buffer_count = PCM_BUF_MAX_COUNT; - - if (config.buffer_size < PCM_BUFSZ_MIN) - config.buffer_size = PCM_BUFSZ_MIN; - - /* Check if pcm feedback is required */ - if ((config.pcm_feedback) && (!audio->read_data)) { - MM_DBG("allocate PCM buf %d\n", - config.buffer_count * - config.buffer_size); - audio->read_phys = allocate_contiguous_ebi_nomap( - config.buffer_size * - config.buffer_count, - SZ_4K); - if (!audio->read_phys) { - rc = -ENOMEM; - break; - } - audio->map_v_read = ioremap( - audio->read_phys, - config.buffer_size * - config.buffer_count); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("failed to map read phys address\n"); - rc = -ENOMEM; - free_contiguous_memory_by_paddr( - audio->read_phys); - } else { - uint8_t index; - uint32_t offset = 0; - audio->read_data = audio->map_v_read; - audio->buf_refresh = 0; - audio->pcm_buf_count = - config.buffer_count; - audio->read_next = 0; - audio->fill_next = 0; - - for (index = 0; - index < config.buffer_count; index++) { - audio->in[index].data = - audio->read_data + offset; - audio->in[index].addr = - audio->read_phys + offset; - audio->in[index].size = - config.buffer_size; - audio->in[index].used = 0; - offset += config.buffer_size; - } - MM_DBG("read buf: phy addr 0x%08x kernel \ - addr 0x%08x\n", audio->read_phys, - (int)audio->read_data); - rc = 0; - } - } else { - rc = 0; - } - break; - } - case AUDIO_GET_SESSION_ID: - if (copy_to_user((void *) arg, &audio->dec_id, - sizeof(unsigned short))) - rc = -EFAULT; - else - rc = 0; - break; - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -static int audamrnb_fsync(struct file *file, loff_t ppos1, loff_t ppos2, int datasync) -{ - struct audio *audio = file->private_data; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (!audio->running || audio->pcm_feedback) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush); - - if (audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; -} - -static ssize_t audamrnb_read(struct file *file, char __user *buf, size_t count, - loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - int rc = 0; - - if (!audio->pcm_feedback) - return 0; /* PCM feedback is not enabled. Nothing to read */ - - mutex_lock(&audio->read_lock); - MM_DBG("%d \n", count); - while (count > 0) { - rc = wait_event_interruptible(audio->read_wait, - (audio->in[audio->read_next].used > 0) || - (audio->stopped) || (audio->rflush)); - - if (rc < 0) - break; - - if (audio->stopped || audio->rflush) { - rc = -EBUSY; - break; - } - - if (count < audio->in[audio->read_next].used) { - /* Read must happen in frame boundary. Since driver does - * not know frame size, read count must be greater or - * equal to size of PCM samples - */ - MM_DBG("read stop - partial frame\n"); - break; - } else { - MM_DBG("read from in[%d]\n", audio->read_next); - - if (copy_to_user - (buf, audio->in[audio->read_next].data, - audio->in[audio->read_next].used)) { - MM_ERR("invalid addr %x \n", (unsigned int)buf); - rc = -EFAULT; - break; - } - count -= audio->in[audio->read_next].used; - buf += audio->in[audio->read_next].used; - audio->in[audio->read_next].used = 0; - if ((++audio->read_next) == audio->pcm_buf_count) - audio->read_next = 0; - break; - } - } - - /* don't feed output buffer to HW decoder during flushing - * buffer refresh command will be sent once flush completes - * send buf refresh command here can confuse HW decoder - */ - if (audio->buf_refresh && !audio->rflush) { - audio->buf_refresh = 0; - MM_DBG("kick start pcm feedback again\n"); - audamrnb_buffer_refresh(audio); - } - - mutex_unlock(&audio->read_lock); - - if (buf > start) - rc = buf - start; - - MM_DBG("read %d bytes\n", rc); - return rc; -} - -static int audamrnb_process_eos(struct audio *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - int rc = 0; - struct buffer *frame; - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - audamrnb_send_data(audio, 0); - -done: - return rc; -} - -static ssize_t audamrnb_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - char *cpy_ptr; - int rc = 0, eos_condition = AUDAMRNB_EOS_NONE; - unsigned short mfield_size = 0; - - MM_DBG("cnt=%d\n", count); - - if (count & 1) - return -EINVAL; - - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - cpy_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - - MM_DBG("buffer available\n"); - if (rc < 0) - break; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - break; - } - - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - break; - } else if (mfield_size > count) { - rc = -EINVAL; - break; - } - MM_DBG("mf offset_val %x\n", mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - break; - } - /* Check if EOS flag is set and buffer - * contains just meta field - */ - if (cpy_ptr[AUDAMRNB_EOS_FLG_OFFSET] & - AUDAMRNB_EOS_FLG_MASK) { - MM_DBG("eos set\n"); - eos_condition = AUDAMRNB_EOS_SET; - if (mfield_size == count) { - buf += mfield_size; - break; - } else - cpy_ptr[AUDAMRNB_EOS_FLG_OFFSET] &= - ~AUDAMRNB_EOS_FLG_MASK; - } - cpy_ptr += mfield_size; - count -= mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - - xfer = (count > (frame->size - mfield_size)) ? - (frame->size - mfield_size) : count; - if (copy_from_user(cpy_ptr, buf, xfer)) { - rc = -EFAULT; - break; - } - - frame->used = (xfer + mfield_size); - audio->out_head ^= 1; - count -= xfer; - buf += xfer; - - audamrnb_send_data(audio, 0); - - } - if (eos_condition == AUDAMRNB_EOS_SET) - rc = audamrnb_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - if (!rc) { - if (buf > start) - return buf - start; - } - return rc; -} - -static int audamrnb_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_INFO("audio instance 0x%08x freeing\n", (int)audio); - - mutex_lock(&audio->lock); - auddev_unregister_evt_listner(AUDDEV_CLNT_DEC, audio->dec_id); - audamrnb_disable(audio); - audamrnb_flush(audio); - audamrnb_flush_pcm_buf(audio); - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->event_abort = 1; - wake_up(&audio->event_wait); - audamrnb_reset_event_queue(audio); - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - if (audio->read_data) { - iounmap(audio->map_v_read); - free_contiguous_memory_by_paddr(audio->read_phys); - } - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - kfree(audio); - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audamrnb_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audamrnb_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audamrnb_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audamrnb_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -static void audamrnb_suspend(struct early_suspend *h) -{ - struct audamrnb_suspend_ctl *ctl = - container_of(h, struct audamrnb_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audamrnb_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audamrnb_resume(struct early_suspend *h) -{ - struct audamrnb_suspend_ctl *ctl = - container_of(h, struct audamrnb_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audamrnb_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audamrnb_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audamrnb_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 1024; - static char buffer[1024]; - int n = 0, i; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_feedback %d\n", audio->pcm_feedback); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_buf_sz %d\n", audio->out[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_count %d \n", audio->pcm_buf_count); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_sz %d \n", audio->in[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %x \n", audio->vol_pan.volume); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "rflush %d\n", audio->rflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d \n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d \n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d \n", audio->out_needed); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_head %d \n", audio->out_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_tail %d \n", audio->out_tail); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[0].used %d \n", audio->out[0].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[1].used %d \n", audio->out[1].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "buffer_refresh %d \n", audio->buf_refresh); - n += scnprintf(buffer + n, debug_bufmax - n, - "read_next %d \n", audio->read_next); - n += scnprintf(buffer + n, debug_bufmax - n, - "fill_next %d \n", audio->fill_next); - for (i = 0; i < audio->pcm_buf_count; i++) - n += scnprintf(buffer + n, debug_bufmax - n, - "in[%d].used %d \n", i, audio->in[i].used); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audamrnb_debug_fops = { - .read = audamrnb_debug_read, - .open = audamrnb_debug_open, -}; -#endif - -static int audamrnb_open(struct inode *inode, struct file *file) -{ - struct audio *audio = NULL; - int rc, dec_attrb, decid, i; - struct audamrnb_event *e_node = NULL; -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_amrnb_" + 5]; -#endif - - /* Allocate Mem for audio instance */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("no memory to allocate audio instance \n"); - rc = -ENOMEM; - goto done; - } - MM_INFO("audio instance 0x%08x created\n", (int)audio); - - /* Allocate the decoder */ - dec_attrb = AUDDEC_DEC_AMRNB; - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_NONTUNNEL; - audio->pcm_feedback = NON_TUNNEL_MODE_PLAYBACK; - } else if ((file->f_mode & FMODE_WRITE) && - !(file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_TUNNEL; - audio->pcm_feedback = TUNNEL_MODE_PLAYBACK; - } else { - kfree(audio); - rc = -EACCES; - goto done; - } - - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - - if (decid < 0) { - MM_ERR("No free decoder available, freeing instance 0x%08x\n", - (int)audio); - rc = -ENODEV; - kfree(audio); - goto done; - } - - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - audio->phys = allocate_contiguous_ebi_nomap(DMASZ, SZ_4K); - if (!audio->phys) { - MM_ERR("could not allocate write buffers, freeing instance \ - 0x%08x\n", (int)audio); - rc = -ENOMEM; - audpp_adec_free(audio->dec_id); - kfree(audio); - goto done; - } else { - audio->map_v_write = ioremap(audio->phys, DMASZ); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write phys address, freeing \ - instance 0x%08x\n", (int)audio); - rc = -ENOMEM; - free_contiguous_memory_by_paddr(audio->phys); - audpp_adec_free(audio->dec_id); - free_contiguous_memory_by_paddr(audio->phys); - kfree(audio); - goto done; - } - audio->data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr \ - 0x%08x\n", audio->phys, (int)audio->data); - } - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audplay_adsp_ops_amrnb, audio); - if (rc) { - MM_ERR("failed to get %s module freeing instance 0x%08x\n", - audio->module_name, (int)audio); - goto err; - } - - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->read_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - spin_lock_init(&audio->event_queue_lock); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->write_wait); - init_waitqueue_head(&audio->read_wait); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - init_waitqueue_head(&audio->avsync_wait); - - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = BUFSZ; - - audio->out[1].data = audio->data + BUFSZ; - audio->out[1].addr = audio->phys + BUFSZ; - audio->out[1].size = BUFSZ; - - audio->vol_pan.volume = 0x2000; - - audamrnb_flush(audio); - - file->private_data = audio; - audio->opened = 1; - - audio->device_events = AUDDEV_EVT_DEV_RDY - |AUDDEV_EVT_DEV_RLS| - AUDDEV_EVT_STREAM_VOL_CHG; - - rc = auddev_register_evt_listner(audio->device_events, - AUDDEV_CLNT_DEC, - audio->dec_id, - amrnb_listner, - (void *)audio); - if (rc) { - MM_ERR("%s: failed to register listner\n", __func__); - goto event_err; - } - -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_amrnb_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, &audamrnb_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audamrnb_resume; - audio->suspend_ctl.node.suspend = audamrnb_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (i = 0; i < AUDAMRNB_EVENT_NUM; i++) { - e_node = kmalloc(sizeof(struct audamrnb_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } -done: - return rc; -event_err: - msm_adsp_put(audio->audplay); -err: - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - audpp_adec_free(audio->dec_id); - kfree(audio); - return rc; -} - -static const struct file_operations audio_amrnb_fops = { - .owner = THIS_MODULE, - .open = audamrnb_open, - .release = audamrnb_release, - .read = audamrnb_read, - .write = audamrnb_write, - .unlocked_ioctl = audamrnb_ioctl, - .fsync = audamrnb_fsync, -}; - -struct miscdevice audio_amrnb_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_amrnb", - .fops = &audio_amrnb_fops, -}; - -static int __init audamrnb_init(void) -{ - return misc_register(&audio_amrnb_misc); -} - -static void __exit audamrnb_exit(void) -{ - misc_deregister(&audio_amrnb_misc); -} - -module_init(audamrnb_init); -module_exit(audamrnb_exit); - -MODULE_DESCRIPTION("MSM AMR-NB driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_amrnb_in.c b/arch/arm/mach-msm/qdsp5v2/audio_amrnb_in.c deleted file mode 100644 index 8b731d16d7d7f3bf92bfa5366835db460b9908d5..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_amrnb_in.c +++ /dev/null @@ -1,903 +0,0 @@ -/* - * amrnb audio input device - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* FRAME_NUM must be a power of two */ -#define FRAME_NUM (8) -#define FRAME_SIZE (22 * 2) /* 36 bytes data */ -#define DMASZ (FRAME_SIZE * FRAME_NUM) - -struct buffer { - void *data; - uint32_t size; - uint32_t read; - uint32_t addr; -}; - -struct audio_in { - struct buffer in[FRAME_NUM]; - - spinlock_t dsp_lock; - - atomic_t in_bytes; - atomic_t in_samples; - - struct mutex lock; - struct mutex read_lock; - wait_queue_head_t wait; - wait_queue_head_t wait_enable; - - struct msm_adsp_module *audrec; - struct audrec_session_info session_info; /*audrec session info*/ - - /* configuration to use on next enable */ - uint32_t buffer_size; /* Frame size (36 bytes) */ - uint32_t enc_type; - - int dtx_mode; - uint32_t frame_format; - uint32_t used_mode; - uint32_t rec_mode; - - uint32_t dsp_cnt; - uint32_t in_head; /* next buffer dsp will write */ - uint32_t in_tail; /* next buffer read() will read */ - uint32_t in_count; /* number of buffers available to read() */ - uint32_t mode; - - const char *module_name; - unsigned queue_ids; - uint16_t enc_id; - - uint16_t source; /* Encoding source bit mask */ - uint32_t device_events; - uint32_t in_call; - uint32_t dev_cnt; - int voice_state; - spinlock_t dev_lock; - - /* data allocated for various buffers */ - char *data; - dma_addr_t phys; - void *map_v_read; - - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - char *build_id; -}; - -struct audio_frame { - uint16_t frame_count_lsw; - uint16_t frame_count_msw; - uint16_t frame_length; - uint16_t erased_pcm; - unsigned char raw_bitstream[]; /* samples */ -} __attribute__((packed)); - -/* Audrec Queue command sent macro's */ -#define audrec_send_bitstreamqueue(audio, cmd, len) \ - msm_adsp_write(audio->audrec, ((audio->queue_ids & 0xFFFF0000) >> 16),\ - cmd, len) - -#define audrec_send_audrecqueue(audio, cmd, len) \ - msm_adsp_write(audio->audrec, (audio->queue_ids & 0x0000FFFF),\ - cmd, len) - -struct audio_in the_audio_amrnb_in; - -/* DSP command send functions */ -static int audamrnb_in_enc_config(struct audio_in *audio, int enable); -static int audamrnb_in_param_config(struct audio_in *audio); -static int audamrnb_in_mem_config(struct audio_in *audio); -static int audamrnb_in_record_config(struct audio_in *audio, int enable); -static int audamrnb_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt); - -static void audamrnb_in_get_dsp_frames(struct audio_in *audio); - -static void audamrnb_in_flush(struct audio_in *audio); - -static void amrnb_in_listener(u32 evt_id, union auddev_evt_data *evt_payload, - void *private_data) -{ - struct audio_in *audio = (struct audio_in *) private_data; - unsigned long flags; - - MM_DBG("evt_id = 0x%8x\n", evt_id); - switch (evt_id) { - case AUDDEV_EVT_DEV_RDY: { - MM_DBG("AUDDEV_EVT_DEV_RDY\n"); - spin_lock_irqsave(&audio->dev_lock, flags); - audio->dev_cnt++; - if (!audio->in_call) - audio->source |= (0x1 << evt_payload->routing_id); - spin_unlock_irqrestore(&audio->dev_lock, flags); - - if ((audio->running == 1) && (audio->enabled == 1)) - audamrnb_in_record_config(audio, 1); - - break; - } - case AUDDEV_EVT_DEV_RLS: { - MM_DBG("AUDDEV_EVT_DEV_RLS\n"); - spin_lock_irqsave(&audio->dev_lock, flags); - audio->dev_cnt--; - if (!audio->in_call) - audio->source &= ~(0x1 << evt_payload->routing_id); - spin_unlock_irqrestore(&audio->dev_lock, flags); - - if ((!audio->running) || (!audio->enabled)) - break; - - /* Turn of as per source */ - if (audio->source) - audamrnb_in_record_config(audio, 1); - else - /* Turn off all */ - audamrnb_in_record_config(audio, 0); - - break; - } - case AUDDEV_EVT_VOICE_STATE_CHG: { - MM_DBG("AUDDEV_EVT_VOICE_STATE_CHG, state = %d\n", - evt_payload->voice_state); - audio->voice_state = evt_payload->voice_state; - if (audio->in_call && audio->running) { - if (audio->voice_state == VOICE_STATE_INCALL) - audamrnb_in_record_config(audio, 1); - else if (audio->voice_state == VOICE_STATE_OFFCALL) { - audamrnb_in_record_config(audio, 0); - wake_up(&audio->wait); - } - } - - break; - } - default: - MM_ERR("wrong event %d\n", evt_id); - break; - } -} - -/* ------------------- dsp preproc event handler--------------------- */ -static void audpreproc_dsp_event(void *data, unsigned id, void *msg) -{ - struct audio_in *audio = data; - - switch (id) { - case AUDPREPROC_ERROR_MSG: { - struct audpreproc_err_msg *err_msg = msg; - - MM_ERR("ERROR_MSG: stream id %d err idx %d\n", - err_msg->stream_id, err_msg->aud_preproc_err_idx); - /* Error case */ - wake_up(&audio->wait_enable); - break; - } - case AUDPREPROC_CMD_CFG_DONE_MSG: { - MM_DBG("CMD_CFG_DONE_MSG \n"); - break; - } - case AUDPREPROC_CMD_ENC_CFG_DONE_MSG: { - struct audpreproc_cmd_enc_cfg_done_msg *enc_cfg_msg = msg; - - MM_DBG("CMD_ENC_CFG_DONE_MSG: stream id %d enc type \ - 0x%8x\n", enc_cfg_msg->stream_id, - enc_cfg_msg->rec_enc_type); - /* Encoder enable success */ - if (enc_cfg_msg->rec_enc_type & ENCODE_ENABLE) - audamrnb_in_param_config(audio); - else { /* Encoder disable success */ - audio->running = 0; - audamrnb_in_record_config(audio, 0); - } - break; - } - case AUDPREPROC_CMD_ENC_PARAM_CFG_DONE_MSG: { - MM_DBG("CMD_ENC_PARAM_CFG_DONE_MSG \n"); - audamrnb_in_mem_config(audio); - break; - } - case AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG_DONE_MSG: { - MM_DBG("AFE_CMD_AUDIO_RECORD_CFG_DONE_MSG \n"); - wake_up(&audio->wait_enable); - break; - } - default: - MM_ERR("Unknown Event id %d\n", id); - } -} - -/* ------------------- dsp audrec event handler--------------------- */ -static void audrec_dsp_event(void *data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - struct audio_in *audio = data; - - switch (id) { - case AUDREC_CMD_MEM_CFG_DONE_MSG: { - MM_DBG("CMD_MEM_CFG_DONE MSG DONE\n"); - audio->running = 1; - if ((!audio->in_call && (audio->dev_cnt > 0)) || - (audio->in_call && - (audio->voice_state == VOICE_STATE_INCALL))) - audamrnb_in_record_config(audio, 1); - break; - } - case AUDREC_FATAL_ERR_MSG: { - struct audrec_fatal_err_msg fatal_err_msg; - - getevent(&fatal_err_msg, AUDREC_FATAL_ERR_MSG_LEN); - MM_ERR("FATAL_ERR_MSG: err id %d\n", - fatal_err_msg.audrec_err_id); - /* Error stop the encoder */ - audio->stopped = 1; - wake_up(&audio->wait); - break; - } - case AUDREC_UP_PACKET_READY_MSG: { - struct audrec_up_pkt_ready_msg pkt_ready_msg; - - getevent(&pkt_ready_msg, AUDREC_UP_PACKET_READY_MSG_LEN); - MM_DBG("UP_PACKET_READY_MSG: write cnt lsw %d \ - write cnt msw %d read cnt lsw %d read cnt msw %d \n",\ - pkt_ready_msg.audrec_packet_write_cnt_lsw, \ - pkt_ready_msg.audrec_packet_write_cnt_msw, \ - pkt_ready_msg.audrec_up_prev_read_cnt_lsw, \ - pkt_ready_msg.audrec_up_prev_read_cnt_msw); - - audamrnb_in_get_dsp_frames(audio); - break; - } - case ADSP_MESSAGE_ID: { - MM_DBG("Received ADSP event:module audrectask\n"); - break; - } - default: - MM_ERR("Unknown Event id %d\n", id); - } -} - -static void audamrnb_in_get_dsp_frames(struct audio_in *audio) -{ - struct audio_frame *frame; - uint32_t index; - unsigned long flags; - - index = audio->in_head; - - frame = (void *) (((char *)audio->in[index].data) - \ - sizeof(*frame)); - - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->in[index].size = frame->frame_length; - - /* statistics of read */ - atomic_add(audio->in[index].size, &audio->in_bytes); - atomic_add(1, &audio->in_samples); - - audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1); - - /* If overflow, move the tail index foward. */ - if (audio->in_head == audio->in_tail) - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - else - audio->in_count++; - - audamrnb_dsp_read_buffer(audio, audio->dsp_cnt++); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - - wake_up(&audio->wait); -} -struct msm_adsp_ops audrec_amrnb_adsp_ops = { - .event = audrec_dsp_event, -}; - -static int audamrnb_in_enc_config(struct audio_in *audio, int enable) -{ - struct audpreproc_audrec_cmd_enc_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - if (audio->build_id[17] == '1') { - cmd.cmd_id = AUDPREPROC_AUDREC_CMD_ENC_CFG_2; - MM_ERR("sending AUDPREPROC_AUDREC_CMD_ENC_CFG_2 command"); - } else { - cmd.cmd_id = AUDPREPROC_AUDREC_CMD_ENC_CFG; - MM_ERR("sending AUDPREPROC_AUDREC_CMD_ENC_CFG command"); - } - cmd.stream_id = audio->enc_id; - - if (enable) - cmd.audrec_enc_type = audio->enc_type | ENCODE_ENABLE; - else - cmd.audrec_enc_type &= ~(ENCODE_ENABLE); - - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); -} - -static int audamrnb_in_param_config(struct audio_in *audio) -{ - struct audpreproc_audrec_cmd_parm_cfg_amrnb cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPREPROC_AUDREC_CMD_PARAM_CFG; - cmd.common.stream_id = audio->enc_id; - - cmd.dtx_mode = audio->dtx_mode; - cmd.test_mode = -1; /* Default set to -1 */ - cmd.used_mode = audio->used_mode; - - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); -} - -/* To Do: msm_snddev_route_enc(audio->enc_id); */ -static int audamrnb_in_record_config(struct audio_in *audio, int enable) -{ - struct audpreproc_afe_cmd_audio_record_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG; - cmd.stream_id = audio->enc_id; - if (enable) - cmd.destination_activity = AUDIO_RECORDING_TURN_ON; - else - cmd.destination_activity = AUDIO_RECORDING_TURN_OFF; - - cmd.source_mix_mask = audio->source; - if (audio->enc_id == 2) { - if ((cmd.source_mix_mask & - INTERNAL_CODEC_TX_SOURCE_MIX_MASK) || - (cmd.source_mix_mask & AUX_CODEC_TX_SOURCE_MIX_MASK) || - (cmd.source_mix_mask & VOICE_UL_SOURCE_MIX_MASK) || - (cmd.source_mix_mask & VOICE_DL_SOURCE_MIX_MASK)) { - cmd.pipe_id = SOURCE_PIPE_1; - } - if (cmd.source_mix_mask & - AUDPP_A2DP_PIPE_SOURCE_MIX_MASK) - cmd.pipe_id |= SOURCE_PIPE_0; - } - - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); -} - -static int audamrnb_in_mem_config(struct audio_in *audio) -{ - struct audrec_cmd_arecmem_cfg cmd; - uint16_t *data = (void *) audio->data; - int n; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_MEM_CFG_CMD; - cmd.audrec_up_pkt_intm_count = 1; - cmd.audrec_ext_pkt_start_addr_msw = audio->phys >> 16; - cmd.audrec_ext_pkt_start_addr_lsw = audio->phys; - cmd.audrec_ext_pkt_buf_number = FRAME_NUM; - - /* prepare buffer pointers: - * 36 bytes amrnb packet + 4 halfword header - */ - for (n = 0; n < FRAME_NUM; n++) { - audio->in[n].data = data + 4; - data += (FRAME_SIZE/2); /* word increment */ - MM_DBG("0x%8x\n", (int)(audio->in[n].data - 8)); - } - - return audrec_send_audrecqueue(audio, &cmd, sizeof(cmd)); -} - -static int audamrnb_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt) -{ - struct up_audrec_packet_ext_ptr cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = UP_AUDREC_PACKET_EXT_PTR; - cmd.audrec_up_curr_read_count_msw = read_cnt >> 16; - cmd.audrec_up_curr_read_count_lsw = read_cnt; - - return audrec_send_bitstreamqueue(audio, &cmd, sizeof(cmd)); -} - -/* must be called with audio->lock held */ -static int audamrnb_in_enable(struct audio_in *audio) -{ - if (audio->enabled) - return 0; - - if (audpreproc_enable(audio->enc_id, &audpreproc_dsp_event, audio)) { - MM_ERR("msm_adsp_enable(audpreproc) failed\n"); - return -ENODEV; - } - - if (msm_adsp_enable(audio->audrec)) { - MM_ERR("msm_adsp_enable(audrec) failed\n"); - audpreproc_disable(audio->enc_id, audio); - return -ENODEV; - } - audio->enabled = 1; - audamrnb_in_enc_config(audio, 1); - - return 0; -} - -/* must be called with audio->lock held */ -static int audamrnb_in_disable(struct audio_in *audio) -{ - if (audio->enabled) { - audio->enabled = 0; - audamrnb_in_enc_config(audio, 0); - wake_up(&audio->wait); - wait_event_interruptible_timeout(audio->wait_enable, - audio->running == 0, 1*HZ); - msm_adsp_disable(audio->audrec); - audpreproc_disable(audio->enc_id, audio); - } - return 0; -} - -static void audamrnb_in_flush(struct audio_in *audio) -{ - int i; - - audio->dsp_cnt = 0; - audio->in_head = 0; - audio->in_tail = 0; - audio->in_count = 0; - for (i = 0; i < FRAME_NUM; i++) { - audio->in[i].size = 0; - audio->in[i].read = 0; - } - MM_DBG("in_bytes %d\n", atomic_read(&audio->in_bytes)); - MM_DBG("in_samples %d\n", atomic_read(&audio->in_samples)); - atomic_set(&audio->in_bytes, 0); - atomic_set(&audio->in_samples, 0); -} - -/* ------------------- device --------------------- */ -static long audamrnb_in_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct audio_in *audio = file->private_data; - int rc = 0; - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = atomic_read(&audio->in_bytes); - stats.sample_count = atomic_read(&audio->in_samples); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return rc; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: { - uint32_t freq; - freq = 48000; - MM_DBG("AUDIO_START\n"); - if (audio->in_call && (audio->voice_state != - VOICE_STATE_INCALL)) { - rc = -EPERM; - break; - } - rc = msm_snddev_request_freq(&freq, audio->enc_id, - SNDDEV_CAP_TX, AUDDEV_CLNT_ENC); - MM_DBG("sample rate configured %d\n", freq); - if (rc < 0) { - MM_DBG(" Sample rate can not be set, return code %d\n", - rc); - msm_snddev_withdraw_freq(audio->enc_id, - SNDDEV_CAP_TX, AUDDEV_CLNT_ENC); - MM_DBG("msm_snddev_withdraw_freq\n"); - break; - } - /*update aurec session info in audpreproc layer*/ - audio->session_info.session_id = audio->enc_id; - /*amrnb works only on 8KHz*/ - audio->session_info.sampling_freq = 8000; - audpreproc_update_audrec_info(&audio->session_info); - rc = audamrnb_in_enable(audio); - if (!rc) { - rc = - wait_event_interruptible_timeout(audio->wait_enable, - audio->running != 0, 1*HZ); - MM_DBG("state %d rc = %d\n", audio->running, rc); - - if (audio->running == 0) - rc = -ENODEV; - else - rc = 0; - } - audio->stopped = 0; - break; - } - case AUDIO_STOP: { - /*reset the sampling frequency information at audpreproc layer*/ - audio->session_info.sampling_freq = 0; - audpreproc_update_audrec_info(&audio->session_info); - rc = audamrnb_in_disable(audio); - rc = msm_snddev_withdraw_freq(audio->enc_id, - SNDDEV_CAP_TX, AUDDEV_CLNT_ENC); - MM_DBG("msm_snddev_withdraw_freq\n"); - audio->stopped = 1; - break; - } - case AUDIO_FLUSH: { - if (audio->stopped) { - /* Make sure we're stopped and we wake any threads - * that might be blocked holding the read_lock. - * While audio->stopped read threads will always - * exit immediately. - */ - wake_up(&audio->wait); - mutex_lock(&audio->read_lock); - audamrnb_in_flush(audio); - mutex_unlock(&audio->read_lock); - } - break; - } - case AUDIO_SET_STREAM_CONFIG: { - struct msm_audio_stream_config cfg; - if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - /* Allow only single frame */ - if (cfg.buffer_size != (FRAME_SIZE - 8)) - rc = -EINVAL; - else - audio->buffer_size = cfg.buffer_size; - break; - } - case AUDIO_GET_STREAM_CONFIG: { - struct msm_audio_stream_config cfg; - memset(&cfg, 0, sizeof(cfg)); - cfg.buffer_size = audio->buffer_size; - cfg.buffer_count = FRAME_NUM; - if (copy_to_user((void *) arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - break; - } - case AUDIO_GET_AMRNB_ENC_CONFIG_V2: { - struct msm_audio_amrnb_enc_config_v2 cfg; - memset(&cfg, 0, sizeof(cfg)); - cfg.dtx_enable = ((audio->dtx_mode == -1) ? 1 : 0); - cfg.band_mode = audio->used_mode; - cfg.frame_format = audio->frame_format; - if (copy_to_user((void *) arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - break; - } - case AUDIO_SET_AMRNB_ENC_CONFIG_V2: { - struct msm_audio_amrnb_enc_config_v2 cfg; - if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - /* DSP does not support any other than default format */ - if (audio->frame_format != cfg.frame_format) { - rc = -EINVAL; - break; - } - if (cfg.dtx_enable == 0) - audio->dtx_mode = 0; - else if (cfg.dtx_enable == 1) - audio->dtx_mode = -1; - else { - rc = -EINVAL; - break; - } - audio->used_mode = cfg.band_mode; - break; - } - case AUDIO_SET_INCALL: { - struct msm_voicerec_mode cfg; - unsigned long flags; - if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - if (cfg.rec_mode != VOC_REC_BOTH && - cfg.rec_mode != VOC_REC_UPLINK && - cfg.rec_mode != VOC_REC_DOWNLINK) { - MM_ERR("invalid rec_mode\n"); - rc = -EINVAL; - break; - } else { - spin_lock_irqsave(&audio->dev_lock, flags); - if (cfg.rec_mode == VOC_REC_UPLINK) - audio->source = VOICE_UL_SOURCE_MIX_MASK; - else if (cfg.rec_mode == VOC_REC_DOWNLINK) - audio->source = VOICE_DL_SOURCE_MIX_MASK; - else - audio->source = VOICE_DL_SOURCE_MIX_MASK | - VOICE_UL_SOURCE_MIX_MASK ; - audio->in_call = 1; - spin_unlock_irqrestore(&audio->dev_lock, flags); - } - break; - } - case AUDIO_GET_SESSION_ID: { - if (copy_to_user((void *) arg, &audio->enc_id, - sizeof(unsigned short))) { - rc = -EFAULT; - } - break; - } - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -static ssize_t audamrnb_in_read(struct file *file, - char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_in *audio = file->private_data; - unsigned long flags; - const char __user *start = buf; - void *data; - uint32_t index; - uint32_t size; - int rc = 0; - - mutex_lock(&audio->read_lock); - while (count > 0) { - rc = wait_event_interruptible( - audio->wait, (audio->in_count > 0) || audio->stopped - || (audio->in_call && audio->running && - (audio->voice_state == VOICE_STATE_OFFCALL))); - if (rc < 0) - break; - - if (!audio->in_count) { - if (audio->stopped) { - rc = 0;/* End of File */ - break; - } else if (audio->in_call && audio->running && - (audio->voice_state == VOICE_STATE_OFFCALL)) { - MM_DBG("Not Permitted Voice Terminated\n"); - rc = -EPERM; /* Voice Call stopped */ - break; - } - } - - index = audio->in_tail; - data = (uint8_t *) audio->in[index].data; - size = audio->in[index].size; - if (count >= size) { - if (copy_to_user(buf, data, size)) { - rc = -EFAULT; - break; - } - spin_lock_irqsave(&audio->dsp_lock, flags); - if (index != audio->in_tail) { - /* overrun -- data is - * invalid and we need to retry */ - spin_unlock_irqrestore(&audio->dsp_lock, flags); - continue; - } - audio->in[index].size = 0; - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - audio->in_count--; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - count -= size; - buf += size; - } else { - MM_ERR("short read\n"); - break; - } - } - mutex_unlock(&audio->read_lock); - - if (buf > start) - return buf - start; - - return rc; -} - -static ssize_t audamrnb_in_write(struct file *file, - const char __user *buf, - size_t count, loff_t *pos) -{ - return -EINVAL; -} - -static int audamrnb_in_release(struct inode *inode, struct file *file) -{ - struct audio_in *audio = file->private_data; - - MM_DBG("\n"); - mutex_lock(&audio->lock); - audio->in_call = 0; - /* with draw frequency for session - incase not stopped the driver */ - msm_snddev_withdraw_freq(audio->enc_id, SNDDEV_CAP_TX, - AUDDEV_CLNT_ENC); - auddev_unregister_evt_listner(AUDDEV_CLNT_ENC, audio->enc_id); - /*reset the sampling frequency information at audpreproc layer*/ - audio->session_info.sampling_freq = 0; - audpreproc_update_audrec_info(&audio->session_info); - audamrnb_in_disable(audio); - audamrnb_in_flush(audio); - msm_adsp_put(audio->audrec); - audpreproc_aenc_free(audio->enc_id); - audio->audrec = NULL; - audio->opened = 0; - if (audio->data) { - iounmap(audio->map_v_read); - free_contiguous_memory_by_paddr(audio->phys); - audio->data = NULL; - } - mutex_unlock(&audio->lock); - return 0; -} - -static int audamrnb_in_open(struct inode *inode, struct file *file) -{ - struct audio_in *audio = &the_audio_amrnb_in; - int rc; - int encid; - - mutex_lock(&audio->lock); - if (audio->opened) { - rc = -EBUSY; - goto done; - } - audio->phys = allocate_contiguous_ebi_nomap(DMASZ, SZ_4K); - if (audio->phys) { - audio->map_v_read = ioremap(audio->phys, DMASZ); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("could not map DMA buffers\n"); - rc = -ENOMEM; - free_contiguous_memory_by_paddr(audio->phys); - goto done; - } - audio->data = audio->map_v_read; - } else { - MM_ERR("could not allocate DMA buffers\n"); - rc = -ENOMEM; - goto done; - } - MM_DBG("Memory addr = 0x%8x phy addr = 0x%8x\n",\ - (int) audio->data, (int) audio->phys); - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - rc = -EACCES; - MM_ERR("Non tunnel encoding is not supported\n"); - goto done; - } else if (!(file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - audio->mode = MSM_AUD_ENC_MODE_TUNNEL; - MM_DBG("Opened for tunnel mode encoding\n"); - } else { - rc = -EACCES; - goto done; - } - - - /* Settings will be re-config at AUDIO_SET_CONFIG, - * but at least we need to have initial config - */ - audio->buffer_size = (FRAME_SIZE - 8); - audio->enc_type = ENC_TYPE_AMRNB | audio->mode; - audio->dtx_mode = -1; - audio->frame_format = 0; - audio->used_mode = 7; /* Bit Rate 12.2 kbps MR122 */ - - encid = audpreproc_aenc_alloc(audio->enc_type, &audio->module_name, - &audio->queue_ids); - if (encid < 0) { - MM_ERR("No free encoder available\n"); - rc = -ENODEV; - goto done; - } - audio->enc_id = encid; - - rc = msm_adsp_get(audio->module_name, &audio->audrec, - &audrec_amrnb_adsp_ops, audio); - - if (rc) { - audpreproc_aenc_free(audio->enc_id); - goto done; - } - - audio->stopped = 0; - audio->source = 0; - - audamrnb_in_flush(audio); - - audio->device_events = AUDDEV_EVT_DEV_RDY | AUDDEV_EVT_DEV_RLS | - AUDDEV_EVT_VOICE_STATE_CHG; - - audio->voice_state = msm_get_voice_state(); - rc = auddev_register_evt_listner(audio->device_events, - AUDDEV_CLNT_ENC, audio->enc_id, - amrnb_in_listener, (void *) audio); - if (rc) { - MM_ERR("failed to register device event listener\n"); - goto evt_error; - } - audio->build_id = socinfo_get_build_id(); - MM_DBG("Modem build id = %s\n", audio->build_id); - - file->private_data = audio; - audio->opened = 1; -done: - mutex_unlock(&audio->lock); - return rc; -evt_error: - msm_adsp_put(audio->audrec); - audpreproc_aenc_free(audio->enc_id); - mutex_unlock(&audio->lock); - return rc; -} - -static const struct file_operations audio_in_fops = { - .owner = THIS_MODULE, - .open = audamrnb_in_open, - .release = audamrnb_in_release, - .read = audamrnb_in_read, - .write = audamrnb_in_write, - .unlocked_ioctl = audamrnb_in_ioctl, -}; - -struct miscdevice audio_amrnb_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_amrnb_in", - .fops = &audio_in_fops, -}; - -static int __init audamrnb_in_init(void) -{ - mutex_init(&the_audio_amrnb_in.lock); - mutex_init(&the_audio_amrnb_in.read_lock); - spin_lock_init(&the_audio_amrnb_in.dsp_lock); - spin_lock_init(&the_audio_amrnb_in.dev_lock); - init_waitqueue_head(&the_audio_amrnb_in.wait); - init_waitqueue_head(&the_audio_amrnb_in.wait_enable); - return misc_register(&audio_amrnb_in_misc); -} - -device_initcall(audamrnb_in_init); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c b/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c deleted file mode 100644 index 66d0a9e14137e5b4cd13f22a5828b49bc47dfd0d..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c +++ /dev/null @@ -1,1727 +0,0 @@ -/* amrwb audio decoder device - * - * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved. - * - * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * - * All source code in this file is licensed under the following license except - * where indicated. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define BUFSZ 4110 /* Hold minimum 700ms voice data and 14 bytes of meta in*/ -#define DMASZ (BUFSZ * 2) - -#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF -#define AUDDEC_DEC_AMRWB 11 - -#define PCM_BUFSZ_MIN 8216 /* 100ms worth of data and 24 bytes of meta out*/ -#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most - but support 2 buffers currently */ -#define ROUTING_MODE_FTRT 1 -#define ROUTING_MODE_RT 2 -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDAMRWB_METAFIELD_MASK 0xFFFF0000 -#define AUDAMRWB_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */ -#define AUDAMRWB_EOS_FLG_MASK 0x01 -#define AUDAMRWB_EOS_NONE 0x0 /* No EOS detected */ -#define AUDAMRWB_EOS_SET 0x1 /* EOS set in meta field */ - -#define AUDAMRWB_EVENT_NUM 10 /* Default number of pre-allocated event pkts */ - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; - unsigned short mfield_sz; /*only useful for data has meta field */ -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audamrwb_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct audamrwb_event{ - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audio { - struct buffer out[2]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - /* Host PCM section */ - struct buffer in[PCM_BUF_MAX_COUNT]; - struct mutex read_lock; - wait_queue_head_t read_wait; /* Wait queue for read */ - char *read_data; /* pointer to reader buffer */ - int32_t read_phys; /* physical address of reader buffer */ - uint8_t read_next; /* index to input buffers to be read next */ - uint8_t fill_next; /* index to buffer that DSP should be filling */ - uint8_t pcm_buf_count; /* number of pcm buffer allocated */ - /* ---- End of Host PCM section */ - - struct msm_adsp_module *audplay; - - /* configuration to use on next enable */ - uint32_t out_sample_rate; - uint32_t out_channel_mode; - - /* data allocated for various buffers */ - char *data; - int32_t phys; /* physical address of write buffer */ - - void *map_v_read; - void *map_v_write; - - int mfield; /* meta field embedded in data */ - int rflush; /* Read flush */ - int wflush; /* Write flush */ - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - int pcm_feedback; - int buf_refresh; - int teos; /* valid only if tunnel mode & no data left for decoder */ - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - int reserved; /* A byte is being reserved */ - char rsv_byte; /* Handle odd length user data */ - - const char *module_name; - unsigned queue_id; - uint16_t dec_id; - uint32_t read_ptr_offset; - int16_t source; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audamrwb_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - /* AV sync Info */ - int avsync_flag; /* Flag to indicate feedback from DSP */ - wait_queue_head_t avsync_wait;/* Wait queue for AV Sync Message */ - /* flags, 48 bits sample/bytes counter per channel */ - uint16_t avsync[AUDPP_AVSYNC_CH_COUNT * AUDPP_AVSYNC_NUM_WORDS + 1]; - - uint32_t device_events; - - int eq_enable; - int eq_needs_commit; - struct audpp_cmd_cfg_object_params_eqalizer eq; - struct audpp_cmd_cfg_object_params_volume vol_pan; -}; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audpp_cmd_cfg_adec_params(struct audio *audio); -static void audpp_cmd_cfg_routing_mode(struct audio *audio); -static void audamrwb_send_data(struct audio *audio, unsigned needed); -static void audamrwb_config_hostpcm(struct audio *audio); -static void audamrwb_buffer_refresh(struct audio *audio); -static void audamrwb_dsp_event(void *private, unsigned id, uint16_t *msg); -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audamrwb_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); -#endif - -/* must be called with audio->lock held */ -static int audamrwb_enable(struct audio *audio) -{ - - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (audio->enabled) - return 0; - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_tail = 0; - audio->out_needed = 0; - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audamrwb_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - return -ENODEV; - } - audio->enabled = 1; - return 0; -} - -static void amrwb_listner(u32 evt_id, union auddev_evt_data *evt_payload, - void *private_data) -{ - struct audio *audio = (struct audio *) private_data; - switch (evt_id) { - case AUDDEV_EVT_DEV_RDY: - MM_DBG("AUDDEV_EVT_DEV_RDY\n"); - audio->source |= (0x1 << evt_payload->routing_id); - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - break; - case AUDDEV_EVT_DEV_RLS: - MM_DBG("AUDDEV_EVT_DEV_RLS\n"); - audio->source &= ~(0x1 << evt_payload->routing_id); - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - break; - case AUDDEV_EVT_STREAM_VOL_CHG: - audio->vol_pan.volume = evt_payload->session_vol; - MM_DBG("AUDDEV_EVT_STREAM_VOL_CHG, stream vol %d\n", - audio->vol_pan.volume); - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - break; - default: - MM_ERR("ERROR:wrong event\n"); - break; - } -} - -/* must be called with audio->lock held */ -static int audamrwb_disable(struct audio *audio) -{ - int rc = 0; - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - wake_up(&audio->write_wait); - wake_up(&audio->read_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - audio->out_needed = 0; - } - return rc; -} - -/* ------------------- dsp --------------------- */ -static void audamrwb_update_pcm_buf_entry(struct audio *audio, - uint32_t *payload) -{ - uint8_t index; - unsigned long flags; - - if (audio->rflush) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < payload[1]; index++) { - if (audio->in[audio->fill_next].addr == - payload[2 + index * 2]) { - MM_DBG("audamrwb_update_pcm_buf_entry: \ - in[%d] ready\n", audio->fill_next); - audio->in[audio->fill_next].used = - payload[3 + index * 2]; - if ((++audio->fill_next) == audio->pcm_buf_count) - audio->fill_next = 0; - - } else { - MM_ERR("expected=%x ret=%x\n", - audio->in[audio->fill_next].addr, - payload[1 + index * 2]); - break; - } - } - if (audio->in[audio->fill_next].used == 0) { - audamrwb_buffer_refresh(audio); - } else { - MM_DBG("audamrwb_update_pcm_buf_entry: \ - read cannot keep up\n"); - audio->buf_refresh = 1; - } - wake_up(&audio->read_wait); - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - getevent(msg, sizeof(msg)); - - MM_DBG("audplay_dsp_event: msg_id=%x\n", id); - - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audamrwb_send_data(audio, 1); - break; - - case AUDPLAY_MSG_BUFFER_UPDATE: - audamrwb_update_pcm_buf_entry(audio, msg); - break; - - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event:module audplaytask\n"); - break; - - default: - MM_DBG("unexpected message from decoder\n"); - } -} - -static void audamrwb_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status:sleep reason=0x%04x\n", - reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init\n"); - if (audio->pcm_feedback) - audpp_cmd_cfg_routing_mode(audio); - else - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg\n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play\n"); - /* send mixer command */ - audpp_route_stream(audio->dec_id, - audio->source); - if (audio->pcm_feedback) { - audamrwb_config_hostpcm(audio); - audamrwb_buffer_refresh(audio); - } - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - default: - MM_DBG("unknown decoder status\n"); - break; - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - audpp_dsp_set_eq(audio->dec_id, audio->eq_enable, - &audio->eq, POPP); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audio->running = 0; - } else { - MM_DBG("CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_ROUTING_ACK: - MM_DBG("ROUTING_ACK mode=%d\n", msg[1]); - audpp_cmd_cfg_adec_params(audio); - break; - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - audio->rflush = 0; - wake_up(&audio->write_wait); - if (audio->pcm_feedback) - audamrwb_buffer_refresh(audio); - break; - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - - case AUDPP_MSG_AVSYNC_MSG: - MM_DBG("AUDPP_MSG_AVSYNC_MSG\n"); - memcpy(&audio->avsync[0], msg, sizeof(audio->avsync)); - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); - break; - - default: - MM_DBG("UNKNOWN (%d)\n", id); - } - -} - -struct msm_adsp_ops audplay_adsp_ops_amrwb = { - .event = audplay_dsp_event, -}; - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id, \ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - struct audpp_cmd_cfg_dec_type cfg_dec_cmd; - - memset(&cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - - cfg_dec_cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE; - if (enable) - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_AMRWB; - else - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - cfg_dec_cmd.dm_mode = 0x0; - cfg_dec_cmd.stream_id = audio->dec_id; - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} - -static void audpp_cmd_cfg_adec_params(struct audio *audio) -{ - struct audpp_cmd_cfg_adec_params_amrwb cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_AMRWB_LEN; - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = audio->out_sample_rate; - cmd.stereo_cfg = audio->out_channel_mode; - audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static void audpp_cmd_cfg_routing_mode(struct audio *audio) -{ - struct audpp_cmd_routing_mode cmd; - MM_DBG("\n"); /* Macro prints the file name and function */ - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; - cmd.object_number = audio->dec_id; - if (audio->pcm_feedback) - cmd.routing_mode = ROUTING_MODE_FTRT; - else - cmd.routing_mode = ROUTING_MODE_RT; - - audpp_send_queue1(&cmd, sizeof(cmd)); -} - -static int audplay_dsp_send_data_avail(struct audio *audio, - unsigned idx, unsigned len) -{ - struct audplay_cmd_bitstream_data_avail_nt2 cmd; - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2; - if (audio->mfield) - cmd.decoder_id = AUDAMRWB_METAFIELD_MASK | - (audio->out[idx].mfield_sz >> 1); - else - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = audio->out[idx].addr; - cmd.buf_size = len / 2; - cmd.partition_number = 0; - return audplay_send_queue0(audio, &cmd, sizeof(cmd)); -} - -static void audamrwb_buffer_refresh(struct audio *audio) -{ - struct audplay_cmd_buffer_refresh refresh_cmd; - - refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; - refresh_cmd.num_buffers = 1; - refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; - refresh_cmd.buf0_length = audio->in[audio->fill_next].size; - refresh_cmd.buf_read_count = 0; - MM_DBG("buf0_addr=%x buf0_len=%d\n", refresh_cmd.buf0_address, - refresh_cmd.buf0_length); - (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); -} - -static void audamrwb_config_hostpcm(struct audio *audio) -{ - struct audplay_cmd_hpcm_buf_cfg cfg_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; - cfg_cmd.max_buffers = audio->pcm_buf_count; - cfg_cmd.byte_swap = 0; - cfg_cmd.hostpcm_config = (0x8000) | (0x4000); - cfg_cmd.feedback_frequency = 1; - cfg_cmd.partition_number = 0; - (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); - -} - -static void audamrwb_send_data(struct audio *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - MM_DBG("frame %d busy\n", audio->out_tail); - audplay_dsp_send_data_avail(audio, audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } - done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ - -static void audamrwb_flush(struct audio *audio) -{ - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->reserved = 0; - audio->out_needed = 0; - atomic_set(&audio->out_bytes, 0); -} - -static void audamrwb_flush_pcm_buf(struct audio *audio) -{ - uint8_t index; - - for (index = 0; index < PCM_BUF_MAX_COUNT; index++) - audio->in[index].used = 0; - - audio->buf_refresh = 0; - audio->read_next = 0; - audio->fill_next = 0; -} - -static void audamrwb_ioport_reset(struct audio *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audamrwb_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->read_wait); - mutex_lock(&audio->read_lock); - audamrwb_flush_pcm_buf(audio); - mutex_unlock(&audio->read_lock); - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); -} - -static int audamrwb_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audamrwb_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audamrwb_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audamrwb_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audamrwb_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - -static long audamrwb_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audamrwb_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - audio->event_wait, audamrwb_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audamrwb_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - rc = 0; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audamrwb_event, list); - list_del(&drv_evt->list); - } - - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audio_enable_eq(struct audio *audio, int enable) -{ - if (audio->eq_enable == enable && !audio->eq_needs_commit) - return 0; - - audio->eq_enable = enable; - - if (audio->running) { - audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq, POPP); - audio->eq_needs_commit = 0; - } - return 0; -} - -static int audio_get_avsync_data(struct audio *audio, - struct msm_audio_stats *stats) -{ - int rc = -EINVAL; - unsigned long flags; - - local_irq_save(flags); - if (audio->dec_id == audio->avsync[0] && audio->avsync_flag) { - /* av_sync sample count */ - stats->sample_count = (audio->avsync[2] << 16) | - (audio->avsync[3]); - - /* av_sync byte_count */ - stats->byte_count = (audio->avsync[5] << 16) | - (audio->avsync[6]); - - audio->avsync_flag = 0; - rc = 0; - } - local_irq_restore(flags); - return rc; - -} - -static long audamrwb_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - unsigned long flags = 0; - uint16_t enable_mask; - int enable; - int prev_state; - - MM_DBG("cmd = %d\n", cmd); - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - - audio->avsync_flag = 0; - memset(&stats, 0, sizeof(stats)); - if (audpp_query_avsync(audio->dec_id) < 0) - return rc; - - rc = wait_event_interruptible_timeout(audio->avsync_wait, - (audio->avsync_flag == 1), - msecs_to_jiffies(AUDPP_AVSYNC_EVENT_TIMEOUT)); - - if (rc < 0) - return rc; - else if ((rc > 0) || ((rc == 0) && (audio->avsync_flag == 1))) { - if (audio_get_avsync_data(audio, &stats) < 0) - return rc; - - if (copy_to_user((void *)arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } else - return -EAGAIN; - } - - switch (cmd) { - case AUDIO_ENABLE_AUDPP: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - spin_lock_irqsave(&audio->dsp_lock, flags); - enable = (enable_mask & EQ_ENABLE) ? 1 : 0; - audio_enable_eq(audio, enable); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - case AUDIO_SET_VOLUME: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.volume = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_PAN: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.pan = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_EQ: - prev_state = audio->eq_enable; - audio->eq_enable = 0; - if (copy_from_user(&audio->eq.num_bands, (void *) arg, - sizeof(audio->eq) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) { - rc = -EFAULT; - break; - } - audio->eq_enable = prev_state; - audio->eq_needs_commit = 1; - rc = 0; - break; - } - - if (-EINVAL != rc) - return rc; - - if (cmd == AUDIO_GET_EVENT) { - MM_DBG("AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audamrwb_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audamrwb_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) - rc = -ENODEV; - else - rc = 0; - } - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audamrwb_disable(audio); - audio->stopped = 1; - audamrwb_ioport_reset(audio); - audio->stopped = 0; - break; - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audamrwb_ioport_reset(audio); - if (audio->running) { - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - case AUDIO_SET_CONFIG:{ - struct msm_audio_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.channel_count == 1) - config.channel_count = - AUDPP_CMD_PCM_INTF_MONO_V; - else if (config.channel_count == 2) - config.channel_count = - AUDPP_CMD_PCM_INTF_STEREO_V; - else - rc = -EINVAL; - audio->out_channel_mode = config.channel_count; - audio->out_sample_rate = config.sample_rate; - audio->mfield = config.meta_field; - rc = 0; - break; - } - case AUDIO_GET_CONFIG:{ - struct msm_audio_config config; - config.buffer_size = BUFSZ; - config.buffer_count = 2; - config.sample_rate = audio->out_sample_rate; - if (audio->out_channel_mode == - AUDPP_CMD_PCM_INTF_MONO_V) - config.channel_count = 1; - else - config.channel_count = 2; - config.meta_field = 0; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - - break; - } - case AUDIO_GET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - config.pcm_feedback = 0; - config.buffer_count = PCM_BUF_MAX_COUNT; - config.buffer_size = PCM_BUFSZ_MIN; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if ((config.buffer_count > PCM_BUF_MAX_COUNT) || - (config.buffer_count == 1)) - config.buffer_count = PCM_BUF_MAX_COUNT; - - if (config.buffer_size < PCM_BUFSZ_MIN) - config.buffer_size = PCM_BUFSZ_MIN; - - /* Check if pcm feedback is required */ - if ((config.pcm_feedback) && (!audio->read_data)) { - MM_DBG("allocate PCM buf %d\n", config.buffer_count * - config.buffer_size); - audio->read_phys = allocate_contiguous_ebi_nomap( - config.buffer_size * - config.buffer_count, - SZ_4K); - if (!audio->read_phys) { - rc = -ENOMEM; - break; - } - audio->map_v_read = ioremap( - audio->read_phys, - config.buffer_size * - config.buffer_count); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("Error could not map read" - " phys address\n"); - rc = -ENOMEM; - free_contiguous_memory_by_paddr( - audio->read_phys); - } else { - uint8_t index; - uint32_t offset = 0; - audio->read_data = audio->map_v_read; - audio->pcm_feedback = 1; - audio->buf_refresh = 0; - audio->pcm_buf_count = - config.buffer_count; - audio->read_next = 0; - audio->fill_next = 0; - - for (index = 0; - index < config.buffer_count; index++) { - audio->in[index].data = - audio->read_data + offset; - audio->in[index].addr = - audio->read_phys + offset; - audio->in[index].size = - config.buffer_size; - audio->in[index].used = 0; - offset += config.buffer_size; - } - MM_DBG("read buf: phy addr 0x%08x \ - kernel addr 0x%08x\n", - audio->read_phys, - (int)audio->read_data); - rc = 0; - } - } else { - rc = 0; - } - break; - } - case AUDIO_GET_SESSION_ID: - if (copy_to_user((void *) arg, &audio->dec_id, - sizeof(unsigned short))) - rc = -EFAULT; - else - rc = 0; - break; - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -static int audamrwb_fsync(struct file *file, loff_t ppos1, loff_t ppos2, int datasync) -{ - struct audio *audio = file->private_data; - struct buffer *frame; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (!audio->running || audio->pcm_feedback) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (audio->reserved) { - MM_DBG("send reserved byte\n"); - frame = audio->out + audio->out_tail; - ((char *) frame->data)[0] = audio->rsv_byte; - ((char *) frame->data)[1] = 0; - frame->used = 2; - audamrwb_send_data(audio, 0); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - } - - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush); - - if (audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; -} - -static ssize_t audamrwb_read(struct file *file, char __user *buf, size_t count, - loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - int rc = 0; - - if (!audio->pcm_feedback) - return 0; /* PCM feedback is not enabled. Nothing to read */ - - mutex_lock(&audio->read_lock); - MM_DBG("count %d\n", count); - while (count > 0) { - rc = wait_event_interruptible(audio->read_wait, - (audio->in[audio->read_next].used > 0) || - (audio->stopped) || (audio->rflush)); - - if (rc < 0) - break; - - if (audio->stopped || audio->rflush) { - rc = -EBUSY; - break; - } - - if (count < audio->in[audio->read_next].used) { - /* Read must happen in frame boundary. Since driver does - * not know frame size, read count must be greater or - * equal to size of PCM samples - */ - MM_DBG("read stop - partial frame\n"); - break; - } else { - MM_DBG("read from in[%d]\n", audio->read_next); - - if (copy_to_user - (buf, audio->in[audio->read_next].data, - audio->in[audio->read_next].used)) { - MM_ERR("invalid addr %x\n", (unsigned int)buf); - rc = -EFAULT; - break; - } - count -= audio->in[audio->read_next].used; - buf += audio->in[audio->read_next].used; - audio->in[audio->read_next].used = 0; - if ((++audio->read_next) == audio->pcm_buf_count) - audio->read_next = 0; - break; - } - } - - /* don't feed output buffer to HW decoder during flushing - * buffer refresh command will be sent once flush completes - * send buf refresh command here can confuse HW decoder - */ - if (audio->buf_refresh && !audio->rflush) { - audio->buf_refresh = 0; - MM_DBG("kick start pcm feedback again\n"); - audamrwb_buffer_refresh(audio); - } - - mutex_unlock(&audio->read_lock); - - if (buf > start) - rc = buf - start; - - MM_DBG("read %d bytes\n", rc); - return rc; -} - -static int audamrwb_process_eos(struct audio *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - struct buffer *frame; - char *buf_ptr; - int rc = 0; - - MM_DBG("signal input EOS reserved=%d\n", audio->reserved); - if (audio->reserved) { - MM_DBG("Pass reserve byte\n"); - frame = audio->out + audio->out_head; - buf_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - buf_ptr[0] = audio->rsv_byte; - buf_ptr[1] = 0; - audio->out_head ^= 1; - frame->mfield_sz = 0; - audio->reserved = 0; - frame->used = 2; - audamrwb_send_data(audio, 0); - } - - MM_DBG("Now signal input EOS after reserved bytes %d %d %d\n", - audio->out[0].used, audio->out[1].used, audio->out_needed); - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - audamrwb_send_data(audio, 0); - -done: - return rc; -} - -static ssize_t audamrwb_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - char *cpy_ptr; - int rc = 0, eos_condition = AUDAMRWB_EOS_NONE; - unsigned short mfield_size = 0; - unsigned dsize; - - MM_DBG("cnt=%d\n", count); - - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - cpy_ptr = frame->data; - dsize = 0; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - - MM_DBG("buffer available\n"); - if (rc < 0) - break; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - break; - } - - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - break; - } else if (mfield_size > count) { - rc = -EINVAL; - break; - } - MM_DBG("mf offset_val %x\n", mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - break; - } - /* Check if EOS flag is set and buffer - * contains just meta field - */ - if (cpy_ptr[AUDAMRWB_EOS_FLG_OFFSET] & - AUDAMRWB_EOS_FLG_MASK) { - MM_DBG("eos set\n"); - eos_condition = AUDAMRWB_EOS_SET; - if (mfield_size == count) { - buf += mfield_size; - break; - } else - cpy_ptr[AUDAMRWB_EOS_FLG_OFFSET] &= - ~AUDAMRWB_EOS_FLG_MASK; - } - cpy_ptr += mfield_size; - count -= mfield_size; - dsize += mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - - if (audio->reserved) { - MM_DBG("append reserved byte %x\n", audio->rsv_byte); - *cpy_ptr = audio->rsv_byte; - xfer = (count > ((frame->size - mfield_size) - 1)) ? - ((frame->size - mfield_size) - 1) : count; - cpy_ptr++; - dsize += 1; - audio->reserved = 0; - } else - xfer = (count > (frame->size - mfield_size)) ? - (frame->size - mfield_size) : count; - - if (copy_from_user(cpy_ptr, buf, xfer)) { - rc = -EFAULT; - break; - } - - dsize += xfer; - if (dsize & 1) { - audio->rsv_byte = ((char *) frame->data)[dsize - 1]; - MM_DBG("odd length buf reserve last byte %x\n", - audio->rsv_byte); - audio->reserved = 1; - dsize--; - } - count -= xfer; - buf += xfer; - - if (dsize > 0) { - audio->out_head ^= 1; - frame->used = dsize; - audamrwb_send_data(audio, 0); - } - } - MM_DBG("eos_condition %x buf[0x%x] start[0x%x]\n", eos_condition, - (int) buf, (int) start); - if (eos_condition == AUDAMRWB_EOS_SET) - rc = audamrwb_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - if (!rc) { - if (buf > start) - return buf - start; - } - return rc; -} - -static int audamrwb_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_INFO("audio instance 0x%08x freeing\n", (int)audio); - - mutex_lock(&audio->lock); - auddev_unregister_evt_listner(AUDDEV_CLNT_DEC, audio->dec_id); - audamrwb_disable(audio); - audamrwb_flush(audio); - audamrwb_flush_pcm_buf(audio); - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->event_abort = 1; - wake_up(&audio->event_wait); - audamrwb_reset_event_queue(audio); - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - if (audio->read_data) { - iounmap(audio->map_v_read); - free_contiguous_memory_by_paddr(audio->read_phys); - } - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - kfree(audio); - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audamrwb_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audamrwb_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audamrwb_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audamrwb_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -static void audamrwb_suspend(struct early_suspend *h) -{ - struct audamrwb_suspend_ctl *ctl = - container_of(h, struct audamrwb_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audamrwb_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audamrwb_resume(struct early_suspend *h) -{ - struct audamrwb_suspend_ctl *ctl = - container_of(h, struct audamrwb_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audamrwb_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audamrwb_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audamrwb_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 1024; - static char buffer[1024]; - int n = 0, i; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_feedback %d\n", audio->pcm_feedback); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_buf_sz %d\n", audio->out[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_count %d \n", audio->pcm_buf_count); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_sz %d \n", audio->in[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %x \n", audio->vol_pan.volume); - n += scnprintf(buffer + n, debug_bufmax - n, - "sample rate %d \n", audio->out_sample_rate); - n += scnprintf(buffer + n, debug_bufmax - n, - "channel mode %d \n", audio->out_channel_mode); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "rflush %d\n", audio->rflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d \n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d \n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d \n", audio->out_needed); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_head %d \n", audio->out_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_tail %d \n", audio->out_tail); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[0].used %d \n", audio->out[0].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[1].used %d \n", audio->out[1].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "buffer_refresh %d \n", audio->buf_refresh); - n += scnprintf(buffer + n, debug_bufmax - n, - "read_next %d \n", audio->read_next); - n += scnprintf(buffer + n, debug_bufmax - n, - "fill_next %d \n", audio->fill_next); - for (i = 0; i < audio->pcm_buf_count; i++) - n += scnprintf(buffer + n, debug_bufmax - n, - "in[%d].used %d \n", i, audio->in[i].used); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audamrwb_debug_fops = { - .read = audamrwb_debug_read, - .open = audamrwb_debug_open, -}; -#endif - -static int audamrwb_open(struct inode *inode, struct file *file) -{ - struct audio *audio = NULL; - int rc, dec_attrb, decid, i; - struct audamrwb_event *e_node = NULL; -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_amrwb_" + 5]; -#endif - - /* Allocate Mem for audio instance */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("no memory to allocate audio instance\n"); - rc = -ENOMEM; - goto done; - } - MM_INFO("audio instance 0x%08x created\n", (int)audio); - - /* Allocate the decoder */ - dec_attrb = AUDDEC_DEC_AMRWB; - if (file->f_mode & FMODE_READ) - dec_attrb |= MSM_AUD_MODE_NONTUNNEL; - else - dec_attrb |= MSM_AUD_MODE_TUNNEL; - - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - - if (decid < 0) { - MM_ERR("No free decoder available, freeing instance 0x%08x\n", - (int)audio); - rc = -ENODEV; - kfree(audio); - goto done; - } - - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - audio->phys = allocate_contiguous_ebi_nomap(DMASZ, SZ_4K); - if (!audio->phys) { - MM_ERR("could not allocate write buffers, freeing instance \ - 0x%08x\n", (int)audio); - rc = -ENOMEM; - audpp_adec_free(audio->dec_id); - kfree(audio); - goto done; - } else { - audio->map_v_write = ioremap(audio->phys, DMASZ); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write phys buffers, freeing \ - instance 0x%08x\n", (int)audio); - rc = -ENOMEM; - free_contiguous_memory_by_paddr(audio->phys); - audpp_adec_free(audio->dec_id); - kfree(audio); - goto done; - } - audio->data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->phys, (int)audio->data); - } - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audplay_adsp_ops_amrwb, audio); - if (rc) { - MM_ERR("failed to get %s module freeing instance 0x%08x\n", - audio->module_name, (int)audio); - goto err; - } - - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->read_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - spin_lock_init(&audio->event_queue_lock); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->write_wait); - init_waitqueue_head(&audio->read_wait); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - init_waitqueue_head(&audio->avsync_wait); - - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = BUFSZ; - - audio->out[1].data = audio->data + BUFSZ; - audio->out[1].addr = audio->phys + BUFSZ; - audio->out[1].size = BUFSZ; - - audio->vol_pan.volume = 0x2000; - audio->vol_pan.pan = 0x0; - audio->eq_enable = 0; - audio->out_sample_rate = 44100; - audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V; - - audamrwb_flush(audio); - - file->private_data = audio; - audio->opened = 1; - audio->event_abort = 0; - audio->device_events = AUDDEV_EVT_DEV_RDY - |AUDDEV_EVT_DEV_RLS| - AUDDEV_EVT_STREAM_VOL_CHG; - - rc = auddev_register_evt_listner(audio->device_events, - AUDDEV_CLNT_DEC, - audio->dec_id, - amrwb_listner, - (void *)audio); - if (rc) { - MM_ERR("failed to register listner\n"); - goto event_err; - } - -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_amrwb_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, &audamrwb_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audamrwb_resume; - audio->suspend_ctl.node.suspend = audamrwb_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (i = 0; i < AUDAMRWB_EVENT_NUM; i++) { - e_node = kmalloc(sizeof(struct audamrwb_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } -done: - return rc; -event_err: - msm_adsp_put(audio->audplay); -err: - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - audpp_adec_free(audio->dec_id); - kfree(audio); - return rc; -} - -static const struct file_operations audio_amrwb_fops = { - .owner = THIS_MODULE, - .open = audamrwb_open, - .release = audamrwb_release, - .read = audamrwb_read, - .write = audamrwb_write, - .unlocked_ioctl = audamrwb_ioctl, - .fsync = audamrwb_fsync, -}; - -struct miscdevice audio_amrwb_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_amrwb", - .fops = &audio_amrwb_fops, -}; - -static int __init audamrwb_init(void) -{ - return misc_register(&audio_amrwb_misc); -} - -static void __exit audamrwb_exit(void) -{ - misc_deregister(&audio_amrwb_misc); -} - -module_init(audamrwb_init); -module_exit(audamrwb_exit); - -MODULE_DESCRIPTION("MSM AMR-WB driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_dev_ctl.c b/arch/arm/mach-msm/qdsp5v2/audio_dev_ctl.c deleted file mode 100644 index b1446e82cc48a2f749b4c2bdb82b0f340acc0c2f..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_dev_ctl.c +++ /dev/null @@ -1,1328 +0,0 @@ -/* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef MAX -#define MAX(x, y) (((x) > (y)) ? (x) : (y)) -#endif - - -static DEFINE_MUTEX(session_lock); - -struct audio_dev_ctrl_state { - struct msm_snddev_info *devs[AUDIO_DEV_CTL_MAX_DEV]; - u32 num_dev; - atomic_t opened; - struct msm_snddev_info *voice_rx_dev; - struct msm_snddev_info *voice_tx_dev; - wait_queue_head_t wait; -}; - -static struct audio_dev_ctrl_state audio_dev_ctrl; -struct event_listner event; -#define MAX_DEC_SESSIONS 7 -#define MAX_ENC_SESSIONS 3 - -struct session_freq { - int freq; - int evt; -}; - - -struct audio_routing_info { - unsigned short mixer_mask[MAX_DEC_SESSIONS]; - unsigned short audrec_mixer_mask[MAX_ENC_SESSIONS]; - struct session_freq dec_freq[MAX_DEC_SESSIONS]; - struct session_freq enc_freq[MAX_ENC_SESSIONS]; - int dual_mic_setting[MAX_ENC_SESSIONS]; - int voice_tx_dev_id; - int voice_rx_dev_id; - int voice_tx_sample_rate; - int voice_rx_sample_rate; - signed int voice_tx_vol; - signed int voice_rx_vol; - int tx_mute; - int rx_mute; - int voice_state; -}; - -static struct audio_routing_info routing_info; - -#ifdef CONFIG_DEBUG_FS - -static struct dentry *dentry; -static int rtc_getdevice_dbg_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - MM_INFO("debug intf %s\n", (char *) file->private_data); - return 0; -} -bool is_dev_opened(u32 adb_id) -{ - - int dev_id = 0; - struct msm_snddev_info *dev_info = NULL; - - for (dev_id = 0; dev_id < audio_dev_ctrl.num_dev; dev_id++) { - dev_info = audio_dev_ctrl_find_dev(dev_id); - if (IS_ERR(dev_info)) { - MM_ERR("pass invalid dev_id %d\n", dev_id); - return false; - } - if (dev_info->opened && (dev_info->acdb_id == adb_id)) - return true; - } - - return false; -} -static ssize_t rtc_getdevice_dbg_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - static char buffer[1024]; - static char swap_buf[1024]; - const int debug_bufmax = sizeof(buffer); - int n = 0; - int swap_count = 0; - int rc = 0; - int dev_count = 0; - int dev_id = 0; - struct msm_snddev_info *dev_info = NULL; - - - if (audio_dev_ctrl.num_dev <= 0) { - MM_ERR("Invalid no Device present\n"); - dev_count = 0; - n = scnprintf(buffer, debug_bufmax, "DEV_NO:0x%x\n", dev_count); - } else { - for (dev_id = 0; dev_id < audio_dev_ctrl.num_dev; dev_id++) { - dev_info = audio_dev_ctrl_find_dev(dev_id); - if (IS_ERR(dev_info)) { - MM_ERR("pass invalid dev_id %d\n", dev_id); - rc = PTR_ERR(dev_info); - return rc; - } - if (dev_info->opened) { - n += scnprintf(swap_buf + n, debug_bufmax - n, - "ACDB_ID:0x%x;CAPB:0x%x\n", - dev_info->acdb_id, - dev_info->capability); - dev_count++; - MM_DBG("RTC Get Device %x COPP %x Session Mask \ - %x Capb %x Dev Count %x\n", - dev_id , dev_info->copp_id, dev_info->sessions, - dev_info->capability, dev_count); - - } - } - - swap_count = scnprintf(buffer, debug_bufmax, \ - "DEV_NO:0x%x\n", dev_count); - - memcpy(buffer+swap_count, swap_buf, n*sizeof(char)); - n = n+swap_count; - - buffer[n] = 0; - } - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations rtc_acdb_debug_fops = { - .open = rtc_getdevice_dbg_open, - .read = rtc_getdevice_dbg_read -}; -#endif -int msm_reset_all_device(void) -{ - int rc = 0; - int dev_id = 0; - struct msm_snddev_info *dev_info = NULL; - - for (dev_id = 0; dev_id < audio_dev_ctrl.num_dev; dev_id++) { - dev_info = audio_dev_ctrl_find_dev(dev_id); - if (IS_ERR(dev_info)) { - MM_ERR("pass invalid dev_id %d\n", dev_id); - rc = PTR_ERR(dev_info); - return rc; - } - if (!dev_info->opened) - continue; - MM_DBG("Resetting device %d active on COPP %d" - "with 0x%08x as routing\n", - dev_id, dev_info->copp_id, dev_info->sessions); - broadcast_event(AUDDEV_EVT_REL_PENDING, - dev_id, - SESSION_IGNORE); - rc = dev_info->dev_ops.close(dev_info); - if (rc < 0) { - MM_ERR("Snd device %d failed close!\n", dev_id); - return rc; - } else { - dev_info->opened = 0; - broadcast_event(AUDDEV_EVT_DEV_RLS, - dev_id, - SESSION_IGNORE); - } - dev_info->sessions = 0; - } - return 0; -} -EXPORT_SYMBOL(msm_reset_all_device); - -int msm_set_dual_mic_config(int enc_session_id, int config) -{ - int i; - if (enc_session_id >= MAX_ENC_SESSIONS) - return -EINVAL; - /*config is set(1) dual mic recording is selected */ - /*config is reset (0) dual mic recording is not selected*/ - routing_info.dual_mic_setting[enc_session_id] = config; - for (i = 0; i < MAX_ENC_SESSIONS; i++) - MM_DBG("dual_mic_setting[%d] = %d\n", - i, routing_info.dual_mic_setting[i]); - return 0; -} -EXPORT_SYMBOL(msm_set_dual_mic_config); - -int msm_get_dual_mic_config(int enc_session_id) -{ - if (enc_session_id >= MAX_ENC_SESSIONS) - return -EINVAL; - return routing_info.dual_mic_setting[enc_session_id]; -} -EXPORT_SYMBOL(msm_get_dual_mic_config); - -int msm_get_voice_state(void) -{ - MM_DBG("voice state %d\n", routing_info.voice_state); - return routing_info.voice_state; -} -EXPORT_SYMBOL(msm_get_voice_state); - -int msm_set_voice_mute(int dir, int mute) -{ - MM_DBG("dir %x mute %x\n", dir, mute); - if (!audio_dev_ctrl.voice_rx_dev - || !audio_dev_ctrl.voice_tx_dev) - return -EPERM; - if (dir == DIR_TX) { - routing_info.tx_mute = mute; - broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG, - routing_info.voice_tx_dev_id, SESSION_IGNORE); - } else - return -EPERM; - return 0; -} -EXPORT_SYMBOL(msm_set_voice_mute); - -int msm_set_voice_vol(int dir, s32 volume) -{ - if (!audio_dev_ctrl.voice_rx_dev - || !audio_dev_ctrl.voice_tx_dev) - return -EPERM; - if (dir == DIR_TX) { - routing_info.voice_tx_vol = volume; - broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG, - routing_info.voice_tx_dev_id, - SESSION_IGNORE); - } else if (dir == DIR_RX) { - routing_info.voice_rx_vol = volume; - broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG, - routing_info.voice_rx_dev_id, - SESSION_IGNORE); - } else - return -EINVAL; - return 0; -} -EXPORT_SYMBOL(msm_set_voice_vol); - -void msm_snddev_register(struct msm_snddev_info *dev_info) -{ - mutex_lock(&session_lock); - if (audio_dev_ctrl.num_dev < AUDIO_DEV_CTL_MAX_DEV) { - audio_dev_ctrl.devs[audio_dev_ctrl.num_dev] = dev_info; - dev_info->dev_volume = 50; /* 50% */ - dev_info->sessions = 0x0; - dev_info->usage_count = 0; - dev_info->set_sample_rate = 0; - audio_dev_ctrl.num_dev++; - } else - MM_ERR("%s: device registry max out\n", __func__); - mutex_unlock(&session_lock); -} -EXPORT_SYMBOL(msm_snddev_register); - -int msm_snddev_devcount(void) -{ - return audio_dev_ctrl.num_dev; -} -EXPORT_SYMBOL(msm_snddev_devcount); - -int msm_snddev_query(int dev_id) -{ - if (dev_id <= audio_dev_ctrl.num_dev) - return 0; - return -ENODEV; -} -EXPORT_SYMBOL(msm_snddev_query); - -int msm_snddev_is_set(int popp_id, int copp_id) -{ - return routing_info.mixer_mask[popp_id] & (0x1 << copp_id); -} -EXPORT_SYMBOL(msm_snddev_is_set); - -unsigned short msm_snddev_route_enc(int enc_id) -{ - if (enc_id >= MAX_ENC_SESSIONS) - return -EINVAL; - return routing_info.audrec_mixer_mask[enc_id]; -} -EXPORT_SYMBOL(msm_snddev_route_enc); - -unsigned short msm_snddev_route_dec(int popp_id) -{ - if (popp_id >= MAX_DEC_SESSIONS) - return -EINVAL; - return routing_info.mixer_mask[popp_id]; -} -EXPORT_SYMBOL(msm_snddev_route_dec); - -int msm_snddev_set_dec(int popp_id, int copp_id, int set) -{ - if (set) - routing_info.mixer_mask[popp_id] |= (0x1 << copp_id); - else - routing_info.mixer_mask[popp_id] &= ~(0x1 << copp_id); - - return 0; -} -EXPORT_SYMBOL(msm_snddev_set_dec); - -int msm_snddev_set_enc(int popp_id, int copp_id, int set) -{ - if (set) - routing_info.audrec_mixer_mask[popp_id] |= (0x1 << copp_id); - else - routing_info.audrec_mixer_mask[popp_id] &= ~(0x1 << copp_id); - return 0; -} -EXPORT_SYMBOL(msm_snddev_set_enc); - -int msm_device_is_voice(int dev_id) -{ - if ((dev_id == routing_info.voice_rx_dev_id) - || (dev_id == routing_info.voice_tx_dev_id)) - return 0; - else - return -EINVAL; -} -EXPORT_SYMBOL(msm_device_is_voice); - -int msm_set_voc_route(struct msm_snddev_info *dev_info, - int stream_type, int dev_id) -{ - int rc = 0; - u32 session_mask = 0; - - mutex_lock(&session_lock); - switch (stream_type) { - case AUDIO_ROUTE_STREAM_VOICE_RX: - if (audio_dev_ctrl.voice_rx_dev) - audio_dev_ctrl.voice_rx_dev->sessions &= ~0xFF; - - if (!(dev_info->capability & SNDDEV_CAP_RX) | - !(dev_info->capability & SNDDEV_CAP_VOICE)) { - rc = -EINVAL; - break; - } - audio_dev_ctrl.voice_rx_dev = dev_info; - if (audio_dev_ctrl.voice_rx_dev) { - session_mask = - 0x1 << (8 * ((int)AUDDEV_CLNT_VOC-1)); - audio_dev_ctrl.voice_rx_dev->sessions |= - session_mask; - } - routing_info.voice_rx_dev_id = dev_id; - break; - case AUDIO_ROUTE_STREAM_VOICE_TX: - if (audio_dev_ctrl.voice_tx_dev) - audio_dev_ctrl.voice_tx_dev->sessions &= ~0xFF; - - if (!(dev_info->capability & SNDDEV_CAP_TX) | - !(dev_info->capability & SNDDEV_CAP_VOICE)) { - rc = -EINVAL; - break; - } - - audio_dev_ctrl.voice_tx_dev = dev_info; - if (audio_dev_ctrl.voice_rx_dev) { - session_mask = - 0x1 << (8 * ((int)AUDDEV_CLNT_VOC-1)); - audio_dev_ctrl.voice_tx_dev->sessions |= - session_mask; - } - routing_info.voice_tx_dev_id = dev_id; - break; - default: - rc = -EINVAL; - } - mutex_unlock(&session_lock); - return rc; -} -EXPORT_SYMBOL(msm_set_voc_route); - -void msm_release_voc_thread(void) -{ - wake_up(&audio_dev_ctrl.wait); -} -EXPORT_SYMBOL(msm_release_voc_thread); - -int msm_snddev_get_enc_freq(session_id) -{ - return routing_info.enc_freq[session_id].freq; -} -EXPORT_SYMBOL(msm_snddev_get_enc_freq); - -int msm_get_voc_freq(int *tx_freq, int *rx_freq) -{ - *tx_freq = routing_info.voice_tx_sample_rate; - *rx_freq = routing_info.voice_rx_sample_rate; - return 0; -} -EXPORT_SYMBOL(msm_get_voc_freq); - -int msm_get_voc_route(u32 *rx_id, u32 *tx_id) -{ - int rc = 0; - - if (!rx_id || !tx_id) - return -EINVAL; - - mutex_lock(&session_lock); - if (!audio_dev_ctrl.voice_rx_dev || !audio_dev_ctrl.voice_tx_dev) { - rc = -ENODEV; - mutex_unlock(&session_lock); - return rc; - } - - *rx_id = audio_dev_ctrl.voice_rx_dev->acdb_id; - *tx_id = audio_dev_ctrl.voice_tx_dev->acdb_id; - - mutex_unlock(&session_lock); - - return rc; -} -EXPORT_SYMBOL(msm_get_voc_route); - -struct msm_snddev_info *audio_dev_ctrl_find_dev(u32 dev_id) -{ - struct msm_snddev_info *info; - - if ((audio_dev_ctrl.num_dev - 1) < dev_id) { - info = ERR_PTR(-ENODEV); - goto error; - } - - info = audio_dev_ctrl.devs[dev_id]; -error: - return info; - -} -EXPORT_SYMBOL(audio_dev_ctrl_find_dev); - -int snddev_voice_set_volume(int vol, int path) -{ - if (audio_dev_ctrl.voice_rx_dev - && audio_dev_ctrl.voice_tx_dev) { - if (path) - audio_dev_ctrl.voice_tx_dev->dev_volume = vol; - else - audio_dev_ctrl.voice_rx_dev->dev_volume = vol; - } else - return -ENODEV; - return 0; -} -EXPORT_SYMBOL(snddev_voice_set_volume); - -static int audio_dev_ctrl_get_devices(struct audio_dev_ctrl_state *dev_ctrl, - void __user *arg) -{ - int rc = 0; - u32 index; - struct msm_snd_device_list work_list; - struct msm_snd_device_info *work_tbl; - - if (copy_from_user(&work_list, arg, sizeof(work_list))) { - rc = -EFAULT; - goto error; - } - - if (work_list.num_dev > dev_ctrl->num_dev) { - rc = -EINVAL; - goto error; - } - - work_tbl = kmalloc(work_list.num_dev * - sizeof(struct msm_snd_device_info), GFP_KERNEL); - if (!work_tbl) { - rc = -ENOMEM; - goto error; - } - - for (index = 0; index < dev_ctrl->num_dev; index++) { - work_tbl[index].dev_id = index; - work_tbl[index].dev_cap = dev_ctrl->devs[index]->capability; - strlcpy(work_tbl[index].dev_name, dev_ctrl->devs[index]->name, - 64); - } - - if (copy_to_user((void *) (work_list.list), work_tbl, - work_list.num_dev * sizeof(struct msm_snd_device_info))) - rc = -EFAULT; - kfree(work_tbl); -error: - return rc; -} - - -int auddev_register_evt_listner(u32 evt_id, u32 clnt_type, u32 clnt_id, - void (*listner)(u32 evt_id, - union auddev_evt_data *evt_payload, - void *private_data), - void *private_data) -{ - int rc; - struct msm_snd_evt_listner *callback = NULL; - struct msm_snd_evt_listner *new_cb; - - new_cb = kzalloc(sizeof(struct msm_snd_evt_listner), GFP_KERNEL); - if (!new_cb) { - MM_ERR("No memory to add new listener node\n"); - return -ENOMEM; - } - - mutex_lock(&session_lock); - new_cb->cb_next = NULL; - new_cb->auddev_evt_listener = listner; - new_cb->evt_id = evt_id; - new_cb->clnt_type = clnt_type; - new_cb->clnt_id = clnt_id; - new_cb->private_data = private_data; - if (event.cb == NULL) { - event.cb = new_cb; - new_cb->cb_prev = NULL; - } else { - callback = event.cb; - for (; ;) { - if (callback->cb_next == NULL) - break; - else { - callback = callback->cb_next; - continue; - } - } - callback->cb_next = new_cb; - new_cb->cb_prev = callback; - } - event.num_listner++; - mutex_unlock(&session_lock); - rc = 0; - return rc; -} -EXPORT_SYMBOL(auddev_register_evt_listner); - -int auddev_unregister_evt_listner(u32 clnt_type, u32 clnt_id) -{ - struct msm_snd_evt_listner *callback = event.cb; - struct msm_snddev_info *info; - u32 session_mask = 0; - int i = 0; - - mutex_lock(&session_lock); - while (callback != NULL) { - if ((callback->clnt_type == clnt_type) - && (callback->clnt_id == clnt_id)) - break; - callback = callback->cb_next; - } - if (callback == NULL) { - mutex_unlock(&session_lock); - return -EINVAL; - } - - if ((callback->cb_next == NULL) && (callback->cb_prev == NULL)) - event.cb = NULL; - else if (callback->cb_next == NULL) - callback->cb_prev->cb_next = NULL; - else if (callback->cb_prev == NULL) { - callback->cb_next->cb_prev = NULL; - event.cb = callback->cb_next; - } else { - callback->cb_prev->cb_next = callback->cb_next; - callback->cb_next->cb_prev = callback->cb_prev; - } - kfree(callback); - - session_mask = (0x1 << (clnt_id)) << (8 * ((int)clnt_type-1)); - for (i = 0; i < audio_dev_ctrl.num_dev; i++) { - info = audio_dev_ctrl.devs[i]; - info->sessions &= ~session_mask; - } - if (clnt_type == AUDDEV_CLNT_ENC) - msm_set_dual_mic_config(clnt_id, 0); - mutex_unlock(&session_lock); - return 0; -} -EXPORT_SYMBOL(auddev_unregister_evt_listner); - -int msm_snddev_withdraw_freq(u32 session_id, u32 capability, u32 clnt_type) -{ - int i = 0; - struct msm_snddev_info *info; - u32 session_mask = 0; - - if ((clnt_type == AUDDEV_CLNT_VOC) && (session_id != 0)) - return -EINVAL; - if ((clnt_type == AUDDEV_CLNT_DEC) - && (session_id >= MAX_DEC_SESSIONS)) - return -EINVAL; - if ((clnt_type == AUDDEV_CLNT_ENC) - && (session_id >= MAX_ENC_SESSIONS)) - return -EINVAL; - - session_mask = (0x1 << (session_id)) << (8 * ((int)clnt_type-1)); - - for (i = 0; i < audio_dev_ctrl.num_dev; i++) { - info = audio_dev_ctrl.devs[i]; - if ((info->sessions & session_mask) - && (info->capability & capability)) { - if (!(info->sessions & ~(session_mask))) - info->set_sample_rate = 0; - } - } - if (clnt_type == AUDDEV_CLNT_DEC) - routing_info.dec_freq[session_id].freq - = 0; - else if (clnt_type == AUDDEV_CLNT_ENC) - routing_info.enc_freq[session_id].freq - = 0; - else if (capability == SNDDEV_CAP_TX) - routing_info.voice_tx_sample_rate = 0; - else - routing_info.voice_rx_sample_rate = 48000; - return 0; -} - -int msm_snddev_request_freq(int *freq, u32 session_id, - u32 capability, u32 clnt_type) -{ - int i = 0; - int rc = 0; - struct msm_snddev_info *info; - u32 set_freq; - u32 session_mask = 0; - u32 clnt_type_mask = 0; - - MM_DBG(": clnt_type 0x%08x\n", clnt_type); - - if ((clnt_type == AUDDEV_CLNT_VOC) && (session_id != 0)) - return -EINVAL; - if ((clnt_type == AUDDEV_CLNT_DEC) - && (session_id >= MAX_DEC_SESSIONS)) - return -EINVAL; - if ((clnt_type == AUDDEV_CLNT_ENC) - && (session_id >= MAX_ENC_SESSIONS)) - return -EINVAL; - session_mask = ((0x1 << session_id)) << (8 * (clnt_type-1)); - clnt_type_mask = (0xFF << (8 * (clnt_type-1))); - if (!(*freq == 8000) && !(*freq == 11025) && - !(*freq == 12000) && !(*freq == 16000) && - !(*freq == 22050) && !(*freq == 24000) && - !(*freq == 32000) && !(*freq == 44100) && - !(*freq == 48000)) - return -EINVAL; - - for (i = 0; i < audio_dev_ctrl.num_dev; i++) { - info = audio_dev_ctrl.devs[i]; - if ((info->sessions & session_mask) - && (info->capability & capability)) { - rc = 0; - if ((info->sessions & ~clnt_type_mask) - && ((*freq != 8000) && (*freq != 16000) - && (*freq != 48000))) { - if (clnt_type == AUDDEV_CLNT_ENC) { - routing_info.enc_freq[session_id].freq - = 0; - return -EPERM; - } else if (clnt_type == AUDDEV_CLNT_DEC) { - routing_info.dec_freq[session_id].freq - = 0; - return -EPERM; - } - } - if (*freq == info->set_sample_rate) { - rc = info->set_sample_rate; - continue; - } - set_freq = MAX(*freq, info->set_sample_rate); - - - if (clnt_type == AUDDEV_CLNT_DEC) - routing_info.dec_freq[session_id].freq - = set_freq; - else if (clnt_type == AUDDEV_CLNT_ENC) - routing_info.enc_freq[session_id].freq - = set_freq; - else if (capability == SNDDEV_CAP_TX) - routing_info.voice_tx_sample_rate = set_freq; - - rc = set_freq; - *freq = set_freq; - /* There is difference in device sample rate to - * requested sample rate. So update device sample rate - * and propagate sample rate change event to active - * sessions of the device. - */ - if (info->set_sample_rate != set_freq) { - info->set_sample_rate = set_freq; - if (info->opened) { - /* Ignore propagating sample rate - * change event to requested client - * session - */ - if (clnt_type == AUDDEV_CLNT_DEC) - routing_info.\ - dec_freq[session_id].evt = 1; - else if (clnt_type == AUDDEV_CLNT_ENC) - routing_info.\ - enc_freq[session_id].evt = 1; - broadcast_event(AUDDEV_EVT_FREQ_CHG, i, - SESSION_IGNORE); - set_freq = info->dev_ops.set_freq(info, - set_freq); - broadcast_event(AUDDEV_EVT_DEV_RDY, i, - SESSION_IGNORE); - } - } - } - MM_DBG("info->set_sample_rate = %d\n", info->set_sample_rate); - MM_DBG("routing_info.enc_freq.freq = %d\n", - routing_info.enc_freq[session_id].freq); - } - return rc; -} -EXPORT_SYMBOL(msm_snddev_request_freq); - -int msm_snddev_enable_sidetone(u32 dev_id, u32 enable) -{ - int rc; - struct msm_snddev_info *dev_info; - - MM_DBG("dev_id %d enable %d\n", dev_id, enable); - - dev_info = audio_dev_ctrl_find_dev(dev_id); - - if (IS_ERR(dev_info)) { - MM_ERR("bad dev_id %d\n", dev_id); - rc = -EINVAL; - } else if (!dev_info->dev_ops.enable_sidetone) { - MM_DBG("dev %d no sidetone support\n", dev_id); - rc = -EPERM; - } else - rc = dev_info->dev_ops.enable_sidetone(dev_info, enable); - - return rc; -} -EXPORT_SYMBOL(msm_snddev_enable_sidetone); - -static long audio_dev_ctrl_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - int rc = 0; - struct audio_dev_ctrl_state *dev_ctrl = file->private_data; - - mutex_lock(&session_lock); - switch (cmd) { - case AUDIO_GET_NUM_SND_DEVICE: - rc = put_user(dev_ctrl->num_dev, (uint32_t __user *) arg); - break; - case AUDIO_GET_SND_DEVICES: - rc = audio_dev_ctrl_get_devices(dev_ctrl, (void __user *) arg); - break; - case AUDIO_ENABLE_SND_DEVICE: { - struct msm_snddev_info *dev_info; - u32 dev_id; - - if (get_user(dev_id, (u32 __user *) arg)) { - rc = -EFAULT; - break; - } - dev_info = audio_dev_ctrl_find_dev(dev_id); - if (IS_ERR(dev_info)) - rc = PTR_ERR(dev_info); - else { - rc = dev_info->dev_ops.open(dev_info); - if (!rc) - dev_info->opened = 1; - wake_up(&audio_dev_ctrl.wait); - } - break; - - } - - case AUDIO_DISABLE_SND_DEVICE: { - struct msm_snddev_info *dev_info; - u32 dev_id; - - if (get_user(dev_id, (u32 __user *) arg)) { - rc = -EFAULT; - break; - } - dev_info = audio_dev_ctrl_find_dev(dev_id); - if (IS_ERR(dev_info)) - rc = PTR_ERR(dev_info); - else { - rc = dev_info->dev_ops.close(dev_info); - dev_info->opened = 0; - } - break; - } - - case AUDIO_ROUTE_STREAM: { - struct msm_audio_route_config route_cfg; - struct msm_snddev_info *dev_info; - - if (copy_from_user(&route_cfg, (void __user *) arg, - sizeof(struct msm_audio_route_config))) { - rc = -EFAULT; - break; - } - MM_DBG("%s: route cfg %d %d type\n", __func__, - route_cfg.dev_id, route_cfg.stream_type); - dev_info = audio_dev_ctrl_find_dev(route_cfg.dev_id); - if (IS_ERR(dev_info)) { - MM_ERR("%s: pass invalid dev_id\n", __func__); - rc = PTR_ERR(dev_info); - break; - } - - switch (route_cfg.stream_type) { - - case AUDIO_ROUTE_STREAM_VOICE_RX: - if (!(dev_info->capability & SNDDEV_CAP_RX) | - !(dev_info->capability & SNDDEV_CAP_VOICE)) { - rc = -EINVAL; - break; - } - dev_ctrl->voice_rx_dev = dev_info; - break; - case AUDIO_ROUTE_STREAM_VOICE_TX: - if (!(dev_info->capability & SNDDEV_CAP_TX) | - !(dev_info->capability & SNDDEV_CAP_VOICE)) { - rc = -EINVAL; - break; - } - dev_ctrl->voice_tx_dev = dev_info; - break; - } - break; - } - - default: - rc = -EINVAL; - } - mutex_unlock(&session_lock); - return rc; -} - -static int audio_dev_ctrl_open(struct inode *inode, struct file *file) -{ - MM_DBG("open audio_dev_ctrl\n"); - atomic_inc(&audio_dev_ctrl.opened); - file->private_data = &audio_dev_ctrl; - return 0; -} - -static int audio_dev_ctrl_release(struct inode *inode, struct file *file) -{ - MM_DBG("release audio_dev_ctrl\n"); - atomic_dec(&audio_dev_ctrl.opened); - return 0; -} - -static const struct file_operations audio_dev_ctrl_fops = { - .owner = THIS_MODULE, - .open = audio_dev_ctrl_open, - .release = audio_dev_ctrl_release, - .unlocked_ioctl = audio_dev_ctrl_ioctl, -}; - - -struct miscdevice audio_dev_ctrl_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_audio_dev_ctrl", - .fops = &audio_dev_ctrl_fops, -}; - -/* session id is 32 bit routing mask per device - * 0-7 for voice clients - * 8-15 for Decoder clients - * 16-23 for Encoder clients - * 24-31 Do not care - */ -void broadcast_event(u32 evt_id, u32 dev_id, u32 session_id) -{ - int clnt_id = 0, i; - union auddev_evt_data *evt_payload; - struct msm_snd_evt_listner *callback; - struct msm_snddev_info *dev_info = NULL; - u32 session_mask = 0; - static int pending_sent; - - MM_DBG(": evt_id = %d\n", evt_id); - - if ((evt_id != AUDDEV_EVT_START_VOICE) - && (evt_id != AUDDEV_EVT_END_VOICE) - && (evt_id != AUDDEV_EVT_STREAM_VOL_CHG) - && (evt_id != AUDDEV_EVT_VOICE_STATE_CHG)) { - dev_info = audio_dev_ctrl_find_dev(dev_id); - if (IS_ERR(dev_info)) { - MM_ERR("pass invalid dev_id\n"); - return; - } - } - - if (event.cb != NULL) - callback = event.cb; - else - return; - - evt_payload = kzalloc(sizeof(union auddev_evt_data), - GFP_KERNEL); - if (evt_payload == NULL) { - MM_ERR("Memory allocation for event payload failed\n"); - return; - } - - mutex_lock(&session_lock); - - if (evt_id == AUDDEV_EVT_VOICE_STATE_CHG) - routing_info.voice_state = dev_id; - - for (; ;) { - if (!(evt_id & callback->evt_id)) { - if (callback->cb_next == NULL) - break; - else { - callback = callback->cb_next; - continue; - } - } - clnt_id = callback->clnt_id; - memset(evt_payload, 0, sizeof(union auddev_evt_data)); - - if ((evt_id == AUDDEV_EVT_START_VOICE) - || (evt_id == AUDDEV_EVT_END_VOICE)) - goto skip_check; - if (callback->clnt_type == AUDDEV_CLNT_AUDIOCAL) - goto aud_cal; - - session_mask = (0x1 << (clnt_id)) - << (8 * ((int)callback->clnt_type-1)); - - if ((evt_id == AUDDEV_EVT_STREAM_VOL_CHG) || \ - (evt_id == AUDDEV_EVT_VOICE_STATE_CHG)) { - MM_DBG("AUDDEV_EVT_STREAM_VOL_CHG or\ - AUDDEV_EVT_VOICE_STATE_CHG\n"); - goto volume_strm; - } - - MM_DBG("dev_info->sessions = %08x\n", dev_info->sessions); - - if ((!session_id && !(dev_info->sessions & session_mask)) || - (session_id && ((dev_info->sessions & session_mask) != - session_id))) { - if (callback->cb_next == NULL) - break; - else { - callback = callback->cb_next; - continue; - } - } - if (evt_id == AUDDEV_EVT_DEV_CHG_VOICE) - goto voc_events; - -volume_strm: - if (callback->clnt_type == AUDDEV_CLNT_DEC) { - MM_DBG("AUDDEV_CLNT_DEC\n"); - if (evt_id == AUDDEV_EVT_STREAM_VOL_CHG) { - MM_DBG("clnt_id = %d, session_id = 0x%8x\n", - clnt_id, session_id); - if (session_mask != session_id) - goto sent_dec; - else - evt_payload->session_vol = - msm_vol_ctl.volume; - } else if (evt_id == AUDDEV_EVT_FREQ_CHG) { - if (routing_info.dec_freq[clnt_id].evt) { - routing_info.dec_freq[clnt_id].evt - = 0; - goto sent_dec; - } else if (routing_info.dec_freq[clnt_id].freq - == dev_info->set_sample_rate) - goto sent_dec; - else { - evt_payload->freq_info.sample_rate - = dev_info->set_sample_rate; - evt_payload->freq_info.dev_type - = dev_info->capability; - evt_payload->freq_info.acdb_dev_id - = dev_info->acdb_id; - } - /* Propogate device information to client */ - } else if (evt_id == AUDDEV_EVT_DEVICE_INFO) { - evt_payload->devinfo.dev_id - = dev_info->copp_id; - evt_payload->devinfo.acdb_id - = dev_info->acdb_id; - evt_payload->devinfo.dev_type = - (dev_info->capability & SNDDEV_CAP_TX) ? - SNDDEV_CAP_TX : SNDDEV_CAP_RX; - evt_payload->devinfo.sample_rate - = dev_info->sample_rate; - if (session_id == SESSION_IGNORE) - evt_payload->devinfo.sessions - = dev_info->sessions; - else - evt_payload->devinfo.sessions - = session_id; - evt_payload->devinfo.sessions = - (evt_payload->devinfo.sessions >> - ((AUDDEV_CLNT_DEC-1) * 8)); - } else if (evt_id == AUDDEV_EVT_VOICE_STATE_CHG) - evt_payload->voice_state = - routing_info.voice_state; - else - evt_payload->routing_id = dev_info->copp_id; - callback->auddev_evt_listener( - evt_id, - evt_payload, - callback->private_data); -sent_dec: - if ((evt_id != AUDDEV_EVT_STREAM_VOL_CHG) && - (evt_id != AUDDEV_EVT_VOICE_STATE_CHG)) - routing_info.dec_freq[clnt_id].freq - = dev_info->set_sample_rate; - - if (callback->cb_next == NULL) - break; - else { - callback = callback->cb_next; - continue; - } - } - if (callback->clnt_type == AUDDEV_CLNT_ENC) { - - MM_DBG("AUDDEV_CLNT_ENC\n"); - if (evt_id == AUDDEV_EVT_FREQ_CHG) { - if (routing_info.enc_freq[clnt_id].evt) { - routing_info.enc_freq[clnt_id].evt - = 0; - goto sent_enc; - } else { - evt_payload->freq_info.sample_rate - = dev_info->set_sample_rate; - evt_payload->freq_info.dev_type - = dev_info->capability; - evt_payload->freq_info.acdb_dev_id - = dev_info->acdb_id; - } - /* Propogate device information to client */ - } else if (evt_id == AUDDEV_EVT_DEVICE_INFO) { - evt_payload->devinfo.dev_id - = dev_info->copp_id; - evt_payload->devinfo.acdb_id - = dev_info->acdb_id; - evt_payload->devinfo.dev_type = - (dev_info->capability & SNDDEV_CAP_TX) ? - SNDDEV_CAP_TX : SNDDEV_CAP_RX; - evt_payload->devinfo.sample_rate - = dev_info->sample_rate; - if (session_id == SESSION_IGNORE) - evt_payload->devinfo.sessions - = dev_info->sessions; - else - evt_payload->devinfo.sessions - = session_id; - evt_payload->devinfo.sessions = - (evt_payload->devinfo.sessions >> - ((AUDDEV_CLNT_ENC-1) * 8)); - } else if (evt_id == AUDDEV_EVT_VOICE_STATE_CHG) - evt_payload->voice_state = - routing_info.voice_state; - else - evt_payload->routing_id = dev_info->copp_id; - callback->auddev_evt_listener( - evt_id, - evt_payload, - callback->private_data); -sent_enc: - if (callback->cb_next == NULL) - break; - else { - callback = callback->cb_next; - continue; - } - } -aud_cal: - if (callback->clnt_type == AUDDEV_CLNT_AUDIOCAL) { - int temp_sessions; - MM_DBG("AUDDEV_CLNT_AUDIOCAL\n"); - if (evt_id == AUDDEV_EVT_VOICE_STATE_CHG) - evt_payload->voice_state = - routing_info.voice_state; - else if (!dev_info->sessions) - goto sent_aud_cal; - else { - evt_payload->audcal_info.dev_id = - dev_info->copp_id; - evt_payload->audcal_info.acdb_id = - dev_info->acdb_id; - evt_payload->audcal_info.dev_type = - (dev_info->capability & SNDDEV_CAP_TX) ? - SNDDEV_CAP_TX : SNDDEV_CAP_RX; - evt_payload->audcal_info.sample_rate = - dev_info->set_sample_rate ? - dev_info->set_sample_rate : - dev_info->sample_rate; - } - if (evt_payload->audcal_info.dev_type == - SNDDEV_CAP_TX) { - if (session_id == SESSION_IGNORE) - temp_sessions = dev_info->sessions; - else - temp_sessions = session_id; - evt_payload->audcal_info.sessions = - (temp_sessions >> - ((AUDDEV_CLNT_ENC-1) * 8)); - } else { - if (session_id == SESSION_IGNORE) - temp_sessions = dev_info->sessions; - else - temp_sessions = session_id; - evt_payload->audcal_info.sessions = - (temp_sessions >> - ((AUDDEV_CLNT_DEC-1) * 8)); - } - callback->auddev_evt_listener( - evt_id, - evt_payload, - callback->private_data); - -sent_aud_cal: - if (callback->cb_next == NULL) - break; - else { - callback = callback->cb_next; - continue; - } - } -skip_check: -voc_events: - if (callback->clnt_type == AUDDEV_CLNT_VOC) { - MM_DBG("AUDDEV_CLNT_VOC\n"); - if (evt_id == AUDDEV_EVT_DEV_RLS) { - if (!pending_sent) - goto sent_voc; - else - pending_sent = 0; - } - if (evt_id == AUDDEV_EVT_REL_PENDING) - pending_sent = 1; - - if (evt_id == AUDDEV_EVT_DEVICE_VOL_MUTE_CHG) { - if (dev_info->capability & SNDDEV_CAP_TX) { - evt_payload->voc_vm_info.dev_type = - SNDDEV_CAP_TX; - evt_payload->voc_vm_info.acdb_dev_id = - dev_info->acdb_id; - evt_payload-> - voc_vm_info.dev_vm_val.mute = - routing_info.tx_mute; - } else { - evt_payload->voc_vm_info.dev_type = - SNDDEV_CAP_RX; - evt_payload->voc_vm_info.acdb_dev_id = - dev_info->acdb_id; - evt_payload-> - voc_vm_info.dev_vm_val.vol = - routing_info.voice_rx_vol; - } - } else if ((evt_id == AUDDEV_EVT_START_VOICE) - || (evt_id == AUDDEV_EVT_END_VOICE)) - memset(evt_payload, 0, - sizeof(union auddev_evt_data)); - else if (evt_id == AUDDEV_EVT_FREQ_CHG) { - if (routing_info.voice_tx_sample_rate - != dev_info->set_sample_rate) { - routing_info.voice_tx_sample_rate - = dev_info->set_sample_rate; - evt_payload->freq_info.sample_rate - = dev_info->set_sample_rate; - evt_payload->freq_info.dev_type - = dev_info->capability; - evt_payload->freq_info.acdb_dev_id - = dev_info->acdb_id; - } else - goto sent_voc; - } else if (evt_id == AUDDEV_EVT_VOICE_STATE_CHG) - evt_payload->voice_state = - routing_info.voice_state; - else { - evt_payload->voc_devinfo.dev_type = - (dev_info->capability & SNDDEV_CAP_TX) ? - SNDDEV_CAP_TX : SNDDEV_CAP_RX; - evt_payload->voc_devinfo.acdb_dev_id = - dev_info->acdb_id; - evt_payload->voc_devinfo.dev_sample = - dev_info->set_sample_rate ? - dev_info->set_sample_rate : - dev_info->sample_rate; - evt_payload->voc_devinfo.dev_id = dev_id; - if (dev_info->capability & SNDDEV_CAP_RX) { - for (i = 0; i < VOC_RX_VOL_ARRAY_NUM; - i++) { - evt_payload-> - voc_devinfo.max_rx_vol[i] = - dev_info->max_voc_rx_vol[i]; - evt_payload - ->voc_devinfo.min_rx_vol[i] = - dev_info->min_voc_rx_vol[i]; - } - } - } - callback->auddev_evt_listener( - evt_id, - evt_payload, - callback->private_data); - if (evt_id == AUDDEV_EVT_DEV_RLS) - dev_info->sessions &= ~(0xFF); -sent_voc: - if (callback->cb_next == NULL) - break; - else { - callback = callback->cb_next; - continue; - } - } - } - kfree(evt_payload); - mutex_unlock(&session_lock); -} -EXPORT_SYMBOL(broadcast_event); - - -void mixer_post_event(u32 evt_id, u32 id) -{ - - MM_DBG("evt_id = %d\n", evt_id); - switch (evt_id) { - case AUDDEV_EVT_DEV_CHG_VOICE: /* Called from Voice_route */ - broadcast_event(AUDDEV_EVT_DEV_CHG_VOICE, id, SESSION_IGNORE); - break; - case AUDDEV_EVT_DEV_RDY: - broadcast_event(AUDDEV_EVT_DEV_RDY, id, SESSION_IGNORE); - break; - case AUDDEV_EVT_DEV_RLS: - broadcast_event(AUDDEV_EVT_DEV_RLS, id, SESSION_IGNORE); - break; - case AUDDEV_EVT_REL_PENDING: - broadcast_event(AUDDEV_EVT_REL_PENDING, id, SESSION_IGNORE); - break; - case AUDDEV_EVT_DEVICE_VOL_MUTE_CHG: - broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG, id, - SESSION_IGNORE); - break; - case AUDDEV_EVT_STREAM_VOL_CHG: - broadcast_event(AUDDEV_EVT_STREAM_VOL_CHG, id, - SESSION_IGNORE); - break; - case AUDDEV_EVT_START_VOICE: - broadcast_event(AUDDEV_EVT_START_VOICE, - id, SESSION_IGNORE); - break; - case AUDDEV_EVT_END_VOICE: - broadcast_event(AUDDEV_EVT_END_VOICE, - id, SESSION_IGNORE); - break; - case AUDDEV_EVT_FREQ_CHG: - broadcast_event(AUDDEV_EVT_FREQ_CHG, id, SESSION_IGNORE); - break; - default: - break; - } -} -EXPORT_SYMBOL(mixer_post_event); - -static int __init audio_dev_ctrl_init(void) -{ -#ifdef CONFIG_DEBUG_FS - char name[sizeof "rtc_get_device"+1]; -#endif - - init_waitqueue_head(&audio_dev_ctrl.wait); - - event.cb = NULL; - - atomic_set(&audio_dev_ctrl.opened, 0); - audio_dev_ctrl.num_dev = 0; - audio_dev_ctrl.voice_tx_dev = NULL; - audio_dev_ctrl.voice_rx_dev = NULL; - routing_info.voice_state = VOICE_STATE_INVALID; -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "rtc_get_device"); - dentry = debugfs_create_file(name, S_IFREG | S_IRUGO | S_IWUGO, - NULL, NULL, &rtc_acdb_debug_fops); - if (IS_ERR(dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif - - return misc_register(&audio_dev_ctrl_misc); -} - -static void __exit audio_dev_ctrl_exit(void) -{ -#ifdef CONFIG_DEBUG_FS - if (dentry) - debugfs_remove(dentry); -#endif - -} -module_init(audio_dev_ctrl_init); -module_exit(audio_dev_ctrl_exit); - -MODULE_DESCRIPTION("MSM 7K Audio Device Control driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_evrc.c b/arch/arm/mach-msm/qdsp5v2/audio_evrc.c deleted file mode 100644 index 2d9327e96d965521eecebd33707de8d825ab00e6..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_evrc.c +++ /dev/null @@ -1,1640 +0,0 @@ -/* - * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved. - * - * This code also borrows from audio_aac.c, which is - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Hold 30 packets of 24 bytes each and 14 bytes of meta in */ -#define BUFSZ 734 -#define DMASZ (BUFSZ * 2) - -#define AUDDEC_DEC_EVRC 12 - -#define PCM_BUFSZ_MIN 1624 /* 100ms worth of data and - and 24 bytes of meta out */ -#define PCM_BUF_MAX_COUNT 5 -/* DSP only accepts 5 buffers at most - * but support 2 buffers currently - */ -#define EVRC_DECODED_FRSZ 320 /* EVRC 20ms 8KHz mono PCM size */ - -#define ROUTING_MODE_FTRT 1 -#define ROUTING_MODE_RT 2 -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDEVRC_METAFIELD_MASK 0xFFFF0000 -#define AUDEVRC_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */ -#define AUDEVRC_EOS_FLG_MASK 0x01 -#define AUDEVRC_EOS_NONE 0x0 /* No EOS detected */ -#define AUDEVRC_EOS_SET 0x1 /* EOS set in meta field */ - -#define AUDEVRC_EVENT_NUM 10 /* Default number of pre-allocated event packets */ - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; - unsigned short mfield_sz; /*only useful for data has meta field */ -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audevrc_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct audevrc_event{ - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audio { - struct buffer out[2]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - /* Host PCM section */ - struct buffer in[PCM_BUF_MAX_COUNT]; - struct mutex read_lock; - wait_queue_head_t read_wait; /* Wait queue for read */ - char *read_data; /* pointer to reader buffer */ - int32_t read_phys; /* physical address of reader buffer */ - uint8_t read_next; /* index to input buffers to be read next */ - uint8_t fill_next; /* index to buffer that DSP should be filling */ - uint8_t pcm_buf_count; /* number of pcm buffer allocated */ - /* ---- End of Host PCM section */ - - struct msm_adsp_module *audplay; - - /* data allocated for various buffers */ - char *data; - int32_t phys; /* physical address of write buffer */ - void *map_v_read; - void *map_v_write; - - int mfield; /* meta field embedded in data */ - int rflush; /* Read flush */ - int wflush; /* Write flush */ - uint8_t opened:1; - uint8_t enabled:1; - uint8_t running:1; - uint8_t stopped:1; /* set when stopped, cleared on flush */ - uint8_t pcm_feedback:1; - uint8_t buf_refresh:1; - int teos; /* valid only if tunnel mode & no data left for decoder */ - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - - const char *module_name; - unsigned queue_id; - uint16_t dec_id; - uint32_t read_ptr_offset; - int16_t source; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audevrc_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - /* AV sync Info */ - int avsync_flag; /* Flag to indicate feedback from DSP */ - wait_queue_head_t avsync_wait;/* Wait queue for AV Sync Message */ - /* flags, 48 bits sample/bytes counter per channel */ - uint16_t avsync[AUDPP_AVSYNC_CH_COUNT * AUDPP_AVSYNC_NUM_WORDS + 1]; - - uint32_t device_events; - - int eq_enable; - int eq_needs_commit; - struct audpp_cmd_cfg_object_params_eqalizer eq; - struct audpp_cmd_cfg_object_params_volume vol_pan; -}; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audpp_cmd_cfg_adec_params(struct audio *audio); -static void audpp_cmd_cfg_routing_mode(struct audio *audio); -static void audevrc_send_data(struct audio *audio, unsigned needed); -static void audevrc_dsp_event(void *private, unsigned id, uint16_t *msg); -static void audevrc_config_hostpcm(struct audio *audio); -static void audevrc_buffer_refresh(struct audio *audio); -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audevrc_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); -#endif - -/* must be called with audio->lock held */ -static int audevrc_enable(struct audio *audio) -{ - if (audio->enabled) - return 0; - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_tail = 0; - audio->out_needed = 0; - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audevrc_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - return -ENODEV; - } - audio->enabled = 1; - return 0; -} - -static void evrc_listner(u32 evt_id, union auddev_evt_data *evt_payload, - void *private_data) -{ - struct audio *audio = (struct audio *) private_data; - switch (evt_id) { - case AUDDEV_EVT_DEV_RDY: - MM_DBG(":AUDDEV_EVT_DEV_RDY\n"); - audio->source |= (0x1 << evt_payload->routing_id); - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - break; - case AUDDEV_EVT_DEV_RLS: - MM_DBG(":AUDDEV_EVT_DEV_RLS\n"); - audio->source &= ~(0x1 << evt_payload->routing_id); - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - break; - case AUDDEV_EVT_STREAM_VOL_CHG: - audio->vol_pan.volume = evt_payload->session_vol; - MM_DBG(":AUDDEV_EVT_STREAM_VOL_CHG, stream vol %d\n", - audio->vol_pan.volume); - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - break; - default: - MM_ERR(":ERROR:wrong event\n"); - break; - } -} -/* must be called with audio->lock held */ -static int audevrc_disable(struct audio *audio) -{ - int rc = 0; - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - wake_up(&audio->write_wait); - wake_up(&audio->read_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - audio->out_needed = 0; - } - return rc; -} - -/* ------------------- dsp --------------------- */ - -static void audevrc_update_pcm_buf_entry(struct audio *audio, - uint32_t *payload) -{ - uint8_t index; - unsigned long flags; - - if (audio->rflush) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < payload[1]; index++) { - if (audio->in[audio->fill_next].addr - == payload[2 + index * 2]) { - MM_DBG("in[%d] ready\n", audio->fill_next); - audio->in[audio->fill_next].used = - payload[3 + index * 2]; - if ((++audio->fill_next) == audio->pcm_buf_count) - audio->fill_next = 0; - - } else { - MM_ERR("expected=%x ret=%x\n", - audio->in[audio->fill_next].addr, - payload[1 + index * 2]); - break; - } - } - if (audio->in[audio->fill_next].used == 0) { - audevrc_buffer_refresh(audio); - } else { - MM_DBG("read cannot keep up\n"); - audio->buf_refresh = 1; - } - wake_up(&audio->read_wait); - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - getevent(msg, sizeof(msg)); - - MM_DBG("msg_id=%x\n", id); - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audevrc_send_data(audio, 1); - break; - case AUDPLAY_MSG_BUFFER_UPDATE: - MM_DBG("\n"); /* Macro prints the file name and function */ - audevrc_update_pcm_buf_entry(audio, msg); - break; - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audplaytask)\n"); - break; - default: - MM_ERR("unexpected message from decoder \n"); - } -} - -static void audevrc_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status:sleep reason = \ - 0x%04x\n", reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init \n"); - if (audio->pcm_feedback) - audpp_cmd_cfg_routing_mode(audio); - else - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg \n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play \n"); - audpp_route_stream(audio->dec_id, - audio->source); - if (audio->pcm_feedback) { - audevrc_config_hostpcm(audio); - audevrc_buffer_refresh(audio); - } - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - default: - MM_ERR("unknown decoder status \n"); - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - audpp_dsp_set_eq(audio->dec_id, audio->eq_enable, - &audio->eq, POPP); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audio->running = 0; - } else { - MM_DBG("CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_ROUTING_ACK: - MM_DBG("ROUTING_ACK\n"); - audpp_cmd_cfg_adec_params(audio); - break; - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - audio->rflush = 0; - wake_up(&audio->write_wait); - if (audio->pcm_feedback) - audevrc_buffer_refresh(audio); - break; - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - - case AUDPP_MSG_AVSYNC_MSG: - MM_DBG("AUDPP_MSG_AVSYNC_MSG\n"); - memcpy(&audio->avsync[0], msg, sizeof(audio->avsync)); - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); - break; - - default: - MM_ERR("UNKNOWN (%d)\n", id); - } - -} - -struct msm_adsp_ops audplay_adsp_ops_evrc = { - .event = audplay_dsp_event, -}; - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id, \ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - struct audpp_cmd_cfg_dec_type cfg_dec_cmd; - - memset(&cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - - cfg_dec_cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE; - if (enable) - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_EVRC; - else - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - cfg_dec_cmd.dm_mode = 0x0; - cfg_dec_cmd.stream_id = audio->dec_id; - - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} - -static void audpp_cmd_cfg_adec_params(struct audio *audio) -{ - struct audpp_cmd_cfg_adec_params_evrc cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = sizeof(cmd); - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = 8000; - cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V; - - audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static void audpp_cmd_cfg_routing_mode(struct audio *audio) -{ - struct audpp_cmd_routing_mode cmd; - MM_DBG("\n"); /* Macro prints the file name and function */ - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; - cmd.object_number = audio->dec_id; - if (audio->pcm_feedback) - cmd.routing_mode = ROUTING_MODE_FTRT; - else - cmd.routing_mode = ROUTING_MODE_RT; - - audpp_send_queue1(&cmd, sizeof(cmd)); -} - -static int audplay_dsp_send_data_avail(struct audio *audio, - unsigned idx, unsigned len) -{ - struct audplay_cmd_bitstream_data_avail_nt2 cmd; - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2; - if (audio->mfield) - cmd.decoder_id = AUDEVRC_METAFIELD_MASK | - (audio->out[idx].mfield_sz >> 1); - else - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = audio->out[idx].addr; - cmd.buf_size = len / 2; - cmd.partition_number = 0; - return audplay_send_queue0(audio, &cmd, sizeof(cmd)); -} - -static void audevrc_buffer_refresh(struct audio *audio) -{ - struct audplay_cmd_buffer_refresh refresh_cmd; - - refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; - refresh_cmd.num_buffers = 1; - refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; - refresh_cmd.buf0_length = audio->in[audio->fill_next].size; - - refresh_cmd.buf_read_count = 0; - MM_DBG("buf0_addr=%x buf0_len=%d\n", refresh_cmd.buf0_address, - refresh_cmd.buf0_length); - audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); -} - -static void audevrc_config_hostpcm(struct audio *audio) -{ - struct audplay_cmd_hpcm_buf_cfg cfg_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; - cfg_cmd.max_buffers = 1; - cfg_cmd.byte_swap = 0; - cfg_cmd.hostpcm_config = (0x8000) | (0x4000); - cfg_cmd.feedback_frequency = 1; - cfg_cmd.partition_number = 0; - audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); - -} - -static void audevrc_send_data(struct audio *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - MM_DBG("frame %d busy\n", audio->out_tail); - audplay_dsp_send_data_avail(audio, audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } -done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ - -static void audevrc_flush(struct audio *audio) -{ - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->out_needed = 0; - atomic_set(&audio->out_bytes, 0); -} - -static void audevrc_flush_pcm_buf(struct audio *audio) -{ - uint8_t index; - - for (index = 0; index < PCM_BUF_MAX_COUNT; index++) - audio->in[index].used = 0; - - audio->buf_refresh = 0; - audio->read_next = 0; - audio->fill_next = 0; -} - -static void audevrc_ioport_reset(struct audio *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audevrc_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->read_wait); - mutex_lock(&audio->read_lock); - audevrc_flush_pcm_buf(audio); - mutex_unlock(&audio->read_lock); - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); -} - -static int audevrc_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audevrc_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audevrc_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audevrc_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audevrc_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - - -static long audevrc_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audevrc_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - audio->event_wait, audevrc_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audevrc_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - rc = 0; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audevrc_event, list); - list_del(&drv_evt->list); - } - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audio_enable_eq(struct audio *audio, int enable) -{ - if (audio->eq_enable == enable && !audio->eq_needs_commit) - return 0; - - audio->eq_enable = enable; - - if (audio->running) { - audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq, POPP); - audio->eq_needs_commit = 0; - } - return 0; -} - -static int audio_get_avsync_data(struct audio *audio, - struct msm_audio_stats *stats) -{ - int rc = -EINVAL; - unsigned long flags; - - local_irq_save(flags); - if (audio->dec_id == audio->avsync[0] && audio->avsync_flag) { - /* av_sync sample count */ - stats->sample_count = (audio->avsync[2] << 16) | - (audio->avsync[3]); - - /* av_sync byte_count */ - stats->byte_count = (audio->avsync[5] << 16) | - (audio->avsync[6]); - - audio->avsync_flag = 0; - rc = 0; - } - local_irq_restore(flags); - return rc; - -} - -static long audevrc_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - unsigned long flags = 0; - uint16_t enable_mask; - int enable; - int prev_state; - - MM_DBG("cmd = %d\n", cmd); - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - - audio->avsync_flag = 0; - memset(&stats, 0, sizeof(stats)); - if (audpp_query_avsync(audio->dec_id) < 0) - return rc; - - rc = wait_event_interruptible_timeout(audio->avsync_wait, - (audio->avsync_flag == 1), - msecs_to_jiffies(AUDPP_AVSYNC_EVENT_TIMEOUT)); - - if (rc < 0) - return rc; - else if ((rc > 0) || ((rc == 0) && (audio->avsync_flag == 1))) { - if (audio_get_avsync_data(audio, &stats) < 0) - return rc; - - if (copy_to_user((void *)arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } else - return -EAGAIN; - } - - switch (cmd) { - case AUDIO_ENABLE_AUDPP: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - spin_lock_irqsave(&audio->dsp_lock, flags); - enable = (enable_mask & EQ_ENABLE) ? 1 : 0; - audio_enable_eq(audio, enable); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - case AUDIO_SET_VOLUME: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.volume = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_PAN: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.pan = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_EQ: - prev_state = audio->eq_enable; - audio->eq_enable = 0; - if (copy_from_user(&audio->eq.num_bands, (void *) arg, - sizeof(audio->eq) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) { - rc = -EFAULT; - break; - } - audio->eq_enable = prev_state; - audio->eq_needs_commit = 1; - rc = 0; - break; - } - - if (-EINVAL != rc) - return rc; - - if (cmd == AUDIO_GET_EVENT) { - MM_DBG("AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audevrc_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audevrc_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) - rc = -ENODEV; - else - rc = 0; - } - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audevrc_disable(audio); - audio->stopped = 1; - audevrc_ioport_reset(audio); - audio->stopped = 0; - break; - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audevrc_ioport_reset(audio); - if (audio->running) { - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - case AUDIO_SET_CONFIG:{ - struct msm_audio_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - audio->mfield = config.meta_field; - rc = 0; - MM_DBG("AUDIO_SET_CONFIG applicable only \ - for meta field configuration\n"); - break; - } - case AUDIO_GET_CONFIG:{ - struct msm_audio_config config; - config.buffer_size = BUFSZ; - config.buffer_count = 2; - config.sample_rate = 8000; - config.channel_count = 1; - config.meta_field = 0; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *)arg, &config, sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_GET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - config.pcm_feedback = audio->pcm_feedback; - config.buffer_count = PCM_BUF_MAX_COUNT; - config.buffer_size = PCM_BUFSZ_MIN; - if (copy_to_user((void *)arg, &config, sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.pcm_feedback != audio->pcm_feedback) { - MM_ERR("Not sufficient permission to" - "change the playback mode\n"); - rc = -EACCES; - break; - } - if ((config.buffer_count > PCM_BUF_MAX_COUNT) || - (config.buffer_count == 1)) - config.buffer_count = PCM_BUF_MAX_COUNT; - - if (config.buffer_size < PCM_BUFSZ_MIN) - config.buffer_size = PCM_BUFSZ_MIN; - - /* Check if pcm feedback is required */ - if ((config.pcm_feedback) && (!audio->read_data)) { - MM_DBG("allocate PCM buf %d\n", - config.buffer_count * - config.buffer_size); - audio->read_phys = - allocate_contiguous_ebi_nomap( - config.buffer_size * - config.buffer_count, - SZ_4K); - if (!audio->read_phys) { - rc = -ENOMEM; - break; - } - audio->map_v_read = ioremap( - audio->read_phys, - config.buffer_size * - config.buffer_count); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("failed to map read" - " phy address\n"); - rc = -ENOMEM; - free_contiguous_memory_by_paddr( - audio->read_phys); - } else { - uint8_t index; - uint32_t offset = 0; - audio->read_data = - audio->map_v_read; - audio->buf_refresh = 0; - audio->pcm_buf_count = - config.buffer_count; - audio->read_next = 0; - audio->fill_next = 0; - - for (index = 0; - index < config.buffer_count; - index++) { - audio->in[index].data = - audio->read_data + offset; - audio->in[index].addr = - audio->read_phys + offset; - audio->in[index].size = - config.buffer_size; - audio->in[index].used = 0; - offset += config.buffer_size; - } - MM_DBG("read buf: phy addr \ - 0x%08x kernel addr 0x%08x\n", - audio->read_phys, - (int)audio->read_data); - rc = 0; - } - } else { - rc = 0; - } - break; - } - case AUDIO_PAUSE: - MM_DBG("AUDIO_PAUSE %ld\n", arg); - rc = audpp_pause(audio->dec_id, (int) arg); - break; - case AUDIO_GET_SESSION_ID: - if (copy_to_user((void *) arg, &audio->dec_id, - sizeof(unsigned short))) - rc = -EFAULT; - else - rc = 0; - break; - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -static int audevrc_fsync(struct file *file, loff_t ppos1, loff_t ppos2, int datasync) -{ - struct audio *audio = file->private_data; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - if (!audio->running || audio->pcm_feedback) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush); - - if (audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; -} - -static ssize_t audevrc_read(struct file *file, char __user *buf, size_t count, - loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - int rc = 0; - if (!audio->pcm_feedback) { - return 0; - /* PCM feedback is not enabled. Nothing to read */ - } - mutex_lock(&audio->read_lock); - MM_DBG("\n"); /* Macro prints the file name and function */ - while (count > 0) { - rc = wait_event_interruptible(audio->read_wait, - (audio->in[audio->read_next].used > 0) || - (audio->stopped) || (audio->rflush)); - - MM_DBG("wait terminated \n"); - if (rc < 0) - break; - if (audio->stopped || audio->rflush) { - rc = -EBUSY; - break; - } - if (count < audio->in[audio->read_next].used) { - /* Read must happen in frame boundary. Since driver does - * not know frame size, read count must be greater or - * equal to size of PCM samples - */ - MM_DBG("read stop - partial frame\n"); - break; - } else { - MM_DBG("read from in[%d]\n", audio->read_next); - if (copy_to_user - (buf, audio->in[audio->read_next].data, - audio->in[audio->read_next].used)) { - MM_ERR("invalid addr %x \n", - (unsigned int)buf); - rc = -EFAULT; - break; - } - count -= audio->in[audio->read_next].used; - buf += audio->in[audio->read_next].used; - audio->in[audio->read_next].used = 0; - if ((++audio->read_next) == audio->pcm_buf_count) - audio->read_next = 0; - break; - /* Force to exit while loop - * to prevent output thread - * sleep too long if data is - * not ready at this moment - */ - - } - } - /* don't feed output buffer to HW decoder during flushing - * buffer refresh command will be sent once flush completes - * send buf refresh command here can confuse HW decoder - */ - if (audio->buf_refresh && !audio->rflush) { - audio->buf_refresh = 0; - MM_DBG("kick start pcm feedback again\n"); - audevrc_buffer_refresh(audio); - } - mutex_unlock(&audio->read_lock); - if (buf > start) - rc = buf - start; - MM_DBG("read %d bytes\n", rc); - return rc; -} - -static int audevrc_process_eos(struct audio *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - int rc = 0; - struct buffer *frame; - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - audevrc_send_data(audio, 0); - -done: - return rc; -} - -static ssize_t audevrc_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - char *cpy_ptr; - unsigned short mfield_size = 0; - int rc = 0, eos_condition = AUDEVRC_EOS_NONE; - - MM_DBG("cnt=%d\n", count); - - if (count & 1) - return -EINVAL; - - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - cpy_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - break; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - break; - } - - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - break; - } else if (mfield_size > count) { - rc = -EINVAL; - break; - } - MM_DBG("mf offset_val %x\n", mfield_size); - if (copy_from_user(cpy_ptr, buf, - mfield_size)) { - rc = -EFAULT; - break; - } - /* Check if EOS flag is set and buffer has - * contains just meta field - */ - if (cpy_ptr[AUDEVRC_EOS_FLG_OFFSET] & - AUDEVRC_EOS_FLG_MASK) { - MM_DBG("eos set\n"); - eos_condition = AUDEVRC_EOS_SET; - if (mfield_size == count) { - buf += mfield_size; - break; - } else - cpy_ptr[AUDEVRC_EOS_FLG_OFFSET] &= - ~AUDEVRC_EOS_FLG_MASK; - } - /* Check EOS to see if */ - cpy_ptr += mfield_size; - count -= mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - - xfer = (count > (frame->size - mfield_size)) ? - (frame->size - mfield_size) : count; - if (copy_from_user(cpy_ptr, buf, xfer)) { - rc = -EFAULT; - break; - } - - frame->used = xfer + mfield_size; - audio->out_head ^= 1; - count -= xfer; - buf += xfer; - audevrc_send_data(audio, 0); - } - if (eos_condition == AUDEVRC_EOS_SET) - rc = audevrc_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - if (!rc) { - if (buf > start) - return buf - start; - } - return rc; -} - -static int audevrc_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_INFO("audio instance 0x%08x freeing\n", (int)audio); - mutex_lock(&audio->lock); - auddev_unregister_evt_listner(AUDDEV_CLNT_DEC, audio->dec_id); - audevrc_disable(audio); - audevrc_flush(audio); - audevrc_flush_pcm_buf(audio); - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->event_abort = 1; - wake_up(&audio->event_wait); - audevrc_reset_event_queue(audio); - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - if (audio->read_data) { - iounmap(audio->map_v_read); - free_contiguous_memory_by_paddr(audio->read_phys); - } - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - kfree(audio); - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audevrc_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audevrc_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audevrc_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audevrc_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -static void audevrc_suspend(struct early_suspend *h) -{ - struct audevrc_suspend_ctl *ctl = - container_of(h, struct audevrc_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audevrc_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audevrc_resume(struct early_suspend *h) -{ - struct audevrc_suspend_ctl *ctl = - container_of(h, struct audevrc_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audevrc_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audevrc_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audevrc_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 1024; - static char buffer[1024]; - int n = 0, i; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_feedback %d\n", audio->pcm_feedback); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_buf_sz %d\n", audio->out[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_count %d \n", audio->pcm_buf_count); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_sz %d \n", audio->in[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %x \n", audio->vol_pan.volume); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "rflush %d\n", audio->rflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d \n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d \n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d \n", audio->out_needed); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_head %d \n", audio->out_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_tail %d \n", audio->out_tail); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[0].used %d \n", audio->out[0].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[1].used %d \n", audio->out[1].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "buffer_refresh %d \n", audio->buf_refresh); - n += scnprintf(buffer + n, debug_bufmax - n, - "read_next %d \n", audio->read_next); - n += scnprintf(buffer + n, debug_bufmax - n, - "fill_next %d \n", audio->fill_next); - for (i = 0; i < audio->pcm_buf_count; i++) - n += scnprintf(buffer + n, debug_bufmax - n, - "in[%d].size %d \n", i, audio->in[i].used); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audevrc_debug_fops = { - .read = audevrc_debug_read, - .open = audevrc_debug_open, -}; -#endif - -static int audevrc_open(struct inode *inode, struct file *file) -{ - struct audio *audio = NULL; - int rc, dec_attrb, decid, i; - struct audevrc_event *e_node = NULL; -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_evrc_" + 5]; -#endif - - /* Allocate audio instance, set to zero */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("no memory to allocate audio instance\n"); - rc = -ENOMEM; - goto done; - } - MM_INFO("audio instance 0x%08x created\n", (int)audio); - - /* Allocate the decoder */ - dec_attrb = AUDDEC_DEC_EVRC; - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_NONTUNNEL; - audio->pcm_feedback = NON_TUNNEL_MODE_PLAYBACK; - } else if ((file->f_mode & FMODE_WRITE) && - !(file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_TUNNEL; - audio->pcm_feedback = TUNNEL_MODE_PLAYBACK; - } else { - kfree(audio); - rc = -EACCES; - goto done; - } - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - - if (decid < 0) { - MM_ERR("No free decoder available, freeing instance 0x%08x\n", - (int)audio); - rc = -ENODEV; - kfree(audio); - goto done; - } - - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - audio->phys = allocate_contiguous_ebi_nomap(DMASZ, SZ_4K); - if (!audio->phys) { - MM_ERR("could not allocate write buffers, freeing instance \ - 0x%08x\n", (int)audio); - rc = -ENOMEM; - audpp_adec_free(audio->dec_id); - kfree(audio); - goto done; - } else { - audio->map_v_write = ioremap(audio->phys, DMASZ); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("failed to map write physical address, freeing \ - instance 0x%08x\n", (int)audio); - rc = -ENOMEM; - free_contiguous_memory_by_paddr(audio->phys); - audpp_adec_free(audio->dec_id); - kfree(audio); - goto done; - } - audio->data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->phys, (int)audio->data); - } - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audplay_adsp_ops_evrc, audio); - - if (rc) { - MM_ERR("failed to get %s module, freeing instance 0x%08x\n", - audio->module_name, (int)audio); - goto err; - } - - /* Initialize all locks of audio instance */ - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->read_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - init_waitqueue_head(&audio->write_wait); - init_waitqueue_head(&audio->read_wait); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - spin_lock_init(&audio->event_queue_lock); - init_waitqueue_head(&audio->avsync_wait); - - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = BUFSZ; - - audio->out[1].data = audio->data + BUFSZ; - audio->out[1].addr = audio->phys + BUFSZ; - audio->out[1].size = BUFSZ; - - audio->vol_pan.volume = 0x3FFF; - - audevrc_flush(audio); - - file->private_data = audio; - audio->opened = 1; - - audio->device_events = AUDDEV_EVT_DEV_RDY - |AUDDEV_EVT_DEV_RLS| - AUDDEV_EVT_STREAM_VOL_CHG; - - rc = auddev_register_evt_listner(audio->device_events, - AUDDEV_CLNT_DEC, - audio->dec_id, - evrc_listner, - (void *)audio); - if (rc) { - MM_ERR("%s: failed to register listner\n", __func__); - goto event_err; - } - -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_evrc_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, &audevrc_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audevrc_resume; - audio->suspend_ctl.node.suspend = audevrc_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (i = 0; i < AUDEVRC_EVENT_NUM; i++) { - e_node = kmalloc(sizeof(struct audevrc_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } -done: - return rc; -event_err: - msm_adsp_put(audio->audplay); -err: - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - audpp_adec_free(audio->dec_id); - kfree(audio); - return rc; -} - -static const struct file_operations audio_evrc_fops = { - .owner = THIS_MODULE, - .open = audevrc_open, - .release = audevrc_release, - .read = audevrc_read, - .write = audevrc_write, - .unlocked_ioctl = audevrc_ioctl, - .fsync = audevrc_fsync, -}; - -struct miscdevice audio_evrc_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_evrc", - .fops = &audio_evrc_fops, -}; - -static int __init audevrc_init(void) -{ - return misc_register(&audio_evrc_misc); - -} - -static void __exit audevrc_exit(void) -{ - misc_deregister(&audio_evrc_misc); -} - -module_init(audevrc_init); -module_exit(audevrc_exit); - -MODULE_DESCRIPTION("MSM EVRC driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c b/arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c deleted file mode 100644 index 1a2d42037632dbe5a57976bcfac09a301690f672..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c +++ /dev/null @@ -1,1507 +0,0 @@ -/* - * evrc audio input device - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define META_OUT_SIZE 24 -/* FRAME_NUM must be a power of two */ -#define FRAME_NUM 8 -#define EVRC_FRAME_SIZE 36 /* 36 bytes data */ -#define FRAME_SIZE (22 * 2) /* 36 bytes data */ - /* 36 bytes data + 24 meta field*/ -#define NT_FRAME_SIZE (EVRC_FRAME_SIZE + META_OUT_SIZE) -#define DMASZ (NT_FRAME_SIZE * FRAME_NUM) -#define OUT_FRAME_NUM 2 -#define OUT_BUFFER_SIZE (4 * 1024 + META_OUT_SIZE) -#define BUFFER_SIZE (OUT_BUFFER_SIZE * OUT_FRAME_NUM) - -#define AUDPREPROC_EVRC_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer*/ -#define AUDPREPROC_EVRC_EOS_FLG_MASK 0x01 -#define AUDPREPROC_EVRC_EOS_NONE 0x0 /* No EOS detected */ -#define AUDPREPROC_EVRC_EOS_SET 0x1 /* EOS set in meta field */ - -struct buffer { - void *data; - uint32_t size; - uint32_t read; - uint32_t addr; - uint32_t used; - uint32_t mfield_sz; -}; - -struct audio_in { - struct buffer in[FRAME_NUM]; - - spinlock_t dsp_lock; - - atomic_t in_bytes; - atomic_t in_samples; - - struct mutex lock; - struct mutex read_lock; - wait_queue_head_t wait; - wait_queue_head_t wait_enable; - /*write section*/ - struct buffer out[OUT_FRAME_NUM]; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - uint32_t out_count; - - struct mutex write_lock; - wait_queue_head_t write_wait; - int32_t out_phys; /* physical address of write buffer */ - char *out_data; - int mfield; /* meta field embedded in data */ - int wflush; /*write flush */ - int rflush; /*read flush*/ - int out_frame_cnt; - - struct msm_adsp_module *audrec; - - struct audrec_session_info session_info; /*audrec session info*/ - - /* configuration to use on next enable */ - uint32_t buffer_size; /* Frame size (36 bytes) */ - uint32_t samp_rate; - uint32_t channel_mode; - uint32_t enc_type; - - struct msm_audio_evrc_enc_config cfg; - - uint32_t dsp_cnt; - uint32_t in_head; /* next buffer dsp will write */ - uint32_t in_tail; /* next buffer read() will read */ - uint32_t in_count; /* number of buffers available to read() */ - uint32_t mode; - uint32_t eos_ack; - uint32_t flush_ack; - - const char *module_name; - unsigned queue_ids; - uint16_t enc_id; - - uint16_t source; /* Encoding source bit mask */ - uint32_t device_events; - uint32_t in_call; - uint32_t dev_cnt; - int voice_state; - spinlock_t dev_lock; - - /* data allocated for various buffers */ - char *data; - dma_addr_t phys; - void *map_v_read; - void *map_v_write; - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - char *build_id; -}; - -struct audio_frame { - uint16_t frame_count_lsw; - uint16_t frame_count_msw; - uint16_t frame_length; - uint16_t erased_pcm; - unsigned char raw_bitstream[]; /* samples */ -} __attribute__((packed)); - -struct audio_frame_nt { - uint16_t metadata_len; - uint16_t frame_count_lsw; - uint16_t frame_count_msw; - uint16_t frame_length; - uint16_t erased_pcm; - uint16_t reserved; - uint16_t time_stamp_dword_lsw; - uint16_t time_stamp_dword_msw; - uint16_t time_stamp_lsw; - uint16_t time_stamp_msw; - uint16_t nflag_lsw; - uint16_t nflag_msw; - unsigned char raw_bitstream[]; /* samples */ -} __attribute__((packed)); - -struct evrc_encoded_meta_out { - uint16_t metadata_len; - uint16_t time_stamp_dword_lsw; - uint16_t time_stamp_dword_msw; - uint16_t time_stamp_lsw; - uint16_t time_stamp_msw; - uint16_t nflag_lsw; - uint16_t nflag_msw; -}; - -/* Audrec Queue command sent macro's */ -#define audrec_send_bitstreamqueue(audio, cmd, len) \ - msm_adsp_write(audio->audrec, ((audio->queue_ids & 0xFFFF0000) >> 16),\ - cmd, len) - -#define audrec_send_audrecqueue(audio, cmd, len) \ - msm_adsp_write(audio->audrec, (audio->queue_ids & 0x0000FFFF),\ - cmd, len) - -/* DSP command send functions */ -static int audevrc_in_enc_config(struct audio_in *audio, int enable); -static int audevrc_in_param_config(struct audio_in *audio); -static int audevrc_in_mem_config(struct audio_in *audio); -static int audevrc_in_record_config(struct audio_in *audio, int enable); -static int audevrc_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt); - -static void audevrc_in_get_dsp_frames(struct audio_in *audio); -static int audpcm_config(struct audio_in *audio); -static void audevrc_out_flush(struct audio_in *audio); -static int audpreproc_cmd_cfg_routing_mode(struct audio_in *audio); -static void audpreproc_pcm_send_data(struct audio_in *audio, unsigned needed); -static void audevrc_nt_in_get_dsp_frames(struct audio_in *audio); - -static void audevrc_in_flush(struct audio_in *audio); - -static void evrc_in_listener(u32 evt_id, union auddev_evt_data *evt_payload, - void *private_data) -{ - struct audio_in *audio = (struct audio_in *) private_data; - unsigned long flags; - - MM_DBG("evt_id = 0x%8x\n", evt_id); - switch (evt_id) { - case AUDDEV_EVT_DEV_RDY: { - MM_DBG("AUDDEV_EVT_DEV_RDY\n"); - spin_lock_irqsave(&audio->dev_lock, flags); - audio->dev_cnt++; - if (!audio->in_call) - audio->source |= (0x1 << evt_payload->routing_id); - spin_unlock_irqrestore(&audio->dev_lock, flags); - - if ((audio->running == 1) && (audio->enabled == 1) && - (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)) - audevrc_in_record_config(audio, 1); - } - break; - case AUDDEV_EVT_DEV_RLS: { - MM_DBG("AUDDEV_EVT_DEV_RLS\n"); - spin_lock_irqsave(&audio->dev_lock, flags); - audio->dev_cnt--; - if (!audio->in_call) - audio->source &= ~(0x1 << evt_payload->routing_id); - spin_unlock_irqrestore(&audio->dev_lock, flags); - - if ((!audio->running) || (!audio->enabled)) - break; - - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - /* Turn of as per source */ - if (audio->source) - audevrc_in_record_config(audio, 1); - else - /* Turn off all */ - audevrc_in_record_config(audio, 0); - } - } - break; - case AUDDEV_EVT_VOICE_STATE_CHG: { - MM_DBG("AUDDEV_EVT_VOICE_STATE_CHG, state = %d\n", - evt_payload->voice_state); - audio->voice_state = evt_payload->voice_state; - if (audio->in_call && audio->running && - (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)) { - if (audio->voice_state == VOICE_STATE_INCALL) - audevrc_in_record_config(audio, 1); - else if (audio->voice_state == VOICE_STATE_OFFCALL) { - audevrc_in_record_config(audio, 0); - wake_up(&audio->wait); - } - } - - break; - } - default: - MM_ERR("wrong event %d\n", evt_id); - break; - } -} - -/* ------------------- dsp preproc event handler--------------------- */ -static void audpreproc_dsp_event(void *data, unsigned id, void *msg) -{ - struct audio_in *audio = data; - - switch (id) { - case AUDPREPROC_ERROR_MSG: { - struct audpreproc_err_msg *err_msg = msg; - - MM_ERR("ERROR_MSG: stream id %d err idx %d\n", - err_msg->stream_id, err_msg->aud_preproc_err_idx); - /* Error case */ - wake_up(&audio->wait_enable); - break; - } - case AUDPREPROC_CMD_CFG_DONE_MSG: { - MM_DBG("CMD_CFG_DONE_MSG \n"); - break; - } - case AUDPREPROC_CMD_ENC_CFG_DONE_MSG: { - struct audpreproc_cmd_enc_cfg_done_msg *enc_cfg_msg = msg; - - MM_DBG("CMD_ENC_CFG_DONE_MSG: stream id %d enc type \ - 0x%8x\n", enc_cfg_msg->stream_id, - enc_cfg_msg->rec_enc_type); - /* Encoder enable success */ - if (enc_cfg_msg->rec_enc_type & ENCODE_ENABLE) { - if(audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) { - MM_DBG("routing command\n"); - audpreproc_cmd_cfg_routing_mode(audio); - } else { - audevrc_in_param_config(audio); - } - } else { /* Encoder disable success */ - audio->running = 0; - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - audevrc_in_record_config(audio, 0); - else - wake_up(&audio->wait_enable); - } - break; - } - case AUDPREPROC_CMD_ENC_PARAM_CFG_DONE_MSG: { - MM_DBG("CMD_ENC_PARAM_CFG_DONE_MSG\n"); - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - audevrc_in_mem_config(audio); - else - audpcm_config(audio); - break; - } - case AUDPREPROC_CMD_ROUTING_MODE_DONE_MSG: { - struct audpreproc_cmd_routing_mode_done\ - *routing_cfg_done_msg = msg; - if (routing_cfg_done_msg->configuration == 0) { - MM_INFO("routing configuration failed\n"); - audio->running = 0; - } else - audevrc_in_param_config(audio); - break; - } - case AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG_DONE_MSG: { - MM_DBG("AFE_CMD_AUDIO_RECORD_CFG_DONE_MSG \n"); - wake_up(&audio->wait_enable); - break; - } - default: - MM_ERR("Unknown Event id %d\n", id); - } -} - -/* ------------------- dsp audrec event handler--------------------- */ -static void audrec_dsp_event(void *data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - struct audio_in *audio = data; - - switch (id) { - case AUDREC_CMD_MEM_CFG_DONE_MSG: { - MM_DBG("CMD_MEM_CFG_DONE MSG DONE\n"); - audio->running = 1; - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - if ((!audio->in_call && (audio->dev_cnt > 0)) || - (audio->in_call && - (audio->voice_state \ - == VOICE_STATE_INCALL))) - audevrc_in_record_config(audio, 1); - } else { - audpreproc_pcm_send_data(audio, 1); - wake_up(&audio->wait_enable); - } - break; - } - case AUDREC_FATAL_ERR_MSG: { - struct audrec_fatal_err_msg fatal_err_msg; - - getevent(&fatal_err_msg, AUDREC_FATAL_ERR_MSG_LEN); - MM_ERR("FATAL_ERR_MSG: err id %d\n", - fatal_err_msg.audrec_err_id); - /* Error stop the encoder */ - audio->stopped = 1; - wake_up(&audio->wait); - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) - wake_up(&audio->write_wait); - break; - } - case AUDREC_UP_PACKET_READY_MSG: { - struct audrec_up_pkt_ready_msg pkt_ready_msg; - - getevent(&pkt_ready_msg, AUDREC_UP_PACKET_READY_MSG_LEN); - MM_DBG("UP_PACKET_READY_MSG: write cnt lsw %d \ - write cnt msw %d read cnt lsw %d read cnt msw %d \n",\ - pkt_ready_msg.audrec_packet_write_cnt_lsw, \ - pkt_ready_msg.audrec_packet_write_cnt_msw, \ - pkt_ready_msg.audrec_up_prev_read_cnt_lsw, \ - pkt_ready_msg.audrec_up_prev_read_cnt_msw); - - audevrc_in_get_dsp_frames(audio); - break; - } - case AUDREC_CMD_PCM_BUFFER_PTR_UPDATE_ARM_TO_ENC_MSG: { - MM_DBG("ptr_update recieved from DSP\n"); - audpreproc_pcm_send_data(audio, 1); - break; - } - case AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG: { - MM_ERR("AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG"); - audevrc_in_mem_config(audio); - break; - } - case AUDREC_UP_NT_PACKET_READY_MSG: { - struct audrec_up_nt_packet_ready_msg pkt_ready_msg; - - getevent(&pkt_ready_msg, AUDREC_UP_NT_PACKET_READY_MSG_LEN); - MM_DBG("UP_NT_PACKET_READY_MSG: write cnt lsw %d \ - write cnt msw %d read cnt lsw %d read cnt msw %d \n",\ - pkt_ready_msg.audrec_packetwrite_cnt_lsw, \ - pkt_ready_msg.audrec_packetwrite_cnt_msw, \ - pkt_ready_msg.audrec_upprev_readcount_lsw, \ - pkt_ready_msg.audrec_upprev_readcount_msw); - - audevrc_nt_in_get_dsp_frames(audio); - break; - } - case AUDREC_CMD_EOS_ACK_MSG: { - MM_DBG("eos ack recieved\n"); - break; - } - case AUDREC_CMD_FLUSH_DONE_MSG: { - audio->wflush = 0; - audio->rflush = 0; - audio->flush_ack = 1; - wake_up(&audio->write_wait); - MM_DBG("flush ack recieved\n"); - break; - } - case ADSP_MESSAGE_ID: { - MM_DBG("Received ADSP event:module audrectask\n"); - break; - } - default: - MM_ERR("Unknown Event id %d\n", id); - } -} - -static void audevrc_in_get_dsp_frames(struct audio_in *audio) -{ - struct audio_frame *frame; - uint32_t index; - unsigned long flags; - - index = audio->in_head; - - frame = (void *) (((char *)audio->in[index].data) - \ - sizeof(*frame)); - - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->in[index].size = frame->frame_length; - - /* statistics of read */ - atomic_add(audio->in[index].size, &audio->in_bytes); - atomic_add(1, &audio->in_samples); - - audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1); - - /* If overflow, move the tail index foward. */ - if (audio->in_head == audio->in_tail) { - MM_ERR("Error! not able to keep up the read\n"); - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - MM_ERR("in_count = %d\n", audio->in_count); - } else - audio->in_count++; - - audevrc_dsp_read_buffer(audio, audio->dsp_cnt++); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - - wake_up(&audio->wait); -} - -static void audevrc_nt_in_get_dsp_frames(struct audio_in *audio) -{ - struct audio_frame_nt *nt_frame; - uint32_t index; - unsigned long flags; - - index = audio->in_head; - nt_frame = (void *) (((char *)audio->in[index].data) - \ - sizeof(struct audio_frame_nt)); - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->in[index].size = nt_frame->frame_length; - /* statistics of read */ - atomic_add(audio->in[index].size, &audio->in_bytes); - atomic_add(1, &audio->in_samples); - - audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1); - - /* If overflow, move the tail index foward. */ - if (audio->in_head == audio->in_tail) - MM_DBG("Error! not able to keep up the read\n"); - else - audio->in_count++; - - spin_unlock_irqrestore(&audio->dsp_lock, flags); - wake_up(&audio->wait); -} - - -struct msm_adsp_ops audrec_evrc_adsp_ops = { - .event = audrec_dsp_event, -}; - -static int audpreproc_pcm_buffer_ptr_refresh(struct audio_in *audio, - unsigned idx, unsigned len) -{ - struct audrec_cmd_pcm_buffer_ptr_refresh_arm_enc cmd; - - if (len == META_OUT_SIZE) - len = len / 2; - else - len = (len + META_OUT_SIZE) / 2; - MM_DBG("len = %d\n", len); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_PCM_BUFFER_PTR_REFRESH_ARM_TO_ENC; - cmd.num_buffers = 1; - if (cmd.num_buffers == 1) { - cmd.buf_address_length[0] = (audio->out[idx].addr & - 0xffff0000) >> 16; - cmd.buf_address_length[1] = (audio->out[idx].addr & - 0x0000ffff); - cmd.buf_address_length[2] = (len & 0xffff0000) >> 16; - cmd.buf_address_length[3] = (len & 0x0000ffff); - } - audio->out_frame_cnt++; - return audrec_send_audrecqueue(audio, (void *)&cmd, - (unsigned int)sizeof(cmd)); -} - - -static int audpcm_config(struct audio_in *audio) -{ - struct audrec_cmd_pcm_cfg_arm_to_enc cmd; - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_PCM_CFG_ARM_TO_ENC; - cmd.config_update_flag = AUDREC_PCM_CONFIG_UPDATE_FLAG_ENABLE; - cmd.enable_flag = AUDREC_ENABLE_FLAG_VALUE; - cmd.sampling_freq = audio->samp_rate; - if (!audio->channel_mode) - cmd.channels = 1; - else - cmd.channels = 2; - cmd.frequency_of_intimation = 1; - cmd.max_number_of_buffers = OUT_FRAME_NUM; - return audrec_send_audrecqueue(audio, (void *)&cmd, - (unsigned int)sizeof(cmd)); -} - - -static int audpreproc_cmd_cfg_routing_mode(struct audio_in *audio) -{ - struct audpreproc_audrec_cmd_routing_mode cmd; - - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPREPROC_AUDREC_CMD_ROUTING_MODE; - cmd.stream_id = audio->enc_id; - if (audio->mode == MSM_ADSP_ENC_MODE_NON_TUNNEL) - cmd.routing_mode = 1; - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); -} - - - -static int audevrc_in_enc_config(struct audio_in *audio, int enable) -{ - struct audpreproc_audrec_cmd_enc_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - if (audio->build_id[17] == '1') { - cmd.cmd_id = AUDPREPROC_AUDREC_CMD_ENC_CFG_2; - MM_ERR("sending AUDPREPROC_AUDREC_CMD_ENC_CFG_2 command"); - } else { - cmd.cmd_id = AUDPREPROC_AUDREC_CMD_ENC_CFG; - MM_ERR("sending AUDPREPROC_AUDREC_CMD_ENC_CFG command"); - } - cmd.stream_id = audio->enc_id; - - if (enable) - cmd.audrec_enc_type = audio->enc_type | ENCODE_ENABLE; - else - cmd.audrec_enc_type &= ~(ENCODE_ENABLE); - - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); -} - -static int audevrc_in_param_config(struct audio_in *audio) -{ - struct audpreproc_audrec_cmd_parm_cfg_evrc cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPREPROC_AUDREC_CMD_PARAM_CFG; - cmd.common.stream_id = audio->enc_id; - - cmd.enc_min_rate = audio->cfg.min_bit_rate; - cmd.enc_max_rate = audio->cfg.max_bit_rate; - cmd.rate_modulation_cmd = 0; /* Default set to 0 */ - - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); -} - -/* To Do: msm_snddev_route_enc(audio->enc_id); */ -static int audevrc_in_record_config(struct audio_in *audio, int enable) -{ - struct audpreproc_afe_cmd_audio_record_cfg cmd; - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG; - cmd.stream_id = audio->enc_id; - if (enable) - cmd.destination_activity = AUDIO_RECORDING_TURN_ON; - else - cmd.destination_activity = AUDIO_RECORDING_TURN_OFF; - - cmd.source_mix_mask = audio->source; - if (audio->enc_id == 2) { - if ((cmd.source_mix_mask & - INTERNAL_CODEC_TX_SOURCE_MIX_MASK) || - (cmd.source_mix_mask & AUX_CODEC_TX_SOURCE_MIX_MASK) || - (cmd.source_mix_mask & VOICE_UL_SOURCE_MIX_MASK) || - (cmd.source_mix_mask & VOICE_DL_SOURCE_MIX_MASK)) { - cmd.pipe_id = SOURCE_PIPE_1; - } - if (cmd.source_mix_mask & - AUDPP_A2DP_PIPE_SOURCE_MIX_MASK) - cmd.pipe_id |= SOURCE_PIPE_0; - } - MM_DBG("stream_id %x destination_activity %x \ - source_mix_mask %x pipe_id %x",\ - cmd.stream_id, cmd.destination_activity, - cmd.source_mix_mask, cmd.pipe_id); - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); -} - -static int audevrc_in_mem_config(struct audio_in *audio) -{ - struct audrec_cmd_arecmem_cfg cmd; - uint16_t *data = (void *) audio->data; - int n; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_MEM_CFG_CMD; - cmd.audrec_up_pkt_intm_count = 1; - cmd.audrec_ext_pkt_start_addr_msw = audio->phys >> 16; - cmd.audrec_ext_pkt_start_addr_lsw = audio->phys; - cmd.audrec_ext_pkt_buf_number = FRAME_NUM; - MM_DBG("audio->phys = %x\n", audio->phys); - /* prepare buffer pointers: - * T:36 bytes evrc packet + 4 halfword header - * NT:36 bytes evrc packet + 12 halfword header - */ - for (n = 0; n < FRAME_NUM; n++) { - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - audio->in[n].data = data + 4; - data += (FRAME_SIZE/2); - MM_DBG("0x%8x\n", (int)(audio->in[n].data - 8)); - } else { - audio->in[n].data = data + 12; - data += ((EVRC_FRAME_SIZE) / 2) + 12; - MM_DBG("0x%8x\n", (int)(audio->in[n].data - 24)); - } - } - return audrec_send_audrecqueue(audio, &cmd, sizeof(cmd)); -} - -static int audevrc_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt) -{ - struct up_audrec_packet_ext_ptr cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = UP_AUDREC_PACKET_EXT_PTR; - cmd.audrec_up_curr_read_count_msw = read_cnt >> 16; - cmd.audrec_up_curr_read_count_lsw = read_cnt; - - return audrec_send_bitstreamqueue(audio, &cmd, sizeof(cmd)); -} -static int audevrc_flush_command(struct audio_in *audio) -{ - struct audrec_cmd_flush cmd; - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_FLUSH; - return audrec_send_audrecqueue(audio, &cmd, sizeof(cmd)); -} - -/* must be called with audio->lock held */ -static int audevrc_in_enable(struct audio_in *audio) -{ - if (audio->enabled) - return 0; - - if (audpreproc_enable(audio->enc_id, &audpreproc_dsp_event, audio)) { - MM_ERR("msm_adsp_enable(audpreproc) failed\n"); - return -ENODEV; - } - - if (msm_adsp_enable(audio->audrec)) { - MM_ERR("msm_adsp_enable(audrec) failed\n"); - audpreproc_disable(audio->enc_id, audio); - return -ENODEV; - } - audio->enabled = 1; - audevrc_in_enc_config(audio, 1); - - return 0; -} - -/* must be called with audio->lock held */ -static int audevrc_in_disable(struct audio_in *audio) -{ - if (audio->enabled) { - audio->enabled = 0; - audevrc_in_enc_config(audio, 0); - wake_up(&audio->wait); - wait_event_interruptible_timeout(audio->wait_enable, - audio->running == 0, 1*HZ); - msm_adsp_disable(audio->audrec); - audpreproc_disable(audio->enc_id, audio); - } - return 0; -} - -static void audevrc_ioport_reset(struct audio_in *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audevrc_in_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->wait); - mutex_lock(&audio->read_lock); - audevrc_out_flush(audio); - mutex_unlock(&audio->read_lock); -} - -static void audevrc_in_flush(struct audio_in *audio) -{ - int i; - - audio->dsp_cnt = 0; - audio->in_head = 0; - audio->in_tail = 0; - audio->in_count = 0; - audio->eos_ack = 0; - for (i = 0; i < FRAME_NUM; i++) { - audio->in[i].size = 0; - audio->in[i].read = 0; - } - MM_DBG("in_bytes %d\n", atomic_read(&audio->in_bytes)); - MM_DBG("in_samples %d\n", atomic_read(&audio->in_samples)); - atomic_set(&audio->in_bytes, 0); - atomic_set(&audio->in_samples, 0); -} - -static void audevrc_out_flush(struct audio_in *audio) -{ - int i; - - audio->out_head = 0; - audio->out_tail = 0; - audio->out_count = 0; - for (i = 0; i < OUT_FRAME_NUM; i++) { - audio->out[i].size = 0; - audio->out[i].read = 0; - audio->out[i].used = 0; - } -} - -/* ------------------- device --------------------- */ -static long audevrc_in_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct audio_in *audio = file->private_data; - int rc = 0; - - MM_DBG("\n"); - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = atomic_read(&audio->in_bytes); - stats.sample_count = atomic_read(&audio->in_samples); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return rc; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: { - uint32_t freq; - freq = 48000; - MM_DBG("AUDIO_START\n"); - if (audio->in_call && (audio->voice_state != - VOICE_STATE_INCALL)) { - rc = -EPERM; - break; - } - rc = msm_snddev_request_freq(&freq, audio->enc_id, - SNDDEV_CAP_TX, AUDDEV_CLNT_ENC); - MM_DBG("sample rate configured %d\n", freq); - if (rc < 0) { - MM_DBG(" Sample rate can not be set, return code %d\n", - rc); - msm_snddev_withdraw_freq(audio->enc_id, - SNDDEV_CAP_TX, AUDDEV_CLNT_ENC); - MM_DBG("msm_snddev_withdraw_freq\n"); - break; - } - /*update aurec session info in audpreproc layer*/ - audio->session_info.session_id = audio->enc_id; - audio->session_info.sampling_freq = audio->samp_rate; - audpreproc_update_audrec_info(&audio->session_info); - rc = audevrc_in_enable(audio); - if (!rc) { - rc = - wait_event_interruptible_timeout(audio->wait_enable, - audio->running != 0, 1*HZ); - MM_DBG("state %d rc = %d\n", audio->running, rc); - - if (audio->running == 0) - rc = -ENODEV; - else - rc = 0; - } - audio->stopped = 0; - break; - } - case AUDIO_STOP: { - /*reset the sampling frequency information at audpreproc layer*/ - audio->session_info.sampling_freq = 0; - audpreproc_update_audrec_info(&audio->session_info); - rc = audevrc_in_disable(audio); - rc = msm_snddev_withdraw_freq(audio->enc_id, - SNDDEV_CAP_TX, AUDDEV_CLNT_ENC); - MM_DBG("msm_snddev_withdraw_freq\n"); - audio->stopped = 1; - break; - } - case AUDIO_FLUSH: { - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audevrc_ioport_reset(audio); - if (audio->running) { - audevrc_flush_command(audio); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - } - case AUDIO_SET_STREAM_CONFIG: { - struct msm_audio_stream_config cfg; - if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - /* Allow only single frame */ - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - if (cfg.buffer_size != (FRAME_SIZE - 8)) { - rc = -EINVAL; - break; - } - } else { - if (cfg.buffer_size != (EVRC_FRAME_SIZE + 14)) { - rc = -EINVAL; - break; - } - } - audio->buffer_size = cfg.buffer_size; - break; - } - case AUDIO_GET_STREAM_CONFIG: { - struct msm_audio_stream_config cfg; - memset(&cfg, 0, sizeof(cfg)); - cfg.buffer_size = audio->buffer_size; - cfg.buffer_count = FRAME_NUM; - if (copy_to_user((void *) arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - break; - } - case AUDIO_GET_EVRC_ENC_CONFIG: { - if (copy_to_user((void *) arg, &audio->cfg, sizeof(audio->cfg))) - rc = -EFAULT; - break; - } - case AUDIO_SET_EVRC_ENC_CONFIG: { - struct msm_audio_evrc_enc_config cfg; - if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - MM_DBG("0X%8x, 0x%8x, 0x%8x\n", cfg.min_bit_rate, - cfg.max_bit_rate, cfg.cdma_rate); - if (cfg.min_bit_rate > CDMA_RATE_FULL || \ - cfg.min_bit_rate < CDMA_RATE_EIGHTH) { - MM_ERR("invalid min bitrate\n"); - rc = -EFAULT; - break; - } - if (cfg.max_bit_rate > CDMA_RATE_FULL || \ - cfg.max_bit_rate < CDMA_RATE_EIGHTH) { - MM_ERR("invalid max bitrate\n"); - rc = -EFAULT; - break; - } - /* Recording Does not support Erase and Blank */ - if (cfg.cdma_rate > CDMA_RATE_FULL || - cfg.cdma_rate < CDMA_RATE_EIGHTH) { - MM_ERR("invalid qcelp cdma rate\n"); - rc = -EFAULT; - break; - } - memcpy(&audio->cfg, &cfg, sizeof(cfg)); - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config cfg; - memset(&cfg, 0, sizeof(cfg)); - cfg.buffer_size = OUT_BUFFER_SIZE; - cfg.buffer_count = OUT_FRAME_NUM; - cfg.sample_rate = audio->samp_rate; - cfg.channel_count = audio->channel_mode; - if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - break; - } - case AUDIO_SET_INCALL: { - struct msm_voicerec_mode cfg; - unsigned long flags; - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - if (cfg.rec_mode != VOC_REC_BOTH && - cfg.rec_mode != VOC_REC_UPLINK && - cfg.rec_mode != VOC_REC_DOWNLINK) { - MM_ERR("invalid rec_mode\n"); - rc = -EINVAL; - break; - } else { - spin_lock_irqsave(&audio->dev_lock, flags); - if (cfg.rec_mode == VOC_REC_UPLINK) - audio->source = \ - VOICE_UL_SOURCE_MIX_MASK; - else if (cfg.rec_mode == VOC_REC_DOWNLINK) - audio->source = \ - VOICE_DL_SOURCE_MIX_MASK; - else - audio->source = \ - VOICE_DL_SOURCE_MIX_MASK | - VOICE_UL_SOURCE_MIX_MASK ; - audio->in_call = 1; - spin_unlock_irqrestore(&audio->dev_lock, flags); - } - } - break; - } - case AUDIO_GET_SESSION_ID: { - if (copy_to_user((void *) arg, &audio->enc_id, - sizeof(unsigned short))) { - rc = -EFAULT; - } - break; - } - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -static ssize_t audevrc_in_read(struct file *file, - char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_in *audio = file->private_data; - unsigned long flags; - const char __user *start = buf; - void *data; - uint32_t index; - uint32_t size; - int rc = 0; - struct evrc_encoded_meta_out meta_field; - struct audio_frame_nt *nt_frame; - MM_DBG("count = %d\n", count); - mutex_lock(&audio->read_lock); - while (count > 0) { - rc = wait_event_interruptible( - audio->wait, (audio->in_count > 0) || audio->stopped || - audio->rflush || - ((audio->mode == MSM_AUD_ENC_MODE_TUNNEL) && - audio->in_call && audio->running && - (audio->voice_state == VOICE_STATE_OFFCALL))); - if (rc < 0) - break; - - if (audio->rflush) { - rc = -EBUSY; - break; - } - if (audio->stopped && !audio->in_count) { - MM_DBG("Driver in stop state, No more buffer to read"); - rc = 0;/* End of File */ - break; - } else if ((audio->mode == MSM_AUD_ENC_MODE_TUNNEL) && - audio->in_call && audio->running && - (audio->voice_state \ - == VOICE_STATE_OFFCALL)) { - MM_DBG("Not Permitted Voice Terminated\n"); - rc = -EPERM; /* Voice Call stopped */ - break; - } - - index = audio->in_tail; - data = (uint8_t *) audio->in[index].data; - size = audio->in[index].size; - - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) { - nt_frame = (struct audio_frame_nt *)(data - - sizeof(struct audio_frame_nt)); - memcpy((char *)&meta_field.time_stamp_dword_lsw, - (char *)&nt_frame->time_stamp_dword_lsw, - (sizeof(struct evrc_encoded_meta_out) - \ - sizeof(uint16_t))); - meta_field.metadata_len = - sizeof(struct evrc_encoded_meta_out); - if (copy_to_user((char *)start, (char *)&meta_field, - sizeof(struct evrc_encoded_meta_out))) { - rc = -EFAULT; - break; - } - if (nt_frame->nflag_lsw & 0x0001) { - MM_ERR("recieved EOS in read call\n"); - audio->eos_ack = 1; - } - buf += sizeof(struct evrc_encoded_meta_out); - count -= sizeof(struct evrc_encoded_meta_out); - } - if (count >= size) { - if (copy_to_user(buf, data, size)) { - rc = -EFAULT; - break; - } - spin_lock_irqsave(&audio->dsp_lock, flags); - if (index != audio->in_tail) { - /* overrun -- data is - * invalid and we need to retry */ - spin_unlock_irqrestore(&audio->dsp_lock, flags); - continue; - } - audio->in[index].size = 0; - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - audio->in_count--; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - count -= size; - buf += size; - if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL)) { - if (!audio->eos_ack) { - MM_DBG("sending read ptr command \ - %d %d\n", - audio->dsp_cnt, - audio->in_tail); - audevrc_dsp_read_buffer(audio, - audio->dsp_cnt++); - } - } - } else { - MM_ERR("short read\n"); - break; - } - break; - } - mutex_unlock(&audio->read_lock); - - if (buf > start) - return buf - start; - - return rc; -} - -static void audpreproc_pcm_send_data(struct audio_in *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - MM_DBG("\n"); - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - audpreproc_pcm_buffer_ptr_refresh(audio, - audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } - done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - - -static int audevrc_in_fsync(struct file *file, loff_t ppos1, loff_t ppos2, int datasync) - -{ - struct audio_in *audio = file->private_data; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - if (!audio->running || (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - audio->wflush); - MM_DBG("waked on by some event audio->wflush = %d\n", audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; - -} - - int audpreproc_evrc_process_eos(struct audio_in *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - struct buffer *frame; - int rc = 0; - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - MM_DBG("copying meta_out frame->used = %d\n", frame->used); - audpreproc_pcm_send_data(audio, 0); -done: - return rc; -} - -static ssize_t audevrc_in_write(struct file *file, - const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_in *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - char *cpy_ptr; - int rc = 0, eos_condition = AUDPREPROC_EVRC_EOS_NONE; - unsigned short mfield_size = 0; - int write_count = 0; - MM_DBG("cnt=%d\n", count); - - if (count & 1) - return -EINVAL; - - if (audio->mode != MSM_AUD_ENC_MODE_NONTUNNEL) - return -EINVAL; - - mutex_lock(&audio->write_lock); - frame = audio->out + audio->out_head; - /* if supplied count is more than driver buffer size - * then only copy driver buffer size - */ - if (count > frame->size) - count = frame->size; - - write_count = count; - cpy_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - goto error; - - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto error; - } - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - goto error; - } else if (mfield_size > count) { - rc = -EINVAL; - goto error; - } - MM_DBG("mf offset_val %x\n", mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - goto error; - } - /* Check if EOS flag is set and buffer has - * contains just meta field - */ - if (cpy_ptr[AUDPREPROC_EVRC_EOS_FLG_OFFSET] & - AUDPREPROC_EVRC_EOS_FLG_MASK) { - eos_condition = AUDPREPROC_EVRC_EOS_SET; - MM_DBG("EOS SET\n"); - if (mfield_size == count) { - buf += mfield_size; - eos_condition = 0; - goto exit; - } else - cpy_ptr[AUDPREPROC_EVRC_EOS_FLG_OFFSET] &= - ~AUDPREPROC_EVRC_EOS_FLG_MASK; - } - cpy_ptr += mfield_size; - count -= mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - MM_DBG("copying the stream count = %d\n", count); - if (copy_from_user(cpy_ptr, buf, count)) { - rc = -EFAULT; - goto error; - } -exit: - frame->used = count; - audio->out_head ^= 1; - if (!audio->flush_ack) - audpreproc_pcm_send_data(audio, 0); - else { - audpreproc_pcm_send_data(audio, 1); - audio->flush_ack = 0; - } - if (eos_condition == AUDPREPROC_EVRC_EOS_SET) - rc = audpreproc_evrc_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - return write_count; -error: - mutex_unlock(&audio->write_lock); - return rc; -} - -static int audevrc_in_release(struct inode *inode, struct file *file) -{ - struct audio_in *audio = file->private_data; - - mutex_lock(&audio->lock); - audio->in_call = 0; - /* with draw frequency for session - incase not stopped the driver */ - msm_snddev_withdraw_freq(audio->enc_id, SNDDEV_CAP_TX, - AUDDEV_CLNT_ENC); - auddev_unregister_evt_listner(AUDDEV_CLNT_ENC, audio->enc_id); - /*reset the sampling frequency information at audpreproc layer*/ - audio->session_info.sampling_freq = 0; - audpreproc_update_audrec_info(&audio->session_info); - audevrc_in_disable(audio); - audevrc_in_flush(audio); - msm_adsp_put(audio->audrec); - audpreproc_aenc_free(audio->enc_id); - audio->audrec = NULL; - audio->opened = 0; - if (audio->data) { - iounmap(audio->map_v_read); - free_contiguous_memory_by_paddr(audio->phys); - audio->data = NULL; - } - if (audio->out_data) { - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->out_phys); - audio->out_data = NULL; - } - mutex_unlock(&audio->lock); - return 0; -} - -struct audio_in the_audio_evrc_in; -static int audevrc_in_open(struct inode *inode, struct file *file) -{ - struct audio_in *audio = &the_audio_evrc_in; - int rc; - int encid; - - mutex_lock(&audio->lock); - if (audio->opened) { - rc = -EBUSY; - goto done; - } - audio->phys = allocate_contiguous_ebi_nomap(DMASZ, SZ_4K); - if (audio->phys) { - audio->map_v_read = ioremap(audio->phys, DMASZ); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("failed to map read physical address\n"); - rc = -ENOMEM; - free_contiguous_memory_by_paddr(audio->phys); - goto done; - } - audio->data = audio->map_v_read; - } else { - MM_ERR("could not allocate DMA buffers\n"); - rc = -ENOMEM; - goto done; - } - MM_DBG("Memory addr = 0x%8x phy addr = 0x%8x\n",\ - (int) audio->data, (int) audio->phys); - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - audio->mode = MSM_AUD_ENC_MODE_NONTUNNEL; - MM_DBG("Opened for non tunnel mode encoding\n"); - } else if (!(file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - audio->mode = MSM_AUD_ENC_MODE_TUNNEL; - MM_DBG("Opened for tunnel mode encoding\n"); - } else { - MM_ERR("Invalid mode\n"); - rc = -EACCES; - goto done; - } - - /* Settings will be re-config at AUDIO_SET_CONFIG, - * but at least we need to have initial config - */ - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) - audio->buffer_size = (EVRC_FRAME_SIZE + 14); - else - audio->buffer_size = (FRAME_SIZE - 8); - audio->enc_type = ENC_TYPE_EVRC | audio->mode; - audio->samp_rate = 8000; - audio->channel_mode = AUDREC_CMD_MODE_MONO; - audio->cfg.cdma_rate = CDMA_RATE_FULL; - audio->cfg.min_bit_rate = CDMA_RATE_FULL; - audio->cfg.max_bit_rate = CDMA_RATE_FULL; - - encid = audpreproc_aenc_alloc(audio->enc_type, &audio->module_name, - &audio->queue_ids); - if (encid < 0) { - MM_ERR("No free encoder available\n"); - rc = -ENODEV; - goto done; - } - audio->enc_id = encid; - - rc = msm_adsp_get(audio->module_name, &audio->audrec, - &audrec_evrc_adsp_ops, audio); - - if (rc) { - audpreproc_aenc_free(audio->enc_id); - goto done; - } - - audio->stopped = 0; - audio->source = 0; - audio->wflush = 0; - audio->rflush = 0; - audio->flush_ack = 0; - - audevrc_in_flush(audio); - audevrc_out_flush(audio); - - audio->out_phys = allocate_contiguous_ebi_nomap(BUFFER_SIZE, - SZ_4K); - if (!audio->out_phys) { - MM_ERR("could not allocate write buffers\n"); - rc = -ENOMEM; - goto evt_error; - } else { - audio->map_v_write = ioremap(audio->out_phys, BUFFER_SIZE); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could map write buffers\n"); - rc = -ENOMEM; - free_contiguous_memory_by_paddr(audio->out_phys); - goto evt_error; - } - audio->out_data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->out_phys, (int)audio->out_data); - } - - /* Initialize buffer */ - audio->out[0].data = audio->out_data + 0; - audio->out[0].addr = audio->out_phys + 0; - audio->out[0].size = OUT_BUFFER_SIZE; - - audio->out[1].data = audio->out_data + OUT_BUFFER_SIZE; - audio->out[1].addr = audio->out_phys + OUT_BUFFER_SIZE; - audio->out[1].size = OUT_BUFFER_SIZE; - - MM_DBG("audio->out[0].data = %d audio->out[1].data = %d", - (unsigned int)audio->out[0].data, - (unsigned int)audio->out[1].data); - audio->device_events = AUDDEV_EVT_DEV_RDY | AUDDEV_EVT_DEV_RLS | - AUDDEV_EVT_VOICE_STATE_CHG; - - audio->voice_state = msm_get_voice_state(); - rc = auddev_register_evt_listner(audio->device_events, - AUDDEV_CLNT_ENC, audio->enc_id, - evrc_in_listener, (void *) audio); - if (rc) { - MM_ERR("failed to register device event listener\n"); - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->out_phys); - goto evt_error; - } - audio->mfield = META_OUT_SIZE; - file->private_data = audio; - audio->opened = 1; - audio->out_frame_cnt++; - audio->build_id = socinfo_get_build_id(); - MM_DBG("Modem build id = %s\n", audio->build_id); - -done: - mutex_unlock(&audio->lock); - return rc; -evt_error: - msm_adsp_put(audio->audrec); - audpreproc_aenc_free(audio->enc_id); - mutex_unlock(&audio->lock); - return rc; -} - -static const struct file_operations audio_in_fops = { - .owner = THIS_MODULE, - .open = audevrc_in_open, - .release = audevrc_in_release, - .read = audevrc_in_read, - .write = audevrc_in_write, - .fsync = audevrc_in_fsync, - .unlocked_ioctl = audevrc_in_ioctl, -}; - -struct miscdevice audio_evrc_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_evrc_in", - .fops = &audio_in_fops, -}; - -static int __init audevrc_in_init(void) -{ - mutex_init(&the_audio_evrc_in.lock); - mutex_init(&the_audio_evrc_in.read_lock); - spin_lock_init(&the_audio_evrc_in.dsp_lock); - spin_lock_init(&the_audio_evrc_in.dev_lock); - init_waitqueue_head(&the_audio_evrc_in.wait); - init_waitqueue_head(&the_audio_evrc_in.wait_enable); - mutex_init(&the_audio_evrc_in.write_lock); - init_waitqueue_head(&the_audio_evrc_in.write_wait); - return misc_register(&audio_evrc_in_misc); -} - -device_initcall(audevrc_in_init); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_fm.c b/arch/arm/mach-msm/qdsp5v2/audio_fm.c deleted file mode 100644 index cffa7e72d1885fe5dfb4d2482f7758575ade4c38..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_fm.c +++ /dev/null @@ -1,358 +0,0 @@ -/* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved. - * - * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * - * All source code in this file is licensed under the following license except - * where indicated. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SESSION_ID_FM 6 -#define FM_ENABLE 0xFFFF -#define FM_DISABLE 0x0 -#define FM_COPP 0x2 -/* Macro specifies maximum FM routing - possible */ -#define FM_MAX_RX_ROUTE 0x2 - -struct fm_rx_calib_gain { - uint16_t device_id; - struct auddev_evt_devinfo dev_details; - struct acdb_calib_gain_rx calib_rx; -}; - -struct audio { - struct mutex lock; - - int opened; - int enabled; - int running; - - uint16_t dec_id; - uint16_t source; - uint16_t fm_source; - uint16_t fm_mask; - uint32_t device_events; - uint16_t volume; - struct fm_rx_calib_gain fm_calibration_rx[FM_MAX_RX_ROUTE]; -}; - -static struct audio fm_audio; - -/* must be called with audio->lock held */ -static int audio_enable(struct audio *audio) -{ - int rc = 0; - if (audio->enabled) - return 0; - - MM_DBG("fm mask= %08x fm_source = %08x\n", - audio->fm_mask, audio->fm_source); - if (audio->fm_mask && audio->fm_source) { - rc = afe_config_fm_codec(FM_ENABLE, audio->fm_mask); - if (!rc) - audio->running = 1; - /* Routed to icodec rx path */ - if ((audio->fm_mask & AFE_HW_PATH_CODEC_RX) == - AFE_HW_PATH_CODEC_RX) { - afe_config_fm_calibration_gain( - audio->fm_calibration_rx[0].device_id, - audio->fm_calibration_rx[0].calib_rx.audppcalgain); - } - /* Routed to aux codec rx path */ - if ((audio->fm_mask & AFE_HW_PATH_AUXPCM_RX) == - AFE_HW_PATH_AUXPCM_RX){ - afe_config_fm_calibration_gain( - audio->fm_calibration_rx[1].device_id, - audio->fm_calibration_rx[1].calib_rx.audppcalgain); - } - } - - audio->enabled = 1; - return rc; -} - -static void fm_listner(u32 evt_id, union auddev_evt_data *evt_payload, - void *private_data) -{ - struct audio *audio = (struct audio *) private_data; - struct auddev_evt_devinfo *devinfo = - (struct auddev_evt_devinfo *)evt_payload; - switch (evt_id) { - case AUDDEV_EVT_DEV_RDY: - MM_DBG(":AUDDEV_EVT_DEV_RDY\n"); - if (evt_payload->routing_id == FM_COPP) - audio->fm_source = 1; - else - audio->source = (0x1 << evt_payload->routing_id); - - if (audio->source & 0x1) - audio->fm_mask = 0x1; - else if (audio->source & 0x2) - audio->fm_mask = 0x3; - else - audio->fm_mask = 0x0; - - if (!audio->enabled - || !audio->fm_mask - || !audio->fm_source) - break; - else { - afe_config_fm_codec(FM_ENABLE, audio->fm_mask); - audio->running = 1; - } - break; - case AUDDEV_EVT_DEV_RLS: - MM_DBG(":AUDDEV_EVT_DEV_RLS\n"); - if (evt_payload->routing_id == FM_COPP) - audio->fm_source = 0; - else - audio->source &= ~(0x1 << evt_payload->routing_id); - - if (audio->source & 0x1) - audio->fm_mask = 0x1; - else if (audio->source & 0x2) - audio->fm_mask = 0x3; - else - audio->fm_mask = 0x0; - - if (audio->running - && (!audio->fm_mask || !audio->fm_source)) { - afe_config_fm_codec(FM_DISABLE, audio->fm_mask); - audio->running = 0; - } - break; - case AUDDEV_EVT_STREAM_VOL_CHG: - MM_DBG(":AUDDEV_EVT_STREAM_VOL_CHG, stream vol \n"); - audio->volume = evt_payload->session_vol; - afe_config_fm_volume(audio->volume); - break; - case AUDDEV_EVT_DEVICE_INFO:{ - struct acdb_get_block get_block; - int rc = 0; - MM_DBG(":AUDDEV_EVT_DEVICE_INFO\n"); - MM_DBG("sample_rate = %d\n", devinfo->sample_rate); - MM_DBG("acdb_id = %d\n", devinfo->acdb_id); - /* Applucable only for icodec rx and aux codec rx path - and fm stream routed to it */ - if (((devinfo->dev_id == 0x00) || (devinfo->dev_id == 0x01)) && - (devinfo->sessions && (1 << audio->dec_id))) { - /* Query ACDB driver for calib gain, only if difference - in device */ - if ((audio->fm_calibration_rx[devinfo->dev_id]. - dev_details.acdb_id != devinfo->acdb_id) || - (audio->fm_calibration_rx[devinfo->dev_id]. - dev_details.sample_rate != - devinfo->sample_rate)) { - audio->fm_calibration_rx[devinfo->dev_id]. - dev_details.dev_id = devinfo->dev_id; - audio->fm_calibration_rx[devinfo->dev_id]. - dev_details.sample_rate = - devinfo->sample_rate; - audio->fm_calibration_rx[devinfo->dev_id]. - dev_details.dev_type = - devinfo->dev_type; - audio->fm_calibration_rx[devinfo->dev_id]. - dev_details.sessions = - devinfo->sessions; - /* Query ACDB driver for calibration gain */ - get_block.acdb_id = devinfo->acdb_id; - get_block.sample_rate_id = devinfo->sample_rate; - get_block.interface_id = - IID_AUDIO_CALIBRATION_GAIN_RX; - get_block.algorithm_block_id = - ABID_AUDIO_CALIBRATION_GAIN_RX; - get_block.total_bytes = - sizeof(struct acdb_calib_gain_rx); - get_block.buf_ptr = (u32 *) - &audio->fm_calibration_rx[devinfo->dev_id]. - calib_rx; - - rc = acdb_get_calibration_data(&get_block); - if (rc < 0) { - MM_ERR("Unable to get calibration"\ - "gain\n"); - /* Set to unity incase of error */ - audio->\ - fm_calibration_rx[devinfo->dev_id]. - calib_rx.audppcalgain = 0x2000; - } else - MM_DBG("calibration gain = 0x%8x\n", - *(get_block.buf_ptr)); - } - if (audio->running) { - afe_config_fm_calibration_gain( - audio->fm_calibration_rx[devinfo->dev_id]. - device_id, - audio->fm_calibration_rx[devinfo->dev_id]. - calib_rx.audppcalgain); - } - } - break; - } - default: - MM_DBG(":ERROR:wrong event\n"); - break; - } -} -/* must be called with audio->lock held */ -static int audio_disable(struct audio *audio) -{ - MM_DBG("\n"); /* Macro prints the file name and function */ - return afe_config_fm_codec(FM_DISABLE, audio->source); -} - -static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - - MM_DBG("cmd = %d\n", cmd); - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audio_enable(audio); - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audio_disable(audio); - audio->running = 0; - audio->enabled = 0; - break; - case AUDIO_GET_SESSION_ID: - if (copy_to_user((void *) arg, &audio->dec_id, - sizeof(unsigned short))) - rc = -EFAULT; - else - rc = 0; - break; - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -static int audio_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_DBG("audio instance 0x%08x freeing\n", (int)audio); - mutex_lock(&audio->lock); - auddev_unregister_evt_listner(AUDDEV_CLNT_DEC, audio->dec_id); - audio_disable(audio); - audio->running = 0; - audio->enabled = 0; - audio->opened = 0; - mutex_unlock(&audio->lock); - return 0; -} - -static int audio_open(struct inode *inode, struct file *file) -{ - struct audio *audio = &fm_audio; - int rc = 0; - - - if (audio->opened) - return -EPERM; - - /* Allocate the decoder */ - audio->dec_id = SESSION_ID_FM; - - audio->running = 0; - audio->fm_source = 0; - audio->fm_mask = 0; - - /* Initialize the calibration gain structure */ - audio->fm_calibration_rx[0].device_id = AFE_HW_PATH_CODEC_RX; - audio->fm_calibration_rx[1].device_id = AFE_HW_PATH_AUXPCM_RX; - audio->fm_calibration_rx[0].calib_rx.audppcalgain = 0x2000; - audio->fm_calibration_rx[1].calib_rx.audppcalgain = 0x2000; - audio->fm_calibration_rx[0].dev_details.acdb_id = PSEUDO_ACDB_ID; - audio->fm_calibration_rx[1].dev_details.acdb_id = PSEUDO_ACDB_ID; - - audio->device_events = AUDDEV_EVT_DEV_RDY - |AUDDEV_EVT_DEV_RLS| - AUDDEV_EVT_STREAM_VOL_CHG| - AUDDEV_EVT_DEVICE_INFO; - - rc = auddev_register_evt_listner(audio->device_events, - AUDDEV_CLNT_DEC, - audio->dec_id, - fm_listner, - (void *)audio); - - if (rc) { - MM_ERR("%s: failed to register listnet\n", __func__); - goto event_err; - } - - audio->opened = 1; - file->private_data = audio; - -event_err: - return rc; -} - -static const struct file_operations audio_fm_fops = { - .owner = THIS_MODULE, - .open = audio_open, - .release = audio_release, - .unlocked_ioctl = audio_ioctl, -}; - -struct miscdevice audio_fm_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_fm", - .fops = &audio_fm_fops, -}; - -static int __init audio_init(void) -{ - struct audio *audio = &fm_audio; - - mutex_init(&audio->lock); - return misc_register(&audio_fm_misc); -} - -device_initcall(audio_init); - -MODULE_DESCRIPTION("MSM FM driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_interct.c b/arch/arm/mach-msm/qdsp5v2/audio_interct.c deleted file mode 100644 index 4e4c5d621deeb14eb7b06a17ff661a24ca401608..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_interct.c +++ /dev/null @@ -1,124 +0,0 @@ -/* Copyright (c) 2009, 2011 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include - -#define AUDIO_INTERCT_ADSPLPA_WBRX_SEL_BMSK 0x4 -#define AUDIO_INTERCT_ADSPLPA_WBRX_SEL_SHFT 0x2 -#define AUDIO_INTERCT_ADSPAV_RPCMI2SRX_SEL_BMSK 0x10 -#define AUDIO_INTERCT_ADSPAV_RPCMI2SRX_SEL_SHFT 0x4 -#define AUDIO_INTERCT_ADSPAV_TPCMI2STX_SEL_BMSK 0x40 -#define AUDIO_INTERCT_ADSPAV_TPCMI2STX_SEL_SHFT 0x6 -#define AUDIO_INTERCT_ADSPAV_AUX_REGSEL_BMSK 0x100 -#define AUDIO_INTERCT_ADSPAV_AUX_REGSEL_SHFT 0x8 - -/* Should look to protect this register */ -void __iomem *aictl_reg; - -void audio_interct_codec(u32 source) -{ - u32 reg_val; - - reg_val = readl(aictl_reg); - reg_val = (reg_val & ~AUDIO_INTERCT_ADSPLPA_WBRX_SEL_BMSK) | - (source << AUDIO_INTERCT_ADSPLPA_WBRX_SEL_SHFT); - writel(reg_val, aictl_reg); - mb(); -} -EXPORT_SYMBOL(audio_interct_codec); - -void audio_interct_aux_regsel(u32 source) -{ - u32 reg_val; - - reg_val = readl(aictl_reg); - reg_val = (reg_val & ~AUDIO_INTERCT_ADSPAV_AUX_REGSEL_BMSK) | - (source << AUDIO_INTERCT_ADSPAV_AUX_REGSEL_SHFT); - writel(reg_val, aictl_reg); - mb(); -} -EXPORT_SYMBOL(audio_interct_aux_regsel); - -void audio_interct_tpcm_source(u32 source) -{ - u32 reg_val; - - reg_val = readl(aictl_reg); - reg_val = (reg_val & ~AUDIO_INTERCT_ADSPAV_TPCMI2STX_SEL_BMSK) | - (source << AUDIO_INTERCT_ADSPAV_TPCMI2STX_SEL_SHFT); - writel(reg_val, aictl_reg); - mb(); -} -EXPORT_SYMBOL(audio_interct_tpcm_source); - -void audio_interct_rpcm_source(u32 source) -{ - u32 reg_val; - - reg_val = readl(aictl_reg); - reg_val = (reg_val & ~AUDIO_INTERCT_ADSPAV_RPCMI2SRX_SEL_BMSK) | - (source << AUDIO_INTERCT_ADSPAV_RPCMI2SRX_SEL_SHFT); - writel(reg_val, aictl_reg); - mb(); -} -EXPORT_SYMBOL(audio_interct_rpcm_source); - -static int audio_interct_probe(struct platform_device *pdev) -{ - int rc = 0; - struct resource *aictl_mem; - - aictl_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!aictl_mem) { - rc = -ENODEV; - goto error; - } - aictl_reg = ioremap(aictl_mem->start, - (aictl_mem->end - aictl_mem->start) + 1); -error: - return rc; -} - - -static int audio_interct_remove(struct platform_device *pdev) -{ - iounmap(aictl_reg); - return 0; -} - -static struct platform_driver audio_interct_driver = { - .probe = audio_interct_probe, - .remove = audio_interct_remove, - .driver = { - .name = "audio_interct", - .owner = THIS_MODULE, - }, -}; - -static int __init audio_interct_init(void) -{ - return platform_driver_register(&audio_interct_driver); -} - -static void __exit audio_interct_exit(void) -{ - platform_driver_unregister(&audio_interct_driver); -} - -module_init(audio_interct_init); -module_exit(audio_interct_exit); - -MODULE_DESCRIPTION("MSM Audio Interconnect driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_lpa.c b/arch/arm/mach-msm/qdsp5v2/audio_lpa.c deleted file mode 100644 index 8a72deaa1ef51d9aa1bd4572c4f73bccb40843a3..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_lpa.c +++ /dev/null @@ -1,1749 +0,0 @@ -/* low power audio output device - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define ADRV_STATUS_AIO_INTF 0x00000001 -#define ADRV_STATUS_OBUF_GIVEN 0x00000002 -#define ADRV_STATUS_IBUF_GIVEN 0x00000004 -#define ADRV_STATUS_FSYNC 0x00000008 -#define ADRV_STATUS_PAUSE 0x00000010 - -#define DEVICE_SWITCH_STATE_NONE 0 -#define DEVICE_SWITCH_STATE_PENDING 1 -#define DEVICE_SWITCH_STATE_READY 2 -#define DEVICE_SWITCH_STATE_COMPLETE 3 - -#define AUDDEC_DEC_PCM 0 -#define AUDDEC_DEC_MP3 2 - -#define PCM_BUFSZ_MIN 4800 /* Hold one stereo MP3 frame */ - -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDMP3_METAFIELD_MASK 0xFFFF0000 -#define AUDMP3_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */ -#define AUDMP3_EOS_FLG_MASK 0x01 -#define AUDMP3_EOS_NONE 0x0 /* No EOS detected */ -#define AUDMP3_EOS_SET 0x1 /* EOS set in meta field */ - -#define AUDLPA_EVENT_NUM 10 /* Default number of pre-allocated event packets */ - -#define MASK_32BITS 0xFFFFFFFF - -#define MAX_BUF 4 -#define BUFSZ (524288) - -#define __CONTAINS(r, v, l) ({ \ - typeof(r) __r = r; \ - typeof(v) __v = v; \ - typeof(v) __e = __v + l; \ - int res = ((__v >= __r->vaddr) && \ - (__e <= __r->vaddr + __r->len)); \ - res; \ -}) - -#define CONTAINS(r1, r2) ({ \ - typeof(r2) __r2 = r2; \ - __CONTAINS(r1, __r2->vaddr, __r2->len); \ -}) - -#define IN_RANGE(r, v) ({ \ - typeof(r) __r = r; \ - typeof(v) __vv = v; \ - int res = ((__vv >= __r->vaddr) && \ - (__vv < (__r->vaddr + __r->len))); \ - res; \ -}) - -#define OVERLAPS(r1, r2) ({ \ - typeof(r1) __r1 = r1; \ - typeof(r2) __r2 = r2; \ - typeof(__r2->vaddr) __v = __r2->vaddr; \ - typeof(__v) __e = __v + __r2->len - 1; \ - int res = (IN_RANGE(__r1, __v) || IN_RANGE(__r1, __e)); \ - res; \ -}) - -/* payload[7]; -1 indicates error, 0 indicates no error */ -#define CHECK_ERROR(v) (!v[7]) - -/* calculates avsync_info from payload */ -#define CALCULATE_AVSYNC_FROM_PAYLOAD(v) ((uint64_t)((((uint64_t)v[10]) \ - << 32) | (v[11] & MASK_32BITS))) - -/* calculates avsync_info from avsync_info stored in audio */ -#define CALCULATE_AVSYNC(v) \ - ((uint64_t)((((uint64_t)v[4]) << 32) | \ - (v[5] << 16) | (v[6]))) - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audlpa_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct audlpa_event { - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audlpa_pmem_region { - struct list_head list; - struct file *file; - int fd; - void *vaddr; - unsigned long paddr; - unsigned long kvaddr; - unsigned long len; - unsigned ref_cnt; -}; - -struct audlpa_buffer_node { - struct list_head list; - struct msm_audio_aio_buf buf; - unsigned long paddr; -}; - -struct audlpa_dec { - char *name; - int dec_attrb; - long (*ioctl)(struct file *, unsigned int, unsigned long); - void (*adec_params)(struct audio *); -}; - -struct audlpa_dec audlpa_decs[] = { - {"msm_mp3_lp", AUDDEC_DEC_MP3, &mp3_ioctl, &audpp_cmd_cfg_mp3_params}, - {"msm_pcm_lp_dec", AUDDEC_DEC_PCM, &pcm_ioctl, - &audpp_cmd_cfg_pcm_params}, -}; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg); -static void audlpa_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); -static unsigned long audlpa_pmem_fixup(struct audio *audio, void *addr, - unsigned long len, int ref_up); -static void audlpa_async_send_data(struct audio *audio, unsigned needed, - uint32_t *payload); - -static void lpa_listner(u32 evt_id, union auddev_evt_data *evt_payload, - void *private_data) -{ - struct audio *audio = (struct audio *) private_data; - switch (evt_id) { - case AUDDEV_EVT_DEV_RDY: - MM_DBG(":AUDDEV_EVT_DEV_RDY routing id = %d\n", - evt_payload->routing_id); - /* Do not select HLB path for icodec, if there is already COPP3 - * routing exists. DSP can not support concurrency of HLB path - * and COPP3 routing as it involves different buffer Path */ - if (((0x1 << evt_payload->routing_id) == AUDPP_MIXER_ICODEC) && - !(audio->source & AUDPP_MIXER_3)) { - audio->source |= AUDPP_MIXER_HLB; - MM_DBG("mixer_mask modified for low-power audio\n"); - } else - audio->source |= (0x1 << evt_payload->routing_id); - - MM_DBG("running = %d, enabled = %d, source = 0x%x\n", - audio->running, audio->enabled, audio->source); - if (audio->running == 1 && audio->enabled == 1) { - audpp_route_stream(audio->dec_id, audio->source); - if (audio->source & AUDPP_MIXER_HLB) { - audpp_dsp_set_vol_pan( - AUDPP_CMD_CFG_DEV_MIXER_ID_4, - &audio->vol_pan, - COPP); - /*restore the POPP gain to 0x2000 - this is needed to avoid use cases - where POPP volume is lowered during - NON HLB playback, when device moved - from NON HLB to HLB POPP is not - disabled but POPP gain will be retained - as the old one which result - in lower volume*/ - audio->vol_pan.volume = 0x2000; - audpp_dsp_set_vol_pan( - audio->dec_id, - &audio->vol_pan, POPP); - } else if (audio->source & AUDPP_MIXER_NONHLB) - audpp_dsp_set_vol_pan( - audio->dec_id, &audio->vol_pan, POPP); - if (audio->device_switch == DEVICE_SWITCH_STATE_READY) { - audio->wflush = 1; - audio->device_switch = - DEVICE_SWITCH_STATE_COMPLETE; - audpp_flush(audio->dec_id); - if (wait_event_interruptible(audio->write_wait, - !audio->wflush) < 0) - MM_DBG("AUDIO_FLUSH interrupted\n"); - - if (audio->wflush == 0) { - if (audio->drv_status & - ADRV_STATUS_PAUSE) { - if (audpp_pause(audio->dec_id, - 1)) - MM_DBG("audpp_pause" - "failed\n"); - } - } - } - } - break; - case AUDDEV_EVT_REL_PENDING: - MM_DBG(":AUDDEV_EVT_REL_PENDING\n"); - /* If route to multiple devices like COPP3, not need to - * handle device switch */ - if ((audio->running == 1) && (audio->enabled == 1) && - !(audio->source & AUDPP_MIXER_3)) { - if (audio->device_switch == DEVICE_SWITCH_STATE_NONE) { - if (!(audio->drv_status & ADRV_STATUS_PAUSE)) { - if (audpp_pause(audio->dec_id, 1)) - MM_DBG("audpp pause failed\n"); - } - audio->device_switch = - DEVICE_SWITCH_STATE_PENDING; - audio->avsync_flag = 0; - if (audpp_query_avsync(audio->dec_id) < 0) - MM_DBG("query avsync failed\n"); - - if (wait_event_interruptible_timeout - (audio->avsync_wait, audio->avsync_flag, - msecs_to_jiffies(AVSYNC_EVENT_TIMEOUT)) < 0) - MM_DBG("AV sync timeout failed\n"); - if (audio->avsync_flag == 1) { - if (audio->device_switch == - DEVICE_SWITCH_STATE_PENDING) - audio->device_switch = - DEVICE_SWITCH_STATE_READY; - } - } - } - break; - case AUDDEV_EVT_DEV_RLS: - /* If there is already COPP3 routing exists. icodec route - * was not having HLB path. */ - MM_DBG(":AUDDEV_EVT_DEV_RLS routing id = %d\n", - evt_payload->routing_id); - if (((0x1 << evt_payload->routing_id) == AUDPP_MIXER_ICODEC) && - !(audio->source & AUDPP_MIXER_3)) - audio->source &= ~AUDPP_MIXER_HLB; - else - audio->source &= ~(0x1 << evt_payload->routing_id); - MM_DBG("running = %d, enabled = %d, source = 0x%x\n", - audio->running, audio->enabled, audio->source); - - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - break; - case AUDDEV_EVT_STREAM_VOL_CHG: - audio->vol_pan.volume = evt_payload->session_vol; - MM_DBG("\n:AUDDEV_EVT_STREAM_VOL_CHG, stream vol %d\n" - "running = %d, enabled = %d, source = 0x%x", - audio->vol_pan.volume, audio->running, - audio->enabled, audio->source); - if (audio->running == 1 && audio->enabled == 1) { - if (audio->source & AUDPP_MIXER_HLB) - audpp_dsp_set_vol_pan( - AUDPP_CMD_CFG_DEV_MIXER_ID_4, - &audio->vol_pan, COPP); - else if (audio->source & AUDPP_MIXER_NONHLB) - audpp_dsp_set_vol_pan( - audio->dec_id, &audio->vol_pan, POPP); - } - break; - default: - MM_ERR(":ERROR:wrong event\n"); - break; - } -} - -/* must be called with audio->lock held */ -static int audio_enable(struct audio *audio) -{ - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (audio->enabled) - return 0; - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_needed = 0; - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - return -ENODEV; - } - - audio->enabled = 1; - return 0; -} - -/* must be called with audio->lock held */ -static int audio_disable(struct audio *audio) -{ - int rc = 0; - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - wake_up(&audio->write_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - audio->out_needed = 0; - } - return rc; -} - -/* ------------------- dsp --------------------- */ -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - getevent(msg, sizeof(msg)); - - MM_DBG("msg_id=%x\n", id); - - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audlpa_async_send_data(audio, 1, msg); - break; - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audplaytask)\n"); - break; - default: - MM_ERR("unexpected message from decoder\n"); - break; - } -} - -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status: sleep reason=0x%04x\n", - reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init\n"); - audio->codec_ops.adec_params(audio); - break; - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg\n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play\n"); - /* send mixer command */ - audpp_route_stream(audio->dec_id, - audio->source); - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - case AUDPP_DEC_STATUS_EOS: - MM_DBG("decoder status: EOS\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - default: - MM_ERR("unknown decoder status\n"); - break; - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - MM_DBG("source = 0x%x\n", audio->source); - if (audio->source & AUDPP_MIXER_HLB) - audpp_dsp_set_vol_pan( - AUDPP_CMD_CFG_DEV_MIXER_ID_4, - &audio->vol_pan, - COPP); - else if (audio->source & AUDPP_MIXER_NONHLB) - audpp_dsp_set_vol_pan( - audio->dec_id, &audio->vol_pan, - POPP); - audpp_dsp_set_eq(audio->dec_id, audio->eq_enable, - &audio->eq, POPP); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audio->running = 0; - } else { - MM_DBG("CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_ROUTING_ACK: - MM_DBG("ROUTING_ACK mode=%d\n", msg[1]); - audio->codec_ops.adec_params(audio); - break; - - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - wake_up(&audio->write_wait); - break; - - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - wake_up(&audio->write_wait); - break; - - case AUDPP_MSG_AVSYNC_MSG: - MM_DBG("AVSYNC_MSG\n"); - memcpy(&audio->avsync[0], msg, sizeof(audio->avsync)); - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); - break; - - default: - MM_ERR("UNKNOWN (%d)\n", id); - } - -} - -struct msm_adsp_ops audplay_adsp_ops_lpa = { - .event = audplay_dsp_event, -}; - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id, \ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - struct audpp_cmd_cfg_dec_type cfg_dec_cmd; - - memset(&cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - - cfg_dec_cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE; - if (enable) - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | - audlpa_decs[audio->minor_no].dec_attrb; - else - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - cfg_dec_cmd.dm_mode = 0x0; - cfg_dec_cmd.stream_id = audio->dec_id; - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} - -static void audlpa_async_send_buffer(struct audio *audio) -{ - int found = 0; - uint64_t temp = 0; - struct audplay_cmd_bitstream_data_avail cmd; - struct audlpa_buffer_node *next_buf = NULL; - - temp = audio->bytecount_head; - if (audio->device_switch == DEVICE_SWITCH_STATE_NONE) { - list_for_each_entry(next_buf, &audio->out_queue, list) { - if (temp == audio->bytecount_given) { - found = 1; - break; - } else - temp += next_buf->buf.data_len; - } - if (next_buf && found) { - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL; - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = (unsigned) next_buf->paddr; - cmd.buf_size = next_buf->buf.data_len >> 1; - cmd.partition_number = 0; - audio->bytecount_given += next_buf->buf.data_len; - wmb(); - audplay_send_queue0(audio, &cmd, sizeof(cmd)); - audio->out_needed = 0; - audio->drv_status |= ADRV_STATUS_OBUF_GIVEN; - } - } else if (audio->device_switch == DEVICE_SWITCH_STATE_COMPLETE) { - audio->device_switch = DEVICE_SWITCH_STATE_NONE; - next_buf = list_first_entry(&audio->out_queue, - struct audlpa_buffer_node, list); - if (next_buf) { - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL; - cmd.decoder_id = audio->dec_id; - temp = audio->bytecount_head + - next_buf->buf.data_len - - audio->bytecount_consumed; - if (audpp_restore_avsync(audio->dec_id, - &audio->avsync[0])) - MM_DBG("audpp_restore_avsync failed\n"); - - if ((signed)(temp >= 0) && - ((signed)(next_buf->buf.data_len - temp) >= 0)) { - MM_DBG("audlpa_async_send_buffer - sending the" - "rest of the buffer bassedon AV sync"); - cmd.buf_ptr = (unsigned) (next_buf->paddr + - (next_buf->buf.data_len - - temp)); - cmd.buf_size = temp >> 1; - cmd.partition_number = 0; - audio->bytecount_given = - audio->bytecount_consumed + temp; - wmb(); - audplay_send_queue0(audio, &cmd, sizeof(cmd)); - audio->out_needed = 0; - audio->drv_status |= ADRV_STATUS_OBUF_GIVEN; - } else if ((signed)(temp >= 0) && - ((signed)(next_buf->buf.data_len - - temp) < 0)) { - MM_DBG("audlpa_async_send_buffer - else case:" - "sending the rest of the buffer bassedon" - "AV sync"); - cmd.buf_ptr = (unsigned) next_buf->paddr; - cmd.buf_size = next_buf->buf.data_len >> 1; - cmd.partition_number = 0; - audio->bytecount_given = audio->bytecount_head + - next_buf->buf.data_len; - wmb(); - audplay_send_queue0(audio, &cmd, sizeof(cmd)); - audio->out_needed = 0; - audio->drv_status |= ADRV_STATUS_OBUF_GIVEN; - } - } - } -} - -static void audlpa_async_send_data(struct audio *audio, unsigned needed, - uint32_t *payload) -{ - unsigned long flags; - uint64_t temp = 0; - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - audio->out_needed = 1; - if (audio->drv_status & ADRV_STATUS_OBUF_GIVEN) { - union msm_audio_event_payload evt_payload; - struct audlpa_buffer_node *used_buf = NULL; - - if (CHECK_ERROR(payload)) - audio->bytecount_consumed = - CALCULATE_AVSYNC_FROM_PAYLOAD(payload); - - if ((audio->device_switch == - DEVICE_SWITCH_STATE_COMPLETE) && - (audio->avsync_flag == 1)) { - audio->avsync_flag = 0; - audio->bytecount_consumed = - CALCULATE_AVSYNC(audio->avsync); - } - BUG_ON(list_empty(&audio->out_queue)); - temp = audio->bytecount_head; - used_buf = list_first_entry(&audio->out_queue, - struct audlpa_buffer_node, list); - if (audio->device_switch != - DEVICE_SWITCH_STATE_COMPLETE) { - audio->bytecount_head += - used_buf->buf.data_len; - temp = audio->bytecount_head; - list_del(&used_buf->list); - evt_payload.aio_buf = used_buf->buf; - audlpa_post_event(audio, - AUDIO_EVENT_WRITE_DONE, - evt_payload); - kfree(used_buf); - audio->drv_status &= ~ADRV_STATUS_OBUF_GIVEN; - } - } - } - if (audio->out_needed) { - if (!list_empty(&audio->out_queue)) - audlpa_async_send_buffer(audio); - } -done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ -static void audlpa_async_flush(struct audio *audio) -{ - struct audlpa_buffer_node *buf_node; - struct list_head *ptr, *next; - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - list_for_each_safe(ptr, next, &audio->out_queue) { - buf_node = list_entry(ptr, struct audlpa_buffer_node, list); - list_del(&buf_node->list); - payload.aio_buf = buf_node->buf; - if ((buf_node->paddr != 0xFFFFFFFF) && - (buf_node->buf.data_len != 0)) - audlpa_post_event(audio, AUDIO_EVENT_WRITE_DONE, - payload); - kfree(buf_node); - } - audio->drv_status &= ~ADRV_STATUS_OBUF_GIVEN; - audio->out_needed = 0; - audio->bytecount_consumed = 0; - audio->bytecount_head = 0; - audio->bytecount_given = 0; - audio->device_switch = DEVICE_SWITCH_STATE_NONE; - atomic_set(&audio->out_bytes, 0); -} - -static void audio_ioport_reset(struct audio *audio) -{ - /* If fsync is in progress, make sure - * return value of fsync indicates - * abort due to flush - */ - if (audio->drv_status & ADRV_STATUS_FSYNC) { - MM_DBG("fsync in progress\n"); - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audlpa_async_flush(audio); - mutex_unlock(&audio->write_lock); - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); - } else - audlpa_async_flush(audio); -} - -static int audlpa_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audlpa_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audlpa_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audlpa_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audlpa_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - -static long audlpa_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audlpa_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - audio->event_wait, audlpa_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audlpa_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - rc = 0; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audlpa_event, list); - list_del(&drv_evt->list); - } - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - if (drv_evt->event_type == AUDIO_EVENT_WRITE_DONE || - drv_evt->event_type == AUDIO_EVENT_READ_DONE) { - mutex_lock(&audio->lock); - audlpa_pmem_fixup(audio, drv_evt->payload.aio_buf.buf_addr, - drv_evt->payload.aio_buf.buf_len, 0); - mutex_unlock(&audio->lock); - } - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audlpa_pmem_check(struct audio *audio, - void *vaddr, unsigned long len) -{ - struct audlpa_pmem_region *region_elt; - struct audlpa_pmem_region t = { .vaddr = vaddr, .len = len }; - - list_for_each_entry(region_elt, &audio->pmem_region_queue, list) { - if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) || - OVERLAPS(region_elt, &t)) { - MM_ERR("region (vaddr %p len %ld)" - " clashes with registered region" - " (vaddr %p paddr %p len %ld)\n", - vaddr, len, - region_elt->vaddr, - (void *)region_elt->paddr, - region_elt->len); - return -EINVAL; - } - } - - return 0; -} - -static int audlpa_pmem_add(struct audio *audio, - struct msm_audio_pmem_info *info) -{ - unsigned long paddr, kvaddr, len; - struct file *file; - struct audlpa_pmem_region *region; - int rc = -EINVAL; - - MM_DBG("\n"); /* Macro prints the file name and function */ - region = kmalloc(sizeof(*region), GFP_KERNEL); - - if (!region) { - rc = -ENOMEM; - goto end; - } - - if (get_pmem_file(info->fd, &paddr, &kvaddr, &len, &file)) { - kfree(region); - goto end; - } - - rc = audlpa_pmem_check(audio, info->vaddr, len); - if (rc < 0) { - put_pmem_file(file); - kfree(region); - goto end; - } - - region->vaddr = info->vaddr; - region->fd = info->fd; - region->paddr = paddr; - region->kvaddr = kvaddr; - region->len = len; - region->file = file; - region->ref_cnt = 0; - MM_DBG("add region paddr %lx vaddr %p, len %lu\n", region->paddr, - region->vaddr, region->len); - list_add_tail(®ion->list, &audio->pmem_region_queue); -end: - return rc; -} - -static int audlpa_pmem_remove(struct audio *audio, - struct msm_audio_pmem_info *info) -{ - struct audlpa_pmem_region *region; - struct list_head *ptr, *next; - int rc = -EINVAL; - - MM_DBG("info fd %d vaddr %p\n", info->fd, info->vaddr); - - list_for_each_safe(ptr, next, &audio->pmem_region_queue) { - region = list_entry(ptr, struct audlpa_pmem_region, list); - - if ((region->fd == info->fd) && - (region->vaddr == info->vaddr)) { - if (region->ref_cnt) { - MM_DBG("region %p in use ref_cnt %d\n", - region, region->ref_cnt); - break; - } - MM_DBG("remove region fd %d vaddr %p\n", - info->fd, info->vaddr); - list_del(®ion->list); - put_pmem_file(region->file); - kfree(region); - rc = 0; - break; - } - } - - return rc; -} - -static int audlpa_pmem_lookup_vaddr(struct audio *audio, void *addr, - unsigned long len, struct audlpa_pmem_region **region) -{ - struct audlpa_pmem_region *region_elt; - - int match_count = 0; - - *region = NULL; - - /* returns physical address or zero */ - list_for_each_entry(region_elt, &audio->pmem_region_queue, - list) { - if (addr >= region_elt->vaddr && - addr < region_elt->vaddr + region_elt->len && - addr + len <= region_elt->vaddr + region_elt->len) { - /* offset since we could pass vaddr inside a registerd - * pmem buffer - */ - - match_count++; - if (!*region) - *region = region_elt; - } - } - - if (match_count > 1) { - MM_ERR("multiple hits for vaddr %p, len %ld\n", addr, len); - list_for_each_entry(region_elt, - &audio->pmem_region_queue, list) { - if (addr >= region_elt->vaddr && - addr < region_elt->vaddr + region_elt->len && - addr + len <= region_elt->vaddr + region_elt->len) - MM_ERR("\t%p, %ld --> %p\n", region_elt->vaddr, - region_elt->len, - (void *)region_elt->paddr); - } - } - - return *region ? 0 : -1; -} - -unsigned long audlpa_pmem_fixup(struct audio *audio, void *addr, - unsigned long len, int ref_up) -{ - struct audlpa_pmem_region *region; - unsigned long paddr; - int ret; - - ret = audlpa_pmem_lookup_vaddr(audio, addr, len, ®ion); - if (ret) { - MM_ERR("lookup (%p, %ld) failed\n", addr, len); - return 0; - } - if (ref_up) - region->ref_cnt++; - else - region->ref_cnt--; - MM_DBG("found region %p ref_cnt %d\n", region, region->ref_cnt); - paddr = region->paddr + (addr - region->vaddr); - return paddr; -} - -/* audio -> lock must be held at this point */ -static int audlpa_aio_buf_add(struct audio *audio, unsigned dir, - void __user *arg) -{ - unsigned long flags; - struct audlpa_buffer_node *buf_node; - - buf_node = kmalloc(sizeof(*buf_node), GFP_KERNEL); - - if (!buf_node) - return -ENOMEM; - - if (copy_from_user(&buf_node->buf, arg, sizeof(buf_node->buf))) { - kfree(buf_node); - return -EFAULT; - } - - MM_DBG("node %p dir %x buf_addr %p buf_len %d data_len" - "%d\n", buf_node, dir, - buf_node->buf.buf_addr, buf_node->buf.buf_len, - buf_node->buf.data_len); - - buf_node->paddr = audlpa_pmem_fixup( - audio, buf_node->buf.buf_addr, - buf_node->buf.buf_len, 1); - - if (dir) { - /* write */ - if (!buf_node->paddr || - (buf_node->paddr & 0x1) || - (buf_node->buf.data_len & 0x1)) { - kfree(buf_node); - return -EINVAL; - } - spin_lock_irqsave(&audio->dsp_lock, flags); - list_add_tail(&buf_node->list, &audio->out_queue); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - audlpa_async_send_data(audio, 0, 0); - } else { - /* read */ - } - - MM_DBG("Add buf_node %p paddr %lx\n", buf_node, buf_node->paddr); - - return 0; -} - -static int audio_enable_eq(struct audio *audio, int enable) -{ - if (audio->eq_enable == enable && !audio->eq_needs_commit) - return 0; - - audio->eq_enable = enable; - - if (audio->running) { - audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq, POPP); - audio->eq_needs_commit = 0; - } - return 0; -} - -static int audio_get_avsync_data(struct audio *audio, - struct msm_audio_stats *stats) -{ - int rc = -EINVAL; - unsigned long flags; - - local_irq_save(flags); - if (audio->dec_id == audio->avsync[0] && audio->avsync_flag) { - /* av_sync sample count */ - stats->sample_count = (audio->avsync[2] << 16) | - (audio->avsync[3]); - - /* av_sync byte_count */ - stats->byte_count = (audio->avsync[5] << 16) | - (audio->avsync[6]); - - audio->avsync_flag = 0; - rc = 0; - } - local_irq_restore(flags); - return rc; - -} - -static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - unsigned long flags = 0; - uint16_t enable_mask; - int enable; - int prev_state; - - MM_DBG("audio_ioctl() cmd = %d\n", cmd); - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - - audio->avsync_flag = 0; - memset(&stats, 0, sizeof(stats)); - if (audpp_query_avsync(audio->dec_id) < 0) - return rc; - - rc = wait_event_interruptible_timeout(audio->avsync_wait, - (audio->avsync_flag == 1), - msecs_to_jiffies(AVSYNC_EVENT_TIMEOUT)); - - if (rc < 0) - return rc; - else if ((rc > 0) || ((rc == 0) && (audio->avsync_flag == 1))) { - if (audio_get_avsync_data(audio, &stats) < 0) - return rc; - - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } else - return -EAGAIN; - } - - switch (cmd) { - case AUDIO_ENABLE_AUDPP: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - spin_lock_irqsave(&audio->dsp_lock, flags); - enable = (enable_mask & EQ_ENABLE) ? 1 : 0; - audio_enable_eq(audio, enable); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_VOLUME: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.volume = arg; - if (audio->running) - audpp_dsp_set_vol_pan(AUDPP_CMD_CFG_DEV_MIXER_ID_4, - &audio->vol_pan, - COPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_PAN: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.pan = arg; - if (audio->running) - audpp_dsp_set_vol_pan(AUDPP_CMD_CFG_DEV_MIXER_ID_4, - &audio->vol_pan, - COPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_EQ: - prev_state = audio->eq_enable; - audio->eq_enable = 0; - if (copy_from_user(&audio->eq.num_bands, (void *) arg, - sizeof(audio->eq) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) { - rc = -EFAULT; - break; - } - audio->eq_enable = prev_state; - audio->eq_needs_commit = 1; - rc = 0; - break; - } - - if (-EINVAL != rc) - return rc; - - if (cmd == AUDIO_GET_EVENT) { - MM_DBG(" AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audlpa_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audio_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_DBG("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) - rc = -ENODEV; - else - rc = 0; - } - break; - - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audio_disable(audio); - audio->stopped = 1; - audio_ioport_reset(audio); - audio->stopped = 0; - audio->drv_status &= ~ADRV_STATUS_PAUSE; - break; - - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH\n"); - audio->wflush = 1; - audio_ioport_reset(audio); - if (audio->running) { - if (!(audio->drv_status & ADRV_STATUS_PAUSE)) { - rc = audpp_pause(audio->dec_id, (int) arg); - if (rc < 0) { - MM_ERR("%s: pause cmd failed rc=%d\n", - __func__, rc); - rc = -EINTR; - break; - } - } - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->wflush = 0; - } - break; - - case AUDIO_SET_CONFIG:{ - struct msm_audio_config config; - MM_INFO("AUDIO_SET_CONFIG\n"); - if (copy_from_user(&config, (void *) arg, sizeof(config))) { - rc = -EFAULT; - MM_INFO("ERROR: copy from user\n"); - break; - } - if (config.channel_count == 1) { - config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V; - } else if (config.channel_count == 2) { - config.channel_count = AUDPP_CMD_PCM_INTF_STEREO_V; - } else { - rc = -EINVAL; - MM_INFO("ERROR: config.channel_count == %d\n", - config.channel_count); - break; - } - - if (config.bits == 8) - config.bits = AUDPP_CMD_WAV_PCM_WIDTH_8; - else if (config.bits == 16) - config.bits = AUDPP_CMD_WAV_PCM_WIDTH_16; - else if (config.bits == 24) - config.bits = AUDPP_CMD_WAV_PCM_WIDTH_24; - else { - rc = -EINVAL; - MM_INFO("ERROR: config.bits == %d\n", config.bits); - break; - } - audio->out_sample_rate = config.sample_rate; - audio->out_channel_mode = config.channel_count; - audio->out_bits = config.bits; - audio->buffer_count = config.buffer_count; - audio->buffer_size = config.buffer_size; - MM_DBG("AUDIO_SET_CONFIG: config.bits = %d\n", config.bits); - rc = 0; - break; - } - - case AUDIO_GET_CONFIG:{ - struct msm_audio_config config; - config.buffer_count = audio->buffer_count; - config.buffer_size = audio->buffer_size; - config.sample_rate = audio->out_sample_rate; - if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) - config.channel_count = 1; - else - config.channel_count = 2; - if (audio->out_bits == AUDPP_CMD_WAV_PCM_WIDTH_8) - config.bits = 8; - else if (audio->out_bits == AUDPP_CMD_WAV_PCM_WIDTH_24) - config.bits = 24; - else - config.bits = 16; - config.meta_field = 0; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - MM_DBG("AUDIO_GET_CONFIG: config.bits = %d\n", config.bits); - if (copy_to_user((void *) arg, &config, sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - - case AUDIO_PAUSE: - MM_DBG("AUDIO_PAUSE %ld\n", arg); - rc = audpp_pause(audio->dec_id, (int) arg); - if (arg == 1) - audio->drv_status |= ADRV_STATUS_PAUSE; - else if (arg == 0) - audio->drv_status &= ~ADRV_STATUS_PAUSE; - break; - - case AUDIO_REGISTER_PMEM: { - struct msm_audio_pmem_info info; - MM_DBG("AUDIO_REGISTER_PMEM\n"); - if (copy_from_user(&info, (void *) arg, sizeof(info))) - rc = -EFAULT; - else - rc = audlpa_pmem_add(audio, &info); - break; - } - - case AUDIO_DEREGISTER_PMEM: { - struct msm_audio_pmem_info info; - MM_DBG("AUDIO_DEREGISTER_PMEM\n"); - if (copy_from_user(&info, (void *) arg, sizeof(info))) - rc = -EFAULT; - else - rc = audlpa_pmem_remove(audio, &info); - break; - } - case AUDIO_ASYNC_WRITE: - if (audio->drv_status & ADRV_STATUS_FSYNC) - rc = -EBUSY; - else - rc = audlpa_aio_buf_add(audio, 1, (void __user *) arg); - break; - - case AUDIO_GET_SESSION_ID: - if (copy_to_user((void *) arg, &audio->dec_id, - sizeof(unsigned short))) - rc = -EFAULT; - else - rc = 0; - break; - default: - rc = audio->codec_ops.ioctl(file, cmd, arg); - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -int audlpa_async_fsync(struct audio *audio) -{ - int rc = 0, empty = 0; - struct audlpa_buffer_node *buf_node; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - /* Blocking client sends more data */ - mutex_lock(&audio->lock); - audio->drv_status |= ADRV_STATUS_FSYNC; - mutex_unlock(&audio->lock); - - mutex_lock(&audio->write_lock); - audio->teos = 0; - empty = list_empty(&audio->out_queue); - buf_node = kmalloc(sizeof(*buf_node), GFP_KERNEL); - if (!buf_node) - goto done; - - buf_node->paddr = 0xFFFFFFFF; - buf_node->buf.data_len = 0; - buf_node->buf.buf_addr = NULL; - buf_node->buf.buf_len = 0; - buf_node->buf.private_data = NULL; - list_add_tail(&buf_node->list, &audio->out_queue); - if ((empty != 0) && (audio->out_needed == 1)) - audlpa_async_send_data(audio, 0, 0); - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush || - audio->stopped); - - if (rc < 0) - goto done; - - if (audio->teos == 1) { - /* Releasing all the pending buffers to user */ - audio->teos = 0; - audlpa_async_flush(audio); - } - - if (audio->stopped || audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); - mutex_lock(&audio->lock); - audio->drv_status &= ~ADRV_STATUS_FSYNC; - mutex_unlock(&audio->lock); - - return rc; -} - -int audlpa_fsync(struct file *file, loff_t ppos1, loff_t ppos2, int datasync) -{ - struct audio *audio = file->private_data; - - if (!audio->running) - return -EINVAL; - - return audlpa_async_fsync(audio); -} - -static void audlpa_reset_pmem_region(struct audio *audio) -{ - struct audlpa_pmem_region *region; - struct list_head *ptr, *next; - - list_for_each_safe(ptr, next, &audio->pmem_region_queue) { - region = list_entry(ptr, struct audlpa_pmem_region, list); - list_del(®ion->list); - put_pmem_file(region->file); - kfree(region); - } - - return; -} - -static int audio_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - MM_INFO("audio instance 0x%08x freeing\n", (int)audio); - mutex_lock(&audio->lock); - auddev_unregister_evt_listner(AUDDEV_CLNT_DEC, audio->dec_id); - audio_disable(audio); - audlpa_async_flush(audio); - audlpa_reset_pmem_region(audio); - - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->opened = 0; - audio->event_abort = 1; - wake_up(&audio->event_wait); - audlpa_reset_event_queue(audio); - iounmap(audio->data); - free_contiguous_memory_by_paddr(audio->phys); - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - kfree(audio); - return 0; -} - -static void audlpa_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audlpa_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audlpa_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audlpa_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audlpa_suspend(struct early_suspend *h) -{ - struct audlpa_suspend_ctl *ctl = - container_of(h, struct audlpa_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audlpa_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audlpa_resume(struct early_suspend *h) -{ - struct audlpa_suspend_ctl *ctl = - container_of(h, struct audlpa_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audlpa_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audlpa_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audlpa_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 4096; - static char buffer[4096]; - int n = 0; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %x\n", audio->vol_pan.volume); - n += scnprintf(buffer + n, debug_bufmax - n, - "sample rate %d\n", - audio->out_sample_rate); - n += scnprintf(buffer + n, debug_bufmax - n, - "channel mode %d\n", - audio->out_channel_mode); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d\n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d\n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d\n", audio->out_needed); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audlpa_debug_fops = { - .read = audlpa_debug_read, - .open = audlpa_debug_open, -}; -#endif - -static int audio_open(struct inode *inode, struct file *file) -{ - struct audio *audio = NULL; - int rc, i, dec_attrb = 0, decid; - struct audlpa_event *e_node = NULL; -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_lpa_" + 5]; -#endif - - /* Allocate audio instance, set to zero */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("no memory to allocate audio instance\n"); - rc = -ENOMEM; - goto done; - } - MM_INFO("audio instance 0x%08x created\n", (int)audio); - - if ((file->f_mode & FMODE_WRITE) && !(file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_TUNNEL; - } else { - kfree(audio); - rc = -EACCES; - goto done; - } - - /* Allocate the decoder based on inode minor number*/ - audio->minor_no = iminor(inode); - dec_attrb |= audlpa_decs[audio->minor_no].dec_attrb; - audio->codec_ops.ioctl = audlpa_decs[audio->minor_no].ioctl; - audio->codec_ops.adec_params = audlpa_decs[audio->minor_no].adec_params; - audio->buffer_size = BUFSZ; - audio->buffer_count = MAX_BUF; - - dec_attrb |= MSM_AUD_MODE_LP; - - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - if (decid < 0) { - MM_ERR("No free decoder available\n"); - rc = -ENODEV; - MM_INFO("audio instance 0x%08x freeing\n", (int)audio); - kfree(audio); - goto done; - } - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - MM_DBG("set to aio interface\n"); - audio->drv_status |= ADRV_STATUS_AIO_INTF; - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audplay_adsp_ops_lpa, audio); - - if (rc) { - MM_ERR("failed to get %s module\n", audio->module_name); - goto err; - } - - /* Initialize all locks of audio instance */ - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - init_waitqueue_head(&audio->write_wait); - INIT_LIST_HEAD(&audio->out_queue); - INIT_LIST_HEAD(&audio->pmem_region_queue); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - spin_lock_init(&audio->event_queue_lock); - init_waitqueue_head(&audio->avsync_wait); - - audio->out_sample_rate = 44100; - audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V; - audio->out_bits = AUDPP_CMD_WAV_PCM_WIDTH_16; - audio->vol_pan.volume = 0x2000; - - audlpa_async_flush(audio); - - file->private_data = audio; - audio->opened = 1; - - audio->device_events = AUDDEV_EVT_DEV_RDY - |AUDDEV_EVT_DEV_RLS | AUDDEV_EVT_REL_PENDING - |AUDDEV_EVT_STREAM_VOL_CHG; - audio->device_switch = DEVICE_SWITCH_STATE_NONE; - audio->drv_status &= ~ADRV_STATUS_PAUSE; - audio->bytecount_consumed = 0; - audio->bytecount_head = 0; - audio->bytecount_given = 0; - - rc = auddev_register_evt_listner(audio->device_events, - AUDDEV_CLNT_DEC, - audio->dec_id, - lpa_listner, - (void *)audio); - if (rc) { - MM_ERR("%s: failed to register listnet\n", __func__); - goto event_err; - } - -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_lpa_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, &audlpa_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audlpa_resume; - audio->suspend_ctl.node.suspend = audlpa_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (i = 0; i < AUDLPA_EVENT_NUM; i++) { - e_node = kmalloc(sizeof(struct audlpa_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } -done: - return rc; -event_err: - msm_adsp_put(audio->audplay); -err: - iounmap(audio->data); - free_contiguous_memory_by_paddr(audio->phys); - audpp_adec_free(audio->dec_id); - MM_INFO("audio instance 0x%08x freeing\n", (int)audio); - kfree(audio); - return rc; -} - -static const struct file_operations audio_lpa_fops = { - .owner = THIS_MODULE, - .open = audio_open, - .release = audio_release, - .unlocked_ioctl = audio_ioctl, - .fsync = audlpa_fsync, -}; - -static dev_t audlpa_devno; -static struct class *audlpa_class; -struct audlpa_device { - const char *name; - struct device *device; - struct cdev cdev; -}; - -static struct audlpa_device *audlpa_devices; - -static void audlpa_create(struct audlpa_device *adev, const char *name, - struct device *parent, dev_t devt) -{ - struct device *dev; - int rc; - - dev = device_create(audlpa_class, parent, devt, "%s", name); - if (IS_ERR(dev)) - return; - - cdev_init(&adev->cdev, &audio_lpa_fops); - adev->cdev.owner = THIS_MODULE; - - rc = cdev_add(&adev->cdev, devt, 1); - if (rc < 0) { - device_destroy(audlpa_class, devt); - } else { - adev->device = dev; - adev->name = name; - } -} - -static int __init audio_init(void) -{ - int rc; - int n = ARRAY_SIZE(audlpa_decs); - - audlpa_devices = kzalloc(sizeof(struct audlpa_device) * n, GFP_KERNEL); - if (!audlpa_devices) - return -ENOMEM; - - audlpa_class = class_create(THIS_MODULE, "audlpa"); - if (IS_ERR(audlpa_class)) - goto fail_create_class; - - rc = alloc_chrdev_region(&audlpa_devno, 0, n, "msm_audio_lpa"); - if (rc < 0) - goto fail_alloc_region; - - for (n = 0; n < ARRAY_SIZE(audlpa_decs); n++) { - audlpa_create(audlpa_devices + n, - audlpa_decs[n].name, NULL, - MKDEV(MAJOR(audlpa_devno), n)); - } - - return 0; - -fail_alloc_region: - class_unregister(audlpa_class); - return rc; -fail_create_class: - kfree(audlpa_devices); - return -ENOMEM; -} - -static void __exit audio_exit(void) -{ - class_unregister(audlpa_class); - kfree(audlpa_devices); -} - -module_init(audio_init); -module_exit(audio_exit); - -MODULE_DESCRIPTION("MSM LPA driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_mp3.c b/arch/arm/mach-msm/qdsp5v2/audio_mp3.c deleted file mode 100644 index 0390edfb0a5d09cf98c0c0f59d6b0844e1c9879f..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_mp3.c +++ /dev/null @@ -1,2521 +0,0 @@ -/* mp3 audio output device - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ADRV_STATUS_AIO_INTF 0x00000001 -#define ADRV_STATUS_OBUF_GIVEN 0x00000002 -#define ADRV_STATUS_IBUF_GIVEN 0x00000004 -#define ADRV_STATUS_FSYNC 0x00000008 - -/* Size must be power of 2 */ -#define BUFSZ_MAX 32768 -#define BUFSZ_MIN 4096 -#define DMASZ_MAX (BUFSZ_MAX * 2) -#define DMASZ_MIN (BUFSZ_MIN * 2) - -#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF -#define AUDDEC_DEC_MP3 2 - -#define PCM_BUFSZ_MIN 4800 /* Hold one stereo MP3 frame */ -#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most - but support 2 buffers currently */ -#define ROUTING_MODE_FTRT 1 -#define ROUTING_MODE_RT 2 -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDMP3_METAFIELD_MASK 0xFFFF0000 -#define AUDMP3_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */ -#define AUDMP3_EOS_FLG_MASK 0x01 -#define AUDMP3_EOS_NONE 0x0 /* No EOS detected */ -#define AUDMP3_EOS_SET 0x1 /* EOS set in meta field */ - -#define AUDMP3_EVENT_NUM 10 /* Default number of pre-allocated event packets */ - -#define BITSTREAM_ERROR_THRESHOLD_VALUE 0x1 /* DEFAULT THRESHOLD VALUE */ - -#define __CONTAINS(r, v, l) ({ \ - typeof(r) __r = r; \ - typeof(v) __v = v; \ - typeof(v) __e = __v + l; \ - int res = ((__v >= __r->vaddr) && \ - (__e <= __r->vaddr + __r->len)); \ - res; \ -}) - -#define CONTAINS(r1, r2) ({ \ - typeof(r2) __r2 = r2; \ - __CONTAINS(r1, __r2->vaddr, __r2->len); \ -}) - -#define IN_RANGE(r, v) ({ \ - typeof(r) __r = r; \ - typeof(v) __vv = v; \ - int res = ((__vv >= __r->vaddr) && \ - (__vv < (__r->vaddr + __r->len))); \ - res; \ -}) - -#define OVERLAPS(r1, r2) ({ \ - typeof(r1) __r1 = r1; \ - typeof(r2) __r2 = r2; \ - typeof(__r2->vaddr) __v = __r2->vaddr; \ - typeof(__v) __e = __v + __r2->len - 1; \ - int res = (IN_RANGE(__r1, __v) || IN_RANGE(__r1, __e)); \ - res; \ -}) -struct audio; - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; - unsigned short mfield_sz; /*only useful for data has meta field */ -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audmp3_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct audmp3_event { - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audmp3_pmem_region { - struct list_head list; - struct file *file; - int fd; - void *vaddr; - unsigned long paddr; - unsigned long kvaddr; - unsigned long len; - unsigned ref_cnt; -}; - -struct audmp3_buffer_node { - struct list_head list; - struct msm_audio_aio_buf buf; - unsigned long paddr; -}; - -struct audmp3_drv_operations { - void (*pcm_buf_update)(struct audio *, uint32_t *); - void (*buffer_refresh)(struct audio *); - void (*send_data)(struct audio *, unsigned); - void (*out_flush)(struct audio *); - void (*in_flush)(struct audio *); - int (*fsync)(struct audio *); -}; - -struct audio { - struct buffer out[2]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - unsigned out_dma_sz; - struct list_head out_queue; /* queue to retain output buffers */ - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - /* Host PCM section */ - struct buffer in[PCM_BUF_MAX_COUNT]; - struct mutex read_lock; - wait_queue_head_t read_wait; /* Wait queue for read */ - char *read_data; /* pointer to reader buffer */ - int32_t read_phys; /* physical address of reader buffer */ - uint8_t read_next; /* index to input buffers to be read next */ - uint8_t fill_next; /* index to buffer that DSP should be filling */ - uint8_t pcm_buf_count; /* number of pcm buffer allocated */ - struct list_head in_queue; /* queue to retain input buffers */ - /* ---- End of Host PCM section */ - - struct msm_adsp_module *audplay; - - /* configuration to use on next enable */ - uint32_t out_sample_rate; - uint32_t out_channel_mode; - - /* data allocated for various buffers */ - char *data; - int32_t phys; /* physical address of write buffer */ - void *map_v_read; - void *map_v_write; - - uint32_t drv_status; - int mfield; /* meta field embedded in data */ - int rflush; /* Read flush */ - int wflush; /* Write flush */ - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - int pcm_feedback; - int buf_refresh; - int teos; /* valid only if tunnel mode & no data left for decoder */ - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - int reserved; /* A byte is being reserved */ - char rsv_byte; /* Handle odd length user data */ - - const char *module_name; - unsigned queue_id; - uint16_t dec_id; - uint32_t read_ptr_offset; - int16_t source; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audmp3_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - /* AV sync Info */ - int avsync_flag; /* Flag to indicate feedback from DSP */ - wait_queue_head_t avsync_wait;/* Wait queue for AV Sync Message */ - /* flags, 48 bits sample/bytes counter per channel */ - uint16_t avsync[AUDPP_AVSYNC_CH_COUNT * AUDPP_AVSYNC_NUM_WORDS + 1]; - - uint32_t device_events; - - struct list_head pmem_region_queue; /* protected by lock */ - struct audmp3_drv_operations drv_ops; - - struct msm_audio_bitstream_info stream_info; - struct msm_audio_bitstream_error_info bitstream_error_info; - uint32_t bitstream_error_threshold_value; - - int eq_enable; - int eq_needs_commit; - struct audpp_cmd_cfg_object_params_eqalizer eq; - struct audpp_cmd_cfg_object_params_volume vol_pan; -}; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audpp_cmd_cfg_adec_params(struct audio *audio); -static void audpp_cmd_cfg_routing_mode(struct audio *audio); -static void audplay_send_data(struct audio *audio, unsigned needed); -static void audplay_error_threshold_config(struct audio *audio); -static void audplay_config_hostpcm(struct audio *audio); -static void audplay_buffer_refresh(struct audio *audio); -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg); -static void audmp3_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); -static unsigned long audmp3_pmem_fixup(struct audio *audio, void *addr, - unsigned long len, int ref_up); - -static void mp3_listner(u32 evt_id, union auddev_evt_data *evt_payload, - void *private_data) -{ - struct audio *audio = (struct audio *) private_data; - switch (evt_id) { - case AUDDEV_EVT_DEV_RDY: - MM_DBG(":AUDDEV_EVT_DEV_RDY\n"); - audio->source |= (0x1 << evt_payload->routing_id); - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - - break; - case AUDDEV_EVT_DEV_RLS: - MM_DBG(":AUDDEV_EVT_DEV_RLS\n"); - audio->source &= ~(0x1 << evt_payload->routing_id); - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - break; - case AUDDEV_EVT_STREAM_VOL_CHG: - audio->vol_pan.volume = evt_payload->session_vol; - MM_DBG(":AUDDEV_EVT_STREAM_VOL_CHG, stream vol %d\n", - audio->vol_pan.volume); - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - break; - default: - MM_ERR(":ERROR:wrong event\n"); - break; - } -} -/* must be called with audio->lock held */ -static int audio_enable(struct audio *audio) -{ - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (audio->enabled) - return 0; - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_tail = 0; - audio->out_needed = 0; - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - return -ENODEV; - } - - audio->enabled = 1; - return 0; -} - -/* must be called with audio->lock held */ -static int audio_disable(struct audio *audio) -{ - int rc = 0; - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - wake_up(&audio->write_wait); - wake_up(&audio->read_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - audio->out_needed = 0; - } - return rc; -} - -/* ------------------- dsp --------------------- */ -static void audmp3_async_pcm_buf_update(struct audio *audio, uint32_t *payload) -{ - unsigned long flags; - union msm_audio_event_payload event_payload; - struct audmp3_buffer_node *filled_buf; - uint8_t index; - - if (audio->rflush) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < payload[1]; index++) { - BUG_ON(list_empty(&audio->in_queue)); - filled_buf = list_first_entry(&audio->in_queue, - struct audmp3_buffer_node, list); - if (filled_buf->paddr == payload[2 + index * 2]) { - list_del(&filled_buf->list); - event_payload.aio_buf = filled_buf->buf; - event_payload.aio_buf.data_len = - payload[3 + index * 2]; - MM_DBG("pcm buf %p data_len %d\n", filled_buf, - event_payload.aio_buf.data_len); - audmp3_post_event(audio, AUDIO_EVENT_READ_DONE, - event_payload); - kfree(filled_buf); - } else { - MM_ERR("expected=%lx ret=%x\n", filled_buf->paddr, - payload[2 + index * 2]); - break; - } - } - - audio->drv_status &= ~ADRV_STATUS_IBUF_GIVEN; - audio->drv_ops.buffer_refresh(audio); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - -} - -static void audio_update_pcm_buf_entry(struct audio *audio, uint32_t *payload) -{ - uint8_t index; - unsigned long flags; - - if (audio->rflush) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < payload[1]; index++) { - if (audio->in[audio->fill_next].addr == - payload[2 + index * 2]) { - MM_DBG("in[%d] ready\n", audio->fill_next); - audio->in[audio->fill_next].used = - payload[3 + index * 2]; - if ((++audio->fill_next) == audio->pcm_buf_count) - audio->fill_next = 0; - - } else { - MM_ERR("expected=%x ret=%x\n", - audio->in[audio->fill_next].addr, - payload[2 + index * 2]); - break; - } - } - if (audio->in[audio->fill_next].used == 0) { - audio->drv_ops.buffer_refresh(audio); - } else { - MM_DBG("read cannot keep up\n"); - audio->buf_refresh = 1; - } - wake_up(&audio->read_wait); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - -} - -static void audmp3_bitstream_error_info(struct audio *audio, uint32_t *payload) -{ - unsigned long flags; - union msm_audio_event_payload e_payload; - - if (payload[0] != AUDDEC_DEC_MP3) { - MM_ERR("Unexpected bitstream error info from DSP:\ - Invalid decoder\n"); - return; - } - - /* get stream info from DSP msg */ - spin_lock_irqsave(&audio->dsp_lock, flags); - - audio->bitstream_error_info.dec_id = payload[0]; - audio->bitstream_error_info.err_msg_indicator = payload[1]; - audio->bitstream_error_info.err_type = payload[2]; - - spin_unlock_irqrestore(&audio->dsp_lock, flags); - MM_ERR("bit_stream_error_type=%d error_count=%d\n", - audio->bitstream_error_info.err_type, (0x0000FFFF & - audio->bitstream_error_info.err_msg_indicator)); - - /* send event to ARM to notify error info coming */ - e_payload.error_info = audio->bitstream_error_info; - audmp3_post_event(audio, AUDIO_EVENT_BITSTREAM_ERROR_INFO, e_payload); -} - -static void audmp3_update_stream_info(struct audio *audio, uint32_t *payload) -{ - unsigned long flags; - union msm_audio_event_payload e_payload; - - /* get stream info from DSP msg */ - spin_lock_irqsave(&audio->dsp_lock, flags); - - audio->stream_info.codec_type = AUDIO_CODEC_TYPE_MP3; - audio->stream_info.chan_info = (0x0000FFFF & payload[1]); - audio->stream_info.sample_rate = (0x0000FFFF & payload[2]); - audio->stream_info.bit_stream_info = (0x0000FFFF & payload[3]); - audio->stream_info.bit_rate = payload[4]; - - spin_unlock_irqrestore(&audio->dsp_lock, flags); - MM_DBG("chan_info=%d, sample_rate=%d, bit_stream_info=%d\n", - audio->stream_info.chan_info, - audio->stream_info.sample_rate, - audio->stream_info.bit_stream_info); - - /* send event to ARM to notify steam info coming */ - e_payload.stream_info = audio->stream_info; - audmp3_post_event(audio, AUDIO_EVENT_STREAM_INFO, e_payload); -} - -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - getevent(msg, sizeof(msg)); - - MM_DBG("msg_id=%x\n", id); - - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audio->drv_ops.send_data(audio, 1); - break; - - case AUDPLAY_MSG_BUFFER_UPDATE: - audio->drv_ops.pcm_buf_update(audio, msg); - break; - - case AUDPLAY_UP_STREAM_INFO: - if ((msg[1] & AUDPLAY_STREAM_INFO_MSG_MASK) == - AUDPLAY_STREAM_INFO_MSG_MASK) { - audmp3_bitstream_error_info(audio, msg); - } else { - audmp3_update_stream_info(audio, msg); - } - break; - - case AUDPLAY_UP_OUTPORT_FLUSH_ACK: - MM_DBG("OUTPORT_FLUSH_ACK\n"); - audio->rflush = 0; - wake_up(&audio->read_wait); - if (audio->pcm_feedback) - audio->drv_ops.buffer_refresh(audio); - break; - - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audplaytask)\n"); - break; - - default: - MM_ERR("unexpected message from decoder \n"); - break; - } -} - -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status: sleep reason=0x%04x\n", - reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init \n"); - if (audio->pcm_feedback) - audpp_cmd_cfg_routing_mode(audio); - else - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg \n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play \n"); - /* send mixer command */ - audpp_route_stream(audio->dec_id, - audio->source); - if (audio->pcm_feedback) { - audplay_error_threshold_config(audio); - audplay_config_hostpcm(audio); - audio->drv_ops.buffer_refresh(audio); - } - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - default: - MM_ERR("unknown decoder status \n"); - break; - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - audpp_dsp_set_eq(audio->dec_id, audio->eq_enable, - &audio->eq, POPP); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audio->running = 0; - } else { - MM_DBG("CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_ROUTING_ACK: - MM_DBG("ROUTING_ACK mode=%d\n", msg[1]); - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - audio->rflush = 0; - wake_up(&audio->write_wait); - if (audio->pcm_feedback) - audio->drv_ops.buffer_refresh(audio); - break; - - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - - case AUDPP_MSG_AVSYNC_MSG: - MM_DBG("AUDPP_MSG_AVSYNC_MSG\n"); - memcpy(&audio->avsync[0], msg, sizeof(audio->avsync)); - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); - break; - - default: - MM_ERR("UNKNOWN (%d)\n", id); - } - -} - - -struct msm_adsp_ops audplay_adsp_ops = { - .event = audplay_dsp_event, -}; - - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id, \ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - struct audpp_cmd_cfg_dec_type cfg_dec_cmd; - - memset(&cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - - cfg_dec_cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE; - if (enable) - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_MP3; - else - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - cfg_dec_cmd.dm_mode = 0x0; - cfg_dec_cmd.stream_id = audio->dec_id; - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} - -static void audpp_cmd_cfg_adec_params(struct audio *audio) -{ - struct audpp_cmd_cfg_adec_params_mp3 cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_MP3_LEN; - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = audio->out_sample_rate; - - audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static void audpp_cmd_cfg_routing_mode(struct audio *audio) -{ - struct audpp_cmd_routing_mode cmd; - MM_DBG("\n"); /* Macro prints the file name and function */ - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; - cmd.object_number = audio->dec_id; - if (audio->pcm_feedback) - cmd.routing_mode = ROUTING_MODE_FTRT; - else - cmd.routing_mode = ROUTING_MODE_RT; - - audpp_send_queue1(&cmd, sizeof(cmd)); -} - -static int audplay_dsp_send_data_avail(struct audio *audio, - unsigned idx, unsigned len) -{ - struct audplay_cmd_bitstream_data_avail_nt2 cmd; - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2; - if (audio->mfield) - cmd.decoder_id = AUDMP3_METAFIELD_MASK | - (audio->out[idx].mfield_sz >> 1); - else - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = audio->out[idx].addr; - cmd.buf_size = len/2; - cmd.partition_number = 0; - return audplay_send_queue0(audio, &cmd, sizeof(cmd)); -} -/* Caller holds irq_lock */ -static void audmp3_async_buffer_refresh(struct audio *audio) -{ - struct audplay_cmd_buffer_refresh refresh_cmd; - struct audmp3_buffer_node *next_buf; - - if (!audio->running || - audio->drv_status & ADRV_STATUS_IBUF_GIVEN) - return; - - if (!list_empty(&audio->in_queue)) { - next_buf = list_first_entry(&audio->in_queue, - struct audmp3_buffer_node, list); - if (!next_buf) - return; - MM_DBG("next buf %p phy %lx len %d\n", next_buf, - next_buf->paddr, next_buf->buf.buf_len); - refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; - refresh_cmd.num_buffers = 1; - refresh_cmd.buf0_address = next_buf->paddr; - refresh_cmd.buf0_length = next_buf->buf.buf_len - - (next_buf->buf.buf_len % 576) + - (audio->mfield ? 24 : 0); /* Mp3 frame size */ - refresh_cmd.buf_read_count = 0; - audio->drv_status |= ADRV_STATUS_IBUF_GIVEN; - (void) audplay_send_queue0(audio, &refresh_cmd, - sizeof(refresh_cmd)); - } - -} - -static void audplay_buffer_refresh(struct audio *audio) -{ - struct audplay_cmd_buffer_refresh refresh_cmd; - - refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; - refresh_cmd.num_buffers = 1; - refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; - refresh_cmd.buf0_length = audio->in[audio->fill_next].size - - (audio->in[audio->fill_next].size % 576) + - (audio->mfield ? 24 : 0); /* Mp3 frame size */ - refresh_cmd.buf_read_count = 0; - MM_DBG("buf0_addr=%x buf0_len=%d\n", refresh_cmd.buf0_address, - refresh_cmd.buf0_length); - (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); -} - -static void audplay_error_threshold_config(struct audio *audio) -{ - union audplay_cmd_channel_info ch_cfg_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - ch_cfg_cmd.thr_update.cmd_id = AUDPLAY_CMD_CHANNEL_INFO; - ch_cfg_cmd.thr_update.threshold_update = AUDPLAY_ERROR_THRESHOLD_ENABLE; - ch_cfg_cmd.thr_update.threshold_value = - audio->bitstream_error_threshold_value; - (void)audplay_send_queue0(audio, &ch_cfg_cmd, sizeof(ch_cfg_cmd)); -} - -static void audplay_config_hostpcm(struct audio *audio) -{ - struct audplay_cmd_hpcm_buf_cfg cfg_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; - cfg_cmd.max_buffers = 1; - cfg_cmd.byte_swap = 0; - cfg_cmd.hostpcm_config = (0x8000) | (0x4000); - cfg_cmd.feedback_frequency = 1; - cfg_cmd.partition_number = 0; - (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); - -} - -static void audplay_outport_flush(struct audio *audio) -{ - struct audplay_cmd_outport_flush op_flush_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - op_flush_cmd.cmd_id = AUDPLAY_CMD_OUTPORT_FLUSH; - (void)audplay_send_queue0(audio, &op_flush_cmd, sizeof(op_flush_cmd)); -} - -static void audmp3_async_send_data(struct audio *audio, unsigned needed) -{ - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - audio->out_needed = 1; - if (audio->drv_status & ADRV_STATUS_OBUF_GIVEN) { - /* pop one node out of queue */ - union msm_audio_event_payload payload; - struct audmp3_buffer_node *used_buf; - - MM_DBG("consumed\n"); - BUG_ON(list_empty(&audio->out_queue)); - used_buf = list_first_entry(&audio->out_queue, - struct audmp3_buffer_node, list); - list_del(&used_buf->list); - payload.aio_buf = used_buf->buf; - audmp3_post_event(audio, AUDIO_EVENT_WRITE_DONE, - payload); - kfree(used_buf); - audio->drv_status &= ~ADRV_STATUS_OBUF_GIVEN; - } - - } - - if (audio->out_needed) { - struct audmp3_buffer_node *next_buf; - struct audplay_cmd_bitstream_data_avail_nt2 cmd; - if (!list_empty(&audio->out_queue)) { - next_buf = list_first_entry(&audio->out_queue, - struct audmp3_buffer_node, list); - MM_DBG("next_buf %p\n", next_buf); - if (next_buf) { - MM_DBG("next buf phy %lx len %d\n", - next_buf->paddr, - next_buf->buf.data_len); - - cmd.cmd_id = - AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2; - if (audio->mfield) - cmd.decoder_id = AUDMP3_METAFIELD_MASK | - (next_buf->buf.mfield_sz >> 1); - else - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = (unsigned) next_buf->paddr; - cmd.buf_size = next_buf->buf.data_len >> 1; - cmd.partition_number = 0; - audplay_send_queue0(audio, &cmd, sizeof(cmd)); - audio->out_needed = 0; - audio->drv_status |= ADRV_STATUS_OBUF_GIVEN; - } - } - } - -done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audplay_send_data(struct audio *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - MM_DBG("frame %d busy\n", audio->out_tail); - audplay_dsp_send_data_avail(audio, audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } -done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ -static void audmp3_async_flush(struct audio *audio) -{ - struct audmp3_buffer_node *buf_node; - struct list_head *ptr, *next; - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - list_for_each_safe(ptr, next, &audio->out_queue) { - buf_node = list_entry(ptr, struct audmp3_buffer_node, list); - list_del(&buf_node->list); - payload.aio_buf = buf_node->buf; - audmp3_post_event(audio, AUDIO_EVENT_WRITE_DONE, - payload); - kfree(buf_node); - } - audio->drv_status &= ~ADRV_STATUS_OBUF_GIVEN; - audio->out_needed = 0; - atomic_set(&audio->out_bytes, 0); -} - -static void audio_flush(struct audio *audio) -{ - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->reserved = 0; - audio->out_needed = 0; - atomic_set(&audio->out_bytes, 0); -} - -static void audmp3_async_flush_pcm_buf(struct audio *audio) -{ - struct audmp3_buffer_node *buf_node; - struct list_head *ptr, *next; - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - list_for_each_safe(ptr, next, &audio->in_queue) { - buf_node = list_entry(ptr, struct audmp3_buffer_node, list); - list_del(&buf_node->list); - payload.aio_buf = buf_node->buf; - payload.aio_buf.data_len = 0; - audmp3_post_event(audio, AUDIO_EVENT_READ_DONE, - payload); - kfree(buf_node); - } - audio->drv_status &= ~ADRV_STATUS_IBUF_GIVEN; - -} - -static void audio_flush_pcm_buf(struct audio *audio) -{ - uint8_t index; - - for (index = 0; index < PCM_BUF_MAX_COUNT; index++) - audio->in[index].used = 0; - - audio->buf_refresh = 0; - audio->read_next = 0; - audio->fill_next = 0; -} - -static void audio_ioport_reset(struct audio *audio) -{ - if (audio->drv_status & ADRV_STATUS_AIO_INTF) { - /* If fsync is in progress, make sure - * return value of fsync indicates - * abort due to flush - */ - if (audio->drv_status & ADRV_STATUS_FSYNC) { - MM_DBG("fsync in progress\n"); - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audio->drv_ops.out_flush(audio); - mutex_unlock(&audio->write_lock); - } else - audio->drv_ops.out_flush(audio); - audio->drv_ops.in_flush(audio); - } else { - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audio->drv_ops.out_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->read_wait); - mutex_lock(&audio->read_lock); - audio->drv_ops.in_flush(audio); - mutex_unlock(&audio->read_lock); - } - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); -} - -static int audmp3_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audmp3_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audmp3_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audmp3_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audmp3_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - -static long audmp3_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audmp3_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - audio->event_wait, audmp3_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audmp3_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - rc = 0; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audmp3_event, list); - list_del(&drv_evt->list); - } - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - if (drv_evt->event_type == AUDIO_EVENT_WRITE_DONE || - drv_evt->event_type == AUDIO_EVENT_READ_DONE) { - mutex_lock(&audio->lock); - audmp3_pmem_fixup(audio, drv_evt->payload.aio_buf.buf_addr, - drv_evt->payload.aio_buf.buf_len, 0); - mutex_unlock(&audio->lock); - } - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audmp3_pmem_check(struct audio *audio, - void *vaddr, unsigned long len) -{ - struct audmp3_pmem_region *region_elt; - struct audmp3_pmem_region t = { .vaddr = vaddr, .len = len }; - - list_for_each_entry(region_elt, &audio->pmem_region_queue, list) { - if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) || - OVERLAPS(region_elt, &t)) { - MM_ERR("region (vaddr %p len %ld)" - " clashes with registered region" - " (vaddr %p paddr %p len %ld)\n", - vaddr, len, - region_elt->vaddr, - (void *)region_elt->paddr, - region_elt->len); - return -EINVAL; - } - } - - return 0; -} - -static int audmp3_pmem_add(struct audio *audio, - struct msm_audio_pmem_info *info) -{ - unsigned long paddr, kvaddr, len; - struct file *file; - struct audmp3_pmem_region *region; - int rc = -EINVAL; - - MM_DBG("\n"); /* Macro prints the file name and function */ - region = kmalloc(sizeof(*region), GFP_KERNEL); - - if (!region) { - rc = -ENOMEM; - goto end; - } - - if (get_pmem_file(info->fd, &paddr, &kvaddr, &len, &file)) { - kfree(region); - goto end; - } - - rc = audmp3_pmem_check(audio, info->vaddr, len); - if (rc < 0) { - put_pmem_file(file); - kfree(region); - goto end; - } - - region->vaddr = info->vaddr; - region->fd = info->fd; - region->paddr = paddr; - region->kvaddr = kvaddr; - region->len = len; - region->file = file; - region->ref_cnt = 0; - MM_DBG("add region paddr %lx vaddr %p, len %lu\n", region->paddr, - region->vaddr, region->len); - list_add_tail(®ion->list, &audio->pmem_region_queue); -end: - return rc; -} - -static int audmp3_pmem_remove(struct audio *audio, - struct msm_audio_pmem_info *info) -{ - struct audmp3_pmem_region *region; - struct list_head *ptr, *next; - int rc = -EINVAL; - - MM_DBG("info fd %d vaddr %p\n", info->fd, info->vaddr); - - list_for_each_safe(ptr, next, &audio->pmem_region_queue) { - region = list_entry(ptr, struct audmp3_pmem_region, list); - - if ((region->fd == info->fd) && - (region->vaddr == info->vaddr)) { - if (region->ref_cnt) { - MM_DBG("region %p in use ref_cnt %d\n", - region, region->ref_cnt); - break; - } - MM_DBG("remove region fd %d vaddr %p \n", - info->fd, info->vaddr); - list_del(®ion->list); - put_pmem_file(region->file); - kfree(region); - rc = 0; - break; - } - } - - return rc; -} - -static int audmp3_pmem_lookup_vaddr(struct audio *audio, void *addr, - unsigned long len, struct audmp3_pmem_region **region) -{ - struct audmp3_pmem_region *region_elt; - - int match_count = 0; - - *region = NULL; - - /* returns physical address or zero */ - list_for_each_entry(region_elt, &audio->pmem_region_queue, - list) { - if (addr >= region_elt->vaddr && - addr < region_elt->vaddr + region_elt->len && - addr + len <= region_elt->vaddr + region_elt->len) { - /* offset since we could pass vaddr inside a registerd - * pmem buffer - */ - - match_count++; - if (!*region) - *region = region_elt; - } - } - - if (match_count > 1) { - MM_ERR("multiple hits for vaddr %p, len %ld\n", addr, len); - list_for_each_entry(region_elt, - &audio->pmem_region_queue, list) { - if (addr >= region_elt->vaddr && - addr < region_elt->vaddr + region_elt->len && - addr + len <= region_elt->vaddr + region_elt->len) - MM_ERR("\t%p, %ld --> %p\n", region_elt->vaddr, - region_elt->len, - (void *)region_elt->paddr); - } - } - - return *region ? 0 : -1; -} - -unsigned long audmp3_pmem_fixup(struct audio *audio, void *addr, - unsigned long len, int ref_up) -{ - struct audmp3_pmem_region *region; - unsigned long paddr; - int ret; - - ret = audmp3_pmem_lookup_vaddr(audio, addr, len, ®ion); - if (ret) { - MM_ERR("lookup (%p, %ld) failed\n", addr, len); - return 0; - } - if (ref_up) - region->ref_cnt++; - else - region->ref_cnt--; - MM_DBG("found region %p ref_cnt %d\n", region, region->ref_cnt); - paddr = region->paddr + (addr - region->vaddr); - return paddr; -} - -/* audio -> lock must be held at this point */ -static int audmp3_aio_buf_add(struct audio *audio, unsigned dir, - void __user *arg) -{ - unsigned long flags; - struct audmp3_buffer_node *buf_node; - - buf_node = kmalloc(sizeof(*buf_node), GFP_KERNEL); - - if (!buf_node) - return -ENOMEM; - - if (copy_from_user(&buf_node->buf, arg, sizeof(buf_node->buf))) { - kfree(buf_node); - return -EFAULT; - } - - MM_DBG("node %p dir %x buf_addr %p buf_len %d data_len \ - %d\n", buf_node, dir, - buf_node->buf.buf_addr, buf_node->buf.buf_len, - buf_node->buf.data_len); - - buf_node->paddr = audmp3_pmem_fixup( - audio, buf_node->buf.buf_addr, - buf_node->buf.buf_len, 1); - - if (dir) { - /* write */ - if (!buf_node->paddr || - (buf_node->paddr & 0x1) || - (buf_node->buf.data_len & 0x1) || - (!audio->pcm_feedback && - !buf_node->buf.data_len)) { - kfree(buf_node); - return -EINVAL; - } - spin_lock_irqsave(&audio->dsp_lock, flags); - list_add_tail(&buf_node->list, &audio->out_queue); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - audio->drv_ops.send_data(audio, 0); - } else { - /* read */ - if (!buf_node->paddr || - (buf_node->paddr & 0x1) || - (buf_node->buf.buf_len < PCM_BUFSZ_MIN)) { - kfree(buf_node); - return -EINVAL; - } - spin_lock_irqsave(&audio->dsp_lock, flags); - list_add_tail(&buf_node->list, &audio->in_queue); - audio->drv_ops.buffer_refresh(audio); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - } - - MM_DBG("Add buf_node %p paddr %lx\n", buf_node, buf_node->paddr); - - return 0; -} - -static int audio_enable_eq(struct audio *audio, int enable) -{ - if (audio->eq_enable == enable && !audio->eq_needs_commit) - return 0; - - audio->eq_enable = enable; - - if (audio->running) { - audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq, POPP); - audio->eq_needs_commit = 0; - } - return 0; -} - -static int audio_get_avsync_data(struct audio *audio, - struct msm_audio_stats *stats) -{ - int rc = -EINVAL; - unsigned long flags; - - local_irq_save(flags); - if (audio->dec_id == audio->avsync[0] && audio->avsync_flag) { - /* av_sync sample count */ - stats->sample_count = (audio->avsync[2] << 16) | - (audio->avsync[3]); - - /* av_sync byte_count */ - stats->byte_count = (audio->avsync[5] << 16) | - (audio->avsync[6]); - - audio->avsync_flag = 0; - rc = 0; - } - local_irq_restore(flags); - return rc; - -} - -static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - unsigned long flags = 0; - uint16_t enable_mask; - int enable; - int prev_state; - - MM_DBG("cmd = %d\n", cmd); - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - - audio->avsync_flag = 0; - memset(&stats, 0, sizeof(stats)); - if (audpp_query_avsync(audio->dec_id) < 0) - return rc; - - rc = wait_event_interruptible_timeout(audio->avsync_wait, - (audio->avsync_flag == 1), - msecs_to_jiffies(AUDPP_AVSYNC_EVENT_TIMEOUT)); - - if (rc < 0) - return rc; - else if ((rc > 0) || ((rc == 0) && (audio->avsync_flag == 1))) { - if (audio_get_avsync_data(audio, &stats) < 0) - return rc; - - if (copy_to_user((void *)arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } else - return -EAGAIN; - } - - switch (cmd) { - case AUDIO_ENABLE_AUDPP: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - spin_lock_irqsave(&audio->dsp_lock, flags); - enable = (enable_mask & EQ_ENABLE) ? 1 : 0; - audio_enable_eq(audio, enable); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - case AUDIO_SET_VOLUME: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.volume = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_PAN: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.pan = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_EQ: - prev_state = audio->eq_enable; - audio->eq_enable = 0; - if (copy_from_user(&audio->eq.num_bands, (void *) arg, - sizeof(audio->eq) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) { - rc = -EFAULT; - break; - } - audio->eq_enable = prev_state; - audio->eq_needs_commit = 1; - rc = 0; - break; - } - - if (-EINVAL != rc) - return rc; - - if (cmd == AUDIO_GET_EVENT) { - MM_DBG(" AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audmp3_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audio_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) - rc = -ENODEV; - else - rc = 0; - } - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audio_disable(audio); - audio->stopped = 1; - audio_ioport_reset(audio); - audio->stopped = 0; - break; - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audio_ioport_reset(audio); - if (audio->running) { - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - case AUDIO_OUTPORT_FLUSH: - MM_DBG("AUDIO_OUTPORT_FLUSH\n"); - audio->rflush = 1; - if (audio->drv_status & ADRV_STATUS_AIO_INTF) { - audio->drv_ops.in_flush(audio); - } else { - wake_up(&audio->read_wait); - mutex_lock(&audio->read_lock); - audio->drv_ops.in_flush(audio); - mutex_unlock(&audio->read_lock); - } - audplay_outport_flush(audio); - rc = wait_event_interruptible(audio->read_wait, - !audio->rflush); - if (rc < 0) { - MM_ERR("AUDPLAY_OUTPORT_FLUSH interrupted\n"); - rc = -EINTR; - } - break; - case AUDIO_SET_CONFIG: { - struct msm_audio_config config; - if (copy_from_user(&config, (void *) arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.channel_count == 1) { - config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V; - } else if (config.channel_count == 2) { - config.channel_count = AUDPP_CMD_PCM_INTF_STEREO_V; - } else { - rc = -EINVAL; - break; - } - audio->mfield = config.meta_field; - audio->out_sample_rate = config.sample_rate; - audio->out_channel_mode = config.channel_count; - rc = 0; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config config; - config.buffer_size = (audio->out_dma_sz >> 1); - config.buffer_count = 2; - config.sample_rate = audio->out_sample_rate; - if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) - config.channel_count = 1; - else - config.channel_count = 2; - config.meta_field = 0; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *) arg, &config, sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_GET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - config.pcm_feedback = audio->pcm_feedback; - config.buffer_count = PCM_BUF_MAX_COUNT; - config.buffer_size = PCM_BUFSZ_MIN; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - - if (config.pcm_feedback != audio->pcm_feedback) { - MM_ERR("Not sufficient permission to" - "change the playback mode\n"); - rc = -EACCES; - break; - } - if (audio->drv_status & ADRV_STATUS_AIO_INTF) { - rc = 0; - break; - } - - if ((config.buffer_count > PCM_BUF_MAX_COUNT) || - (config.buffer_count == 1)) - config.buffer_count = PCM_BUF_MAX_COUNT; - - if (config.buffer_size < PCM_BUFSZ_MIN) - config.buffer_size = PCM_BUFSZ_MIN; - - /* Check if pcm feedback is required */ - if ((config.pcm_feedback) && (!audio->read_data)) { - MM_DBG("allocate PCM buffer %d\n", - config.buffer_count * - config.buffer_size); - audio->read_phys = - allocate_contiguous_ebi_nomap( - config.buffer_size * - config.buffer_count, - SZ_4K); - if (!audio->read_phys) { - rc = -ENOMEM; - break; - } - audio->map_v_read = ioremap( - audio->read_phys, - config.buffer_size * - config.buffer_count); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("failed to map read buffer" - " physical address\n"); - rc = -ENOMEM; - free_contiguous_memory_by_paddr( - audio->read_phys); - } else { - uint8_t index; - uint32_t offset = 0; - audio->read_data = - audio->map_v_read; - audio->buf_refresh = 0; - audio->pcm_buf_count = - config.buffer_count; - audio->read_next = 0; - audio->fill_next = 0; - - for (index = 0; - index < config.buffer_count; - index++) { - audio->in[index].data = - audio->read_data + offset; - audio->in[index].addr = - audio->read_phys + offset; - audio->in[index].size = - config.buffer_size; - audio->in[index].used = 0; - offset += config.buffer_size; - } - rc = 0; - MM_DBG("read buf: phy addr \ - 0x%08x kernel addr 0x%08x\n", - audio->read_phys, - (int)audio->read_data); - } - } else { - rc = 0; - } - break; - } - case AUDIO_PAUSE: - MM_DBG("AUDIO_PAUSE %ld\n", arg); - rc = audpp_pause(audio->dec_id, (int) arg); - break; - - case AUDIO_GET_STREAM_INFO:{ - if (audio->stream_info.sample_rate == 0) { - /* haven't received DSP stream event, - the stream info is not updated */ - rc = -EPERM; - break; - } - if (copy_to_user((void *)arg, &audio->stream_info, - sizeof(struct msm_audio_bitstream_info))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_GET_BITSTREAM_ERROR_INFO:{ - if ((audio->bitstream_error_info.err_msg_indicator & - AUDPLAY_STREAM_INFO_MSG_MASK) == - AUDPLAY_STREAM_INFO_MSG_MASK) { - /* haven't received bitstream error info event, - the bitstream error info is not updated */ - rc = -EPERM; - break; - } - if (copy_to_user((void *)arg, &audio->bitstream_error_info, - sizeof(struct msm_audio_bitstream_error_info))) - rc = -EFAULT; - else - rc = 0; - break; - } - - case AUDIO_REGISTER_PMEM: { - struct msm_audio_pmem_info info; - MM_DBG("AUDIO_REGISTER_PMEM\n"); - if (copy_from_user(&info, (void *) arg, sizeof(info))) - rc = -EFAULT; - else - rc = audmp3_pmem_add(audio, &info); - break; - } - - case AUDIO_DEREGISTER_PMEM: { - struct msm_audio_pmem_info info; - MM_DBG("AUDIO_DEREGISTER_PMEM\n"); - if (copy_from_user(&info, (void *) arg, sizeof(info))) - rc = -EFAULT; - else - rc = audmp3_pmem_remove(audio, &info); - break; - } - case AUDIO_ASYNC_WRITE: - if (audio->drv_status & ADRV_STATUS_FSYNC) - rc = -EBUSY; - else - rc = audmp3_aio_buf_add(audio, 1, (void __user *) arg); - break; - - case AUDIO_ASYNC_READ: - if (audio->pcm_feedback) - rc = audmp3_aio_buf_add(audio, 0, (void __user *) arg); - else - rc = -EPERM; - break; - case AUDIO_GET_SESSION_ID: - if (copy_to_user((void *) arg, &audio->dec_id, - sizeof(unsigned short))) - rc = -EFAULT; - else - rc = 0; - break; - case AUDIO_SET_ERR_THRESHOLD_VALUE: - if (copy_from_user(&audio->bitstream_error_threshold_value, - (void *)arg, sizeof(uint32_t))) - rc = -EFAULT; - else - rc = 0; - break; - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -int audmp3_async_fsync(struct audio *audio) -{ - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - /* Blocking client sends more data */ - mutex_lock(&audio->lock); - audio->drv_status |= ADRV_STATUS_FSYNC; - mutex_unlock(&audio->lock); - - mutex_lock(&audio->write_lock); - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - (audio->teos && audio->out_needed && - list_empty(&audio->out_queue)) - || audio->wflush || audio->stopped); - - if (audio->stopped || audio->wflush) - rc = -EBUSY; - - mutex_unlock(&audio->write_lock); - mutex_lock(&audio->lock); - audio->drv_status &= ~ADRV_STATUS_FSYNC; - mutex_unlock(&audio->lock); - - return rc; -} - -int audmp3_sync_fsync(struct audio *audio) -{ - struct buffer *frame; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (audio->reserved) { - MM_DBG("send reserved byte\n"); - frame = audio->out + audio->out_tail; - ((char *) frame->data)[0] = audio->rsv_byte; - ((char *) frame->data)[1] = 0; - frame->used = 2; - audio->drv_ops.send_data(audio, 0); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - } - - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush); - - if (audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); - return rc; -} - -int audmp3_fsync(struct file *file, loff_t ppos1, loff_t ppos2, int datasync) -{ - struct audio *audio = file->private_data; - - if (!audio->running || audio->pcm_feedback) - return -EINVAL; - - return audio->drv_ops.fsync(audio); -} - -static ssize_t audio_read(struct file *file, char __user *buf, size_t count, - loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - int rc = 0; - - if (audio->drv_status & ADRV_STATUS_AIO_INTF) - return -EPERM; - else if (!audio->pcm_feedback) - return 0; /* PCM feedback disabled. Nothing to read */ - - mutex_lock(&audio->read_lock); - MM_DBG("%d \n", count); - while (count > 0) { - rc = wait_event_interruptible_timeout( - audio->read_wait, - (audio->in[audio->read_next]. - used > 0) || (audio->stopped) - || (audio->rflush), - msecs_to_jiffies(MSM_AUD_BUFFER_UPDATE_WAIT_MS)); - - if (rc == 0) { - rc = -ETIMEDOUT; - break; - } else if (rc < 0) - break; - - if (audio->stopped || audio->rflush) { - rc = -EBUSY; - break; - } - - if (count < audio->in[audio->read_next].used) { - /* Read must happen in frame boundary. Since - * driver does not know frame size, read count - * must be greater or equal - * to size of PCM samples - */ - MM_DBG("no partial frame done reading\n"); - break; - } else { - MM_DBG("read from in[%d]\n", audio->read_next); - - if (copy_to_user - (buf, audio->in[audio->read_next].data, - audio->in[audio->read_next].used)) { - MM_ERR("invalid addr %x \n", (unsigned int)buf); - rc = -EFAULT; - break; - } - count -= audio->in[audio->read_next].used; - buf += audio->in[audio->read_next].used; - audio->in[audio->read_next].used = 0; - if ((++audio->read_next) == audio->pcm_buf_count) - audio->read_next = 0; - break; /* Force to exit while loop - * to prevent output thread - * sleep too long if data is - * not ready at this moment. - */ - } - } - - /* don't feed output buffer to HW decoder during flushing - * buffer refresh command will be sent once flush completes - * send buf refresh command here can confuse HW decoder - */ - if (audio->buf_refresh && !audio->rflush) { - audio->buf_refresh = 0; - MM_DBG("kick start pcm feedback again\n"); - audio->drv_ops.buffer_refresh(audio); - } - - mutex_unlock(&audio->read_lock); - - if (buf > start) - rc = buf - start; - - MM_DBG("read %d bytes\n", rc); - return rc; -} - -static int audmp3_process_eos(struct audio *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - int rc = 0; - struct buffer *frame; - char *buf_ptr; - - if (audio->reserved) { - MM_DBG("flush reserve byte\n"); - frame = audio->out + audio->out_head; - buf_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - buf_ptr[0] = audio->rsv_byte; - buf_ptr[1] = 0; - audio->out_head ^= 1; - frame->mfield_sz = 0; - frame->used = 2; - audio->reserved = 0; - audio->drv_ops.send_data(audio, 0); - } - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - audio->drv_ops.send_data(audio, 0); -done: - return rc; -} - -static ssize_t audio_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - char *cpy_ptr; - int rc = 0, eos_condition = AUDMP3_EOS_NONE; - unsigned dsize; - unsigned short mfield_size = 0; - - if (audio->drv_status & ADRV_STATUS_AIO_INTF) - return -EPERM; - - MM_DBG("cnt=%d\n", count); - - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - cpy_ptr = frame->data; - dsize = 0; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - break; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - break; - } - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - break; - } else if (mfield_size > count) { - rc = -EINVAL; - break; - } - MM_DBG("mf offset_val %x\n", mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - break; - } - /* Check if EOS flag is set and buffer has - * contains just meta field - */ - if (cpy_ptr[AUDMP3_EOS_FLG_OFFSET] & - AUDMP3_EOS_FLG_MASK) { - MM_DBG("EOS SET\n"); - eos_condition = AUDMP3_EOS_SET; - if (mfield_size == count) { - buf += mfield_size; - break; - } else - cpy_ptr[AUDMP3_EOS_FLG_OFFSET] - &= ~AUDMP3_EOS_FLG_MASK; - } - cpy_ptr += mfield_size; - count -= mfield_size; - dsize += mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - - if (audio->reserved) { - MM_DBG("append reserved byte %x\n", audio->rsv_byte); - *cpy_ptr = audio->rsv_byte; - xfer = (count > ((frame->size - mfield_size) - 1)) ? - (frame->size - mfield_size) - 1 : count; - cpy_ptr++; - dsize += 1; - audio->reserved = 0; - } else - xfer = (count > (frame->size - mfield_size)) ? - (frame->size - mfield_size) : count; - - if (copy_from_user(cpy_ptr, buf, xfer)) { - rc = -EFAULT; - break; - } - - dsize += xfer; - if (dsize & 1) { - audio->rsv_byte = ((char *) frame->data)[dsize - 1]; - MM_DBG("odd length buf reserve last byte %x\n", - audio->rsv_byte); - audio->reserved = 1; - dsize--; - } - count -= xfer; - buf += xfer; - - if (dsize > 0) { - audio->out_head ^= 1; - frame->used = dsize; - audio->drv_ops.send_data(audio, 0); - } - } - if (eos_condition == AUDMP3_EOS_SET) - rc = audmp3_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - if (!rc) { - if (buf > start) - return buf - start; - } - return rc; -} - -static void audmp3_reset_pmem_region(struct audio *audio) -{ - struct audmp3_pmem_region *region; - struct list_head *ptr, *next; - - list_for_each_safe(ptr, next, &audio->pmem_region_queue) { - region = list_entry(ptr, struct audmp3_pmem_region, list); - list_del(®ion->list); - put_pmem_file(region->file); - kfree(region); - } - - return; -} - -static int audio_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_INFO("audio instance 0x%08x freeing\n", (int)audio); - mutex_lock(&audio->lock); - auddev_unregister_evt_listner(AUDDEV_CLNT_DEC, audio->dec_id); - audio_disable(audio); - audio->drv_ops.out_flush(audio); - audio->drv_ops.in_flush(audio); - audmp3_reset_pmem_region(audio); - - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->opened = 0; - audio->event_abort = 1; - wake_up(&audio->event_wait); - audmp3_reset_event_queue(audio); - if (audio->data) { - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - } - if (audio->read_data) { - iounmap(audio->map_v_read); - free_contiguous_memory_by_paddr(audio->read_phys); - } - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - kfree(audio); - return 0; -} - -static void audmp3_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audmp3_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audmp3_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audmp3_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audmp3_suspend(struct early_suspend *h) -{ - struct audmp3_suspend_ctl *ctl = - container_of(h, struct audmp3_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audmp3_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audmp3_resume(struct early_suspend *h) -{ - struct audmp3_suspend_ctl *ctl = - container_of(h, struct audmp3_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audmp3_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audmp3_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audmp3_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 4096; - static char buffer[4096]; - int n = 0, i; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_feedback %d\n", audio->pcm_feedback); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_buf_sz %d\n", audio->out[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_count %d \n", audio->pcm_buf_count); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_sz %d \n", audio->in[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %x \n", audio->vol_pan.volume); - n += scnprintf(buffer + n, debug_bufmax - n, - "sample rate %d \n", audio->out_sample_rate); - n += scnprintf(buffer + n, debug_bufmax - n, - "channel mode %d \n", audio->out_channel_mode); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "rflush %d\n", audio->rflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d \n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d \n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d \n", audio->out_needed); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_head %d \n", audio->out_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_tail %d \n", audio->out_tail); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[0].used %d \n", audio->out[0].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[1].used %d \n", audio->out[1].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "buffer_refresh %d \n", audio->buf_refresh); - n += scnprintf(buffer + n, debug_bufmax - n, - "read_next %d \n", audio->read_next); - n += scnprintf(buffer + n, debug_bufmax - n, - "fill_next %d \n", audio->fill_next); - for (i = 0; i < audio->pcm_buf_count; i++) - n += scnprintf(buffer + n, debug_bufmax - n, - "in[%d].size %d \n", i, audio->in[i].used); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audmp3_debug_fops = { - .read = audmp3_debug_read, - .open = audmp3_debug_open, -}; -#endif - -static int audio_open(struct inode *inode, struct file *file) -{ - - struct audio *audio = NULL; - int rc, i, dec_attrb, decid; - struct audmp3_event *e_node = NULL; - unsigned pmem_sz = DMASZ_MAX; -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_mp3_" + 5]; -#endif - - /* Allocate audio instance, set to zero */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("no memory to allocate audio instance \n"); - rc = -ENOMEM; - goto done; - } - MM_INFO("audio instance 0x%08x created\n", (int)audio); - - /* Allocate the decoder */ - dec_attrb = AUDDEC_DEC_MP3; - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_NONTUNNEL; - audio->pcm_feedback = NON_TUNNEL_MODE_PLAYBACK; - } else if ((file->f_mode & FMODE_WRITE) && - !(file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_TUNNEL; - audio->pcm_feedback = TUNNEL_MODE_PLAYBACK; - } else { - kfree(audio); - rc = -EACCES; - goto done; - } - - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - if (decid < 0) { - MM_ERR("No free decoder available, freeing instance 0x%08x\n", - (int)audio); - rc = -ENODEV; - kfree(audio); - goto done; - } - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - /* AIO interface */ - if (file->f_flags & O_NONBLOCK) { - MM_DBG("set to aio interface\n"); - audio->drv_status |= ADRV_STATUS_AIO_INTF; - audio->drv_ops.pcm_buf_update = audmp3_async_pcm_buf_update; - audio->drv_ops.buffer_refresh = audmp3_async_buffer_refresh; - audio->drv_ops.send_data = audmp3_async_send_data; - audio->drv_ops.out_flush = audmp3_async_flush; - audio->drv_ops.in_flush = audmp3_async_flush_pcm_buf; - audio->drv_ops.fsync = audmp3_async_fsync; - } else { - MM_DBG("set to std io interface\n"); - while (pmem_sz >= DMASZ_MIN) { - MM_DBG("pmemsz = %d\n", pmem_sz); - audio->phys = allocate_contiguous_ebi_nomap(pmem_sz, - SZ_4K); - if (audio->phys) { - audio->map_v_write = ioremap( - audio->phys, pmem_sz); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("failed to map write physical" - " address , freeing instance" - "0x%08x\n", (int)audio); - rc = -ENOMEM; - free_contiguous_memory_by_paddr( - audio->phys); - audpp_adec_free(audio->dec_id); - kfree(audio); - goto done; - } - audio->data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr\ - 0x%08x\n", audio->phys,\ - (int)audio->data); - break; - } else if (pmem_sz == DMASZ_MIN) { - MM_ERR("could not allocate write buffers, \ - freeing instance 0x%08x\n", - (int)audio); - rc = -ENOMEM; - audpp_adec_free(audio->dec_id); - kfree(audio); - goto done; - } else - pmem_sz >>= 1; - } - audio->out_dma_sz = pmem_sz; - audio->drv_ops.pcm_buf_update = audio_update_pcm_buf_entry; - audio->drv_ops.buffer_refresh = audplay_buffer_refresh; - audio->drv_ops.send_data = audplay_send_data; - audio->drv_ops.out_flush = audio_flush; - audio->drv_ops.in_flush = audio_flush_pcm_buf; - audio->drv_ops.fsync = audmp3_sync_fsync; - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = (audio->out_dma_sz >> 1); - - audio->out[1].data = audio->data + audio->out[0].size; - audio->out[1].addr = audio->phys + audio->out[0].size; - audio->out[1].size = audio->out[0].size; - } - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audplay_adsp_ops, audio); - - if (rc) { - MM_ERR("failed to get %s module freeing instance 0x%08x\n", - audio->module_name, (int)audio); - goto err; - } - - /* Initialize all locks of audio instance */ - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->read_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - init_waitqueue_head(&audio->write_wait); - init_waitqueue_head(&audio->read_wait); - INIT_LIST_HEAD(&audio->out_queue); - INIT_LIST_HEAD(&audio->in_queue); - INIT_LIST_HEAD(&audio->pmem_region_queue); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - spin_lock_init(&audio->event_queue_lock); - init_waitqueue_head(&audio->avsync_wait); - - audio->out_sample_rate = 44100; - audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V; - audio->vol_pan.volume = 0x2000; - audio->bitstream_error_threshold_value = - BITSTREAM_ERROR_THRESHOLD_VALUE; - - audio->drv_ops.out_flush(audio); - - file->private_data = audio; - audio->opened = 1; - - audio->device_events = AUDDEV_EVT_DEV_RDY - |AUDDEV_EVT_DEV_RLS | - AUDDEV_EVT_STREAM_VOL_CHG; - - rc = auddev_register_evt_listner(audio->device_events, - AUDDEV_CLNT_DEC, - audio->dec_id, - mp3_listner, - (void *)audio); - if (rc) { - MM_ERR("%s: failed to register listner\n", __func__); - goto event_err; - } - -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_mp3_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, &audmp3_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audmp3_resume; - audio->suspend_ctl.node.suspend = audmp3_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (i = 0; i < AUDMP3_EVENT_NUM; i++) { - e_node = kmalloc(sizeof(struct audmp3_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } - memset(&audio->stream_info, 0, sizeof(struct msm_audio_bitstream_info)); - memset(&audio->bitstream_error_info, 0, - sizeof(struct msm_audio_bitstream_info)); -done: - return rc; -event_err: - msm_adsp_put(audio->audplay); -err: - if (audio->data) { - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - } - audpp_adec_free(audio->dec_id); - kfree(audio); - return rc; -} - -static const struct file_operations audio_mp3_fops = { - .owner = THIS_MODULE, - .open = audio_open, - .release = audio_release, - .read = audio_read, - .write = audio_write, - .unlocked_ioctl = audio_ioctl, - .fsync = audmp3_fsync, -}; - -struct miscdevice audio_mp3_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_mp3", - .fops = &audio_mp3_fops, -}; - -static int __init audio_init(void) -{ - return misc_register(&audio_mp3_misc); -} - -static void __exit audio_exit(void) -{ - misc_deregister(&audio_mp3_misc); -} - -module_init(audio_init); -module_exit(audio_exit); - -MODULE_DESCRIPTION("MSM MP3 driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_mvs.c b/arch/arm/mach-msm/qdsp5v2/audio_mvs.c deleted file mode 100644 index f211fa01ac3e1d5986b4a4252c7110c0a50b1f85..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_mvs.c +++ /dev/null @@ -1,1766 +0,0 @@ -/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define MVS_PROG 0x30000014 -#define MVS_VERS 0x00030001 -#define MVS_VERS_COMP_VER4 0x00040001 -#define MVS_VERS_COMP_VER5 0x00050001 - -#define MVS_CLIENT_ID_VOIP 0x00000003 - -#define MVS_ACQUIRE_PROC 4 -#define MVS_ENABLE_PROC 5 -#define MVS_RELEASE_PROC 6 -#define MVS_AMR_SET_AMR_MODE_PROC 7 -#define MVS_AMR_SET_AWB_MODE_PROC 8 -#define MVS_VOC_SET_FRAME_RATE_PROC 10 -#define MVS_GSM_SET_DTX_MODE_PROC 11 -#define MVS_G729A_SET_MODE_PROC 12 -#define MVS_G711_GET_MODE_PROC 14 -#define MVS_G711_SET_MODE_PROC 15 -#define MVS_G711A_GET_MODE_PROC 16 -#define MVS_G711A_SET_MODE_PROC 17 -#define MVS_G722_SET_MODE_PROC 20 -#define MVS_G722_GET_MODE_PROC 21 -#define MVS_SET_DTX_MODE_PROC 22 - -#define MVS_EVENT_CB_TYPE_PROC 1 -#define MVS_PACKET_UL_FN_TYPE_PROC 2 -#define MVS_PACKET_DL_FN_TYPE_PROC 3 - -#define MVS_CB_FUNC_ID 0xAAAABBBB -#define MVS_UL_CB_FUNC_ID 0xBBBBCCCC -#define MVS_DL_CB_FUNC_ID 0xCCCCDDDD - -#define MVS_FRAME_MODE_VOC_TX 1 -#define MVS_FRAME_MODE_VOC_RX 2 -#define MVS_FRAME_MODE_AMR_UL 3 -#define MVS_FRAME_MODE_AMR_DL 4 -#define MVS_FRAME_MODE_GSM_UL 5 -#define MVS_FRAME_MODE_GSM_DL 6 -#define MVS_FRAME_MODE_HR_UL 7 -#define MVS_FRAME_MODE_HR_DL 8 -#define MVS_FRAME_MODE_G711_UL 9 -#define MVS_FRAME_MODE_G711_DL 10 -#define MVS_FRAME_MODE_PCM_UL 13 -#define MVS_FRAME_MODE_PCM_DL 14 -#define MVS_FRAME_MODE_G729A_UL 17 -#define MVS_FRAME_MODE_G729A_DL 18 -#define MVS_FRAME_MODE_G711A_UL 19 -#define MVS_FRAME_MODE_G711A_DL 20 -#define MVS_FRAME_MODE_G722_UL 21 -#define MVS_FRAME_MODE_G722_DL 22 - - - -#define MVS_PKT_CONTEXT_ISR 0x00000001 - -#define RPC_TYPE_REQUEST 0 -#define RPC_TYPE_REPLY 1 - -#define RPC_STATUS_FAILURE 0 -#define RPC_STATUS_SUCCESS 1 -#define RPC_STATUS_REJECT 1 - -#define RPC_COMMON_HDR_SZ (sizeof(uint32_t) * 2) -#define RPC_REQUEST_HDR_SZ (sizeof(struct rpc_request_hdr)) -#define RPC_REPLY_HDR_SZ (sizeof(uint32_t) * 3) - -enum audio_mvs_state_type { - AUDIO_MVS_CLOSED, - AUDIO_MVS_OPENED, - AUDIO_MVS_STARTED, - AUDIO_MVS_STOPPED -}; - -enum audio_mvs_event_type { - AUDIO_MVS_COMMAND, - AUDIO_MVS_MODE, - AUDIO_MVS_NOTIFY -}; - -enum audio_mvs_cmd_status_type { - AUDIO_MVS_CMD_FAILURE, - AUDIO_MVS_CMD_BUSY, - AUDIO_MVS_CMD_SUCCESS -}; - -enum audio_mvs_mode_status_type { - AUDIO_MVS_MODE_NOT_AVAIL, - AUDIO_MVS_MODE_INIT, - AUDIO_MVS_MODE_READY -}; - -enum audio_mvs_pkt_status_type { - AUDIO_MVS_PKT_NORMAL, - AUDIO_MVS_PKT_FAST, - AUDIO_MVS_PKT_SLOW -}; - -/* Parameters required for MVS acquire. */ -struct rpc_audio_mvs_acquire_args { - uint32_t client_id; - uint32_t cb_func_id; -}; - -struct audio_mvs_acquire_msg { - struct rpc_request_hdr rpc_hdr; - struct rpc_audio_mvs_acquire_args acquire_args; -}; - -/* Parameters required for MVS enable. */ -struct rpc_audio_mvs_enable_args { - uint32_t client_id; - uint32_t mode; - uint32_t ul_cb_func_id; - uint32_t dl_cb_func_id; - uint32_t context; -}; - -struct audio_mvs_enable_msg { - struct rpc_request_hdr rpc_hdr; - struct rpc_audio_mvs_enable_args enable_args; -}; - -/* Parameters required for MVS release. */ -struct audio_mvs_release_msg { - struct rpc_request_hdr rpc_hdr; - uint32_t client_id; -}; - -/* Parameters required for setting AMR mode. */ -struct audio_mvs_set_amr_mode_msg { - struct rpc_request_hdr rpc_hdr; - uint32_t amr_mode; -}; - -/* Parameters required for setting DTX. */ -struct audio_mvs_set_dtx_mode_msg { - struct rpc_request_hdr rpc_hdr; - uint32_t dtx_mode; -}; - -/* Parameters required for setting EVRC mode. */ -struct audio_mvs_set_voc_mode_msg { - struct rpc_request_hdr rpc_hdr; - uint32_t max_rate; - uint32_t min_rate; -}; - -/* Parameters for G711 mode */ -struct audio_mvs_set_g711_mode_msg { - struct rpc_request_hdr rpc_hdr; - uint32_t g711_mode; -}; - -/* Parameters for G729 mode */ -struct audio_mvs_set_g729_mode_msg { - struct rpc_request_hdr rpc_hdr; - uint32_t g729_mode; -}; - -/* Parameters for G722 mode */ -struct audio_mvs_set_g722_mode_msg { - struct rpc_request_hdr rpc_hdr; - uint32_t g722_mode; -}; - - -/* Parameters for G711A mode */ -struct audio_mvs_set_g711A_mode_msg { - struct rpc_request_hdr rpc_hdr; - uint32_t g711A_mode; -}; - -/* Parameters for EFR FR and HR mode */ -struct audio_mvs_set_efr_mode_msg { - struct rpc_request_hdr rpc_hdr; - uint32_t efr_mode; -}; - -union audio_mvs_event_data { - struct mvs_ev_command_type { - uint32_t event; - uint32_t client_id; - uint32_t cmd_status; - } mvs_ev_command_type; - - struct mvs_ev_mode_type { - uint32_t event; - uint32_t client_id; - uint32_t mode_status; - uint32_t mode; - } mvs_ev_mode_type; - - struct mvs_ev_notify_type { - uint32_t event; - uint32_t client_id; - uint32_t buf_dir; - uint32_t max_frames; - } mvs_ev_notify_type; -}; - -struct audio_mvs_cb_func_args { - uint32_t cb_func_id; - uint32_t valid_ptr; - uint32_t event; - union audio_mvs_event_data event_data; -}; - -struct audio_mvs_frame_info_hdr { - uint32_t frame_mode; - uint32_t mvs_mode; - uint16_t buf_free_cnt; -}; - -struct audio_mvs_ul_reply { - struct rpc_reply_hdr reply_hdr; - uint32_t valid_pkt_status_ptr; - uint32_t pkt_status; -}; - -struct audio_mvs_dl_cb_func_args { - uint32_t cb_func_id; - - uint32_t valid_ptr; - uint32_t frame_mode; - uint32_t frame_mode_ignore; - - struct audio_mvs_frame_info_hdr frame_info_hdr; - - uint32_t amr_frame; - uint32_t amr_mode; -}; -/*general codec parameters includes AMR, G711A, PCM -G729, VOC and HR vocoders -*/ -struct gnr_cdc_param { - uint32_t param1; - uint32_t param2; - uint32_t valid_pkt_status_ptr; - uint32_t pkt_status; -}; -/*G711 codec parameter*/ -struct g711_param { - uint32_t param1; - uint32_t valid_pkt_status_ptr; - uint32_t pkt_status; -}; - -union codec_param { - struct gnr_cdc_param gnr_arg; - struct g711_param g711_arg; -}; - -struct audio_mvs_dl_reply { - struct rpc_reply_hdr reply_hdr; - - uint32_t voc_pkt[Q5V2_MVS_MAX_VOC_PKT_SIZE/4]; - - uint32_t valid_frame_info_ptr; - uint32_t frame_mode; - uint32_t frame_mode_again; - - struct audio_mvs_frame_info_hdr frame_info_hdr; - union codec_param cdc_param; -}; - -struct audio_mvs_buf_node { - struct list_head list; - struct q5v2_msm_audio_mvs_frame frame; -}; - -/* Each buffer is 20 ms, queue holds 200 ms of data. */ -#define MVS_MAX_Q_LEN 10 - -struct audio_mvs_info_type { - enum audio_mvs_state_type state; - uint32_t frame_mode; - uint32_t mvs_mode; - uint32_t buf_free_cnt; - uint32_t rate_type; - uint32_t dtx_mode; - struct min_max_rate min_max_rate; - - struct msm_rpc_endpoint *rpc_endpt; - uint32_t rpc_prog; - uint32_t rpc_ver; - uint32_t rpc_status; - - uint8_t *mem_chunk; - - struct list_head in_queue; - struct list_head free_in_queue; - - struct list_head out_queue; - struct list_head free_out_queue; - - struct task_struct *task; - - wait_queue_head_t wait; - wait_queue_head_t mode_wait; - wait_queue_head_t out_wait; - - struct mutex lock; - struct mutex in_lock; - struct mutex out_lock; - - struct wake_lock suspend_lock; - struct pm_qos_request pm_qos_req; -}; - -static struct audio_mvs_info_type audio_mvs_info; - -static int audio_mvs_setup_mode(struct audio_mvs_info_type *audio) -{ - int rc = 0; - - pr_debug("%s:\n", __func__); - - switch (audio->mvs_mode) { - case MVS_MODE_AMR: - case MVS_MODE_AMR_WB: { - struct audio_mvs_set_amr_mode_msg set_amr_mode_msg; - struct audio_mvs_set_dtx_mode_msg set_dtx_mode_msg; - - /* Set AMR mode. */ - memset(&set_amr_mode_msg, 0, sizeof(set_amr_mode_msg)); - set_amr_mode_msg.amr_mode = cpu_to_be32(audio->rate_type); - - if (audio->mvs_mode == MVS_MODE_AMR) { - msm_rpc_setup_req(&set_amr_mode_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_AMR_SET_AMR_MODE_PROC); - } else { - msm_rpc_setup_req(&set_amr_mode_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_AMR_SET_AWB_MODE_PROC); - } - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, - &set_amr_mode_msg, - sizeof(set_amr_mode_msg)); - - if (rc >= 0) { - pr_debug("%s: RPC write for set amr mode done\n", - __func__); - - /* Save the MVS configuration information. */ - audio->frame_mode = MVS_FRAME_MODE_AMR_DL; - - /* Disable DTX. */ - memset(&set_dtx_mode_msg, 0, sizeof(set_dtx_mode_msg)); - set_dtx_mode_msg.dtx_mode = cpu_to_be32(0); - - msm_rpc_setup_req(&set_dtx_mode_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_SET_DTX_MODE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, - &set_dtx_mode_msg, - sizeof(set_dtx_mode_msg)); - - if (rc >= 0) { - pr_debug("%s: RPC write for set dtx done\n", - __func__); - - rc = 0; - } - } else { - pr_err("%s: RPC write for set amr mode failed %d\n", - __func__, rc); - } - break; - } - case MVS_MODE_PCM: - case MVS_MODE_LINEAR_PCM: { - /* PCM does not have any params to be set. - Save the MVS configuration information. */ - audio->rate_type = MVS_AMR_MODE_UNDEF; - audio->frame_mode = MVS_FRAME_MODE_PCM_DL; - break; - } - case MVS_MODE_IS127: - case MVS_MODE_IS733: - case MVS_MODE_4GV_NB: - case MVS_MODE_4GV_WB: { - struct audio_mvs_set_voc_mode_msg set_voc_mode_msg; - - /* Set EVRC mode. */ - memset(&set_voc_mode_msg, 0, sizeof(set_voc_mode_msg)); - set_voc_mode_msg.min_rate = - cpu_to_be32(audio->min_max_rate.min_rate); - set_voc_mode_msg.max_rate = - cpu_to_be32(audio->min_max_rate.max_rate); - - msm_rpc_setup_req(&set_voc_mode_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_VOC_SET_FRAME_RATE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, - &set_voc_mode_msg, - sizeof(set_voc_mode_msg)); - - if (rc >= 0) { - pr_debug("%s: RPC write for set voc mode done\n", - __func__); - - /* Save the MVS configuration information. */ - audio->frame_mode = MVS_FRAME_MODE_VOC_RX; - - rc = 0; - } else { - pr_err("%s: RPC write for set voc mode failed %d\n", - __func__, rc); - } - break; - } - case MVS_MODE_G711: { - struct audio_mvs_set_g711_mode_msg set_g711_mode_msg; - - /* Set G711 mode. */ - memset(&set_g711_mode_msg, 0, sizeof(set_g711_mode_msg)); - set_g711_mode_msg.g711_mode = cpu_to_be32(audio->rate_type); - - pr_debug("%s: mode of g711:%d\n", - __func__, set_g711_mode_msg.g711_mode); - - msm_rpc_setup_req(&set_g711_mode_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_G711_SET_MODE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, - &set_g711_mode_msg, - sizeof(set_g711_mode_msg)); - - if (rc >= 0) { - pr_debug("%s: RPC write for set g711 mode done\n", - __func__); - /* Save the MVS configuration information. */ - audio->frame_mode = MVS_FRAME_MODE_G711_DL; - - rc = 0; - } else { - pr_err("%s: RPC write for set g711 mode failed %d\n", - __func__, rc); - } - break; - } - case MVS_MODE_G729A: { - struct audio_mvs_set_g729_mode_msg set_g729_mode_msg; - - /* Set G729 mode. */ - memset(&set_g729_mode_msg, 0, sizeof(set_g729_mode_msg)); - set_g729_mode_msg.g729_mode = cpu_to_be32(audio->dtx_mode); - - pr_debug("%s: mode of g729:%d\n", - __func__, set_g729_mode_msg.g729_mode); - - msm_rpc_setup_req(&set_g729_mode_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_G729A_SET_MODE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, - &set_g729_mode_msg, - sizeof(set_g729_mode_msg)); - - if (rc >= 0) { - pr_debug("%s: RPC write for set g729 mode done\n", - __func__); - - /* Save the MVS configuration information. */ - audio->frame_mode = MVS_FRAME_MODE_G729A_DL; - - rc = 0; - } else { - pr_err("%s: RPC write for set g729 mode failed %d\n", - __func__, rc); - } - break; - } - case MVS_MODE_G722: { - struct audio_mvs_set_g722_mode_msg set_g722_mode_msg; - - /* Set G722 mode. */ - memset(&set_g722_mode_msg, 0, sizeof(set_g722_mode_msg)); - set_g722_mode_msg.g722_mode = cpu_to_be32(audio->rate_type); - - pr_debug("%s: mode of g722:%d\n", - __func__, set_g722_mode_msg.g722_mode); - - msm_rpc_setup_req(&set_g722_mode_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_G722_SET_MODE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, - &set_g722_mode_msg, - sizeof(set_g722_mode_msg)); - - if (rc >= 0) { - pr_debug("%s: RPC write for set g722 mode done\n", - __func__); - - /* Save the MVS configuration information. */ - audio->frame_mode = MVS_FRAME_MODE_G722_DL; - - rc = 0; - } - break; - } - case MVS_MODE_G711A: { - struct audio_mvs_set_g711A_mode_msg set_g711A_mode_msg; - struct audio_mvs_set_dtx_mode_msg set_dtx_mode_msg; - - /* Set G711A mode. */ - memset(&set_g711A_mode_msg, 0, sizeof(set_g711A_mode_msg)); - set_g711A_mode_msg.g711A_mode = cpu_to_be32(audio->rate_type); - - pr_debug("%s: mode of g711A:%d\n", - __func__, set_g711A_mode_msg.g711A_mode); - - msm_rpc_setup_req(&set_g711A_mode_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_G711A_SET_MODE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, - &set_g711A_mode_msg, - sizeof(set_g711A_mode_msg)); - - if (rc >= 0) { - pr_debug("%s: RPC write for set g711A mode done\n", - __func__); - - /* Save the MVS configuration information. */ - audio->frame_mode = MVS_FRAME_MODE_G711A_DL; - /* Set DTX MODE. */ - memset(&set_dtx_mode_msg, 0, sizeof(set_dtx_mode_msg)); - set_dtx_mode_msg.dtx_mode = - cpu_to_be32((audio->dtx_mode)); - - msm_rpc_setup_req(&set_dtx_mode_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_SET_DTX_MODE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, - &set_dtx_mode_msg, - sizeof(set_dtx_mode_msg)); - - if (rc >= 0) { - pr_debug("%s: RPC write for set dtx done\n", - __func__); - - rc = 0; - } - rc = 0; - } else { - pr_err("%s: RPC write for set g711A mode failed %d\n", - __func__, rc); - } - break; - } - case MVS_MODE_EFR: - case MVS_MODE_FR: - case MVS_MODE_HR: { - struct audio_mvs_set_efr_mode_msg set_efr_mode_msg; - - /* Set G729 mode. */ - memset(&set_efr_mode_msg, 0, sizeof(set_efr_mode_msg)); - set_efr_mode_msg.efr_mode = cpu_to_be32(audio->dtx_mode); - - pr_debug("%s: mode of EFR, FR and HR:%d\n", - __func__, set_efr_mode_msg.efr_mode); - - msm_rpc_setup_req(&set_efr_mode_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_GSM_SET_DTX_MODE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, - &set_efr_mode_msg, - sizeof(set_efr_mode_msg)); - - if (rc >= 0) { - pr_debug("%s: RPC write for set EFR, FR and HR mode done\n", - __func__); - - /* Save the MVS configuration information. */ - if ((audio->mvs_mode == MVS_MODE_EFR) || - (audio->mvs_mode == MVS_MODE_FR)) - audio->frame_mode = MVS_FRAME_MODE_GSM_DL; - if (audio->mvs_mode == MVS_MODE_HR) - audio->frame_mode = MVS_FRAME_MODE_HR_DL; - - rc = 0; - } else { - pr_err("%s: RPC write for set EFR, FR and HR mode failed %d\n", - __func__, rc); - } - break; - } - default: - rc = -EINVAL; - pr_err("Default case\n"); - } - return rc; -} - -static int audio_mvs_setup(struct audio_mvs_info_type *audio) -{ - int rc = 0; - struct audio_mvs_enable_msg enable_msg; - - pr_debug("%s:\n", __func__); - - /* Enable MVS. */ - memset(&enable_msg, 0, sizeof(enable_msg)); - enable_msg.enable_args.client_id = cpu_to_be32(MVS_CLIENT_ID_VOIP); - enable_msg.enable_args.mode = cpu_to_be32(audio->mvs_mode); - enable_msg.enable_args.ul_cb_func_id = cpu_to_be32(MVS_UL_CB_FUNC_ID); - enable_msg.enable_args.dl_cb_func_id = cpu_to_be32(MVS_DL_CB_FUNC_ID); - enable_msg.enable_args.context = cpu_to_be32(MVS_PKT_CONTEXT_ISR); - - msm_rpc_setup_req(&enable_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_ENABLE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, &enable_msg, sizeof(enable_msg)); - - if (rc >= 0) { - pr_debug("%s: RPC write for enable done\n", __func__); - - rc = wait_event_timeout(audio->mode_wait, - (audio->rpc_status != RPC_STATUS_FAILURE), - 10 * HZ); - - if (rc > 0) { - pr_debug("%s: Wait event for enable succeeded\n", - __func__); - rc = audio_mvs_setup_mode(audio); - if (rc < 0) { - pr_err("%s: Unknown MVS mode %d\n", - __func__, audio->mvs_mode); - } - pr_err("rc value after mode setup: %d\n", rc); - } else { - pr_err("%s: Wait event for enable failed %d\n", - __func__, rc); - } - } else { - pr_err("%s: RPC write for enable failed %d\n", __func__, rc); - } - - return rc; -} - -static int audio_mvs_start(struct audio_mvs_info_type *audio) -{ - int rc = 0; - struct audio_mvs_acquire_msg acquire_msg; - - pr_info("%s:\n", __func__); - - /* Prevent sleep. */ - wake_lock(&audio->suspend_lock); - pm_qos_update_request(&audio->pm_qos_req, - msm_cpuidle_get_deep_idle_latency()); - - /* Acquire MVS. */ - memset(&acquire_msg, 0, sizeof(acquire_msg)); - acquire_msg.acquire_args.client_id = cpu_to_be32(MVS_CLIENT_ID_VOIP); - acquire_msg.acquire_args.cb_func_id = cpu_to_be32(MVS_CB_FUNC_ID); - - msm_rpc_setup_req(&acquire_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_ACQUIRE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, - &acquire_msg, - sizeof(acquire_msg)); - - if (rc >= 0) { - pr_debug("%s: RPC write for acquire done\n", __func__); - - rc = wait_event_timeout(audio->wait, - (audio->rpc_status != RPC_STATUS_FAILURE), - 1 * HZ); - - if (rc > 0) { - - rc = audio_mvs_setup(audio); - - if (rc == 0) - audio->state = AUDIO_MVS_STARTED; - - } else { - pr_err("%s: Wait event for acquire failed %d\n", - __func__, rc); - - rc = -EBUSY; - } - } else { - pr_err("%s: RPC write for acquire failed %d\n", __func__, rc); - - rc = -EBUSY; - } - - return rc; -} - -static int audio_mvs_stop(struct audio_mvs_info_type *audio) -{ - int rc = 0; - struct audio_mvs_release_msg release_msg; - - pr_info("%s:\n", __func__); - - /* Release MVS. */ - memset(&release_msg, 0, sizeof(release_msg)); - release_msg.client_id = cpu_to_be32(MVS_CLIENT_ID_VOIP); - - msm_rpc_setup_req(&release_msg.rpc_hdr, - audio->rpc_prog, - audio->rpc_ver, - MVS_RELEASE_PROC); - - audio->rpc_status = RPC_STATUS_FAILURE; - rc = msm_rpc_write(audio->rpc_endpt, &release_msg, sizeof(release_msg)); - - if (rc >= 0) { - pr_debug("%s: RPC write for release done\n", __func__); - - rc = wait_event_timeout(audio->mode_wait, - (audio->rpc_status != RPC_STATUS_FAILURE), - 1 * HZ); - - if (rc > 0) { - pr_debug("%s: Wait event for release succeeded\n", - __func__); - - audio->state = AUDIO_MVS_STOPPED; - - /* Un-block read in case it is waiting for data. */ - wake_up(&audio->out_wait); - rc = 0; - } else { - pr_err("%s: Wait event for release failed %d\n", - __func__, rc); - } - } else { - pr_err("%s: RPC write for release failed %d\n", __func__, rc); - } - - /* Allow sleep. */ - pm_qos_update_request(&audio->pm_qos_req, PM_QOS_DEFAULT_VALUE); - wake_unlock(&audio->suspend_lock); - - return rc; -} - -static void audio_mvs_process_rpc_request(uint32_t procedure, - uint32_t xid, - void *data, - uint32_t length, - struct audio_mvs_info_type *audio) -{ - int rc = 0; - - pr_debug("%s:\n", __func__); - - switch (procedure) { - case MVS_EVENT_CB_TYPE_PROC: { - struct audio_mvs_cb_func_args *args = data; - struct rpc_reply_hdr reply_hdr; - - pr_debug("%s: MVS CB CB_FUNC_ID 0x%x\n", - __func__, be32_to_cpu(args->cb_func_id)); - - if (be32_to_cpu(args->valid_ptr)) { - uint32_t event_type = be32_to_cpu(args->event); - - pr_debug("%s: MVS CB event type %d\n", - __func__, be32_to_cpu(args->event)); - - if (event_type == AUDIO_MVS_COMMAND) { - uint32_t cmd_status = be32_to_cpu( - args->event_data.mvs_ev_command_type.cmd_status); - - pr_debug("%s: MVS CB command status %d\n", - __func__, cmd_status); - - if (cmd_status == AUDIO_MVS_CMD_SUCCESS) { - audio->rpc_status = RPC_STATUS_SUCCESS; - wake_up(&audio->wait); - } - - } else if (event_type == AUDIO_MVS_MODE) { - uint32_t mode_status = be32_to_cpu( - args->event_data.mvs_ev_mode_type.mode_status); - - pr_debug("%s: MVS CB mode status %d\n", - __func__, mode_status); - - if (mode_status == AUDIO_MVS_MODE_READY) { - audio->rpc_status = RPC_STATUS_SUCCESS; - wake_up(&audio->mode_wait); - } - } else { - pr_err("%s: MVS CB unknown event type %d\n", - __func__, event_type); - } - } else { - pr_err("%s: MVS CB event pointer not valid\n", - __func__); - } - - /* Send ack to modem. */ - memset(&reply_hdr, 0, sizeof(reply_hdr)); - reply_hdr.xid = cpu_to_be32(xid); - reply_hdr.type = cpu_to_be32(RPC_TYPE_REPLY); - reply_hdr.reply_stat = cpu_to_be32(RPCMSG_REPLYSTAT_ACCEPTED); - - reply_hdr.data.acc_hdr.accept_stat = cpu_to_be32( - RPC_ACCEPTSTAT_SUCCESS); - reply_hdr.data.acc_hdr.verf_flavor = 0; - reply_hdr.data.acc_hdr.verf_length = 0; - - rc = msm_rpc_write(audio->rpc_endpt, - &reply_hdr, - sizeof(reply_hdr)); - - if (rc < 0) - pr_err("%s: RPC write for response failed %d\n", - __func__, rc); - - break; - } - - case MVS_PACKET_UL_FN_TYPE_PROC: { - uint32_t *args = data; - uint32_t pkt_len; - uint32_t frame_mode; - struct audio_mvs_ul_reply ul_reply; - struct audio_mvs_buf_node *buf_node = NULL; - - pr_debug("%s: MVS UL CB_FUNC_ID 0x%x\n", - __func__, be32_to_cpu(*args)); - args++; - - pkt_len = be32_to_cpu(*args); - pr_debug("%s: UL pkt_len %d\n", __func__, pkt_len); - args++; - - /* Copy the vocoder packets. */ - mutex_lock(&audio->out_lock); - - if (!list_empty(&audio->free_out_queue)) { - buf_node = list_first_entry(&audio->free_out_queue, - struct audio_mvs_buf_node, - list); - list_del(&buf_node->list); - - memcpy(&buf_node->frame.voc_pkt[0], args, pkt_len); - buf_node->frame.len = pkt_len; - pkt_len = ALIGN(pkt_len, 4); - args = args + pkt_len/4; - - pr_debug("%s: UL valid_ptr 0x%x\n", - __func__, be32_to_cpu(*args)); - args++; - - frame_mode = be32_to_cpu(*args); - pr_debug("%s: UL frame_mode %d\n", - __func__, frame_mode); - args++; - - pr_debug("%s: UL frame_mode %d\n", - __func__, be32_to_cpu(*args)); - args++; - - pr_debug("%s: UL frame_mode %d\n", - __func__, be32_to_cpu(*args)); - args++; - - pr_debug("%s: UL mvs_mode %d\n", - __func__, be32_to_cpu(*args)); - args++; - - pr_debug("%s: UL buf_free_cnt %d\n", - __func__, be32_to_cpu(*args)); - args++; - - if (frame_mode == MVS_FRAME_MODE_AMR_UL) { - /* Extract AMR frame type. */ - buf_node->frame.frame_type = be32_to_cpu(*args); - - pr_debug("%s: UL AMR frame_type %d\n", - __func__, be32_to_cpu(*args)); - } else if (frame_mode == MVS_FRAME_MODE_PCM_UL) { - /* PCM don't have frame_type */ - buf_node->frame.frame_type = 0; - } else if (frame_mode == MVS_FRAME_MODE_VOC_TX) { - /* Extracting EVRC current buffer frame rate*/ - buf_node->frame.frame_type = be32_to_cpu(*args); - - pr_debug("%s: UL EVRC frame_type %d\n", - __func__, be32_to_cpu(*args)); - } else if (frame_mode == MVS_FRAME_MODE_G711_UL) { - /* Extract G711 frame type. */ - buf_node->frame.frame_type = be32_to_cpu(*args); - - pr_debug("%s: UL G711 frame_type %d\n", - __func__, be32_to_cpu(*args)); - } else if (frame_mode == MVS_FRAME_MODE_G729A_UL) { - /* Extract G729 frame type. */ - buf_node->frame.frame_type = be32_to_cpu(*args); - - pr_debug("%s: UL G729 frame_type %d\n", - __func__, be32_to_cpu(*args)); - } else if (frame_mode == MVS_FRAME_MODE_G722_UL) { - /* Extract G722 frame type. */ - buf_node->frame.frame_type = be32_to_cpu(*args); - - pr_debug("%s: UL G722 frame_type %d\n", - __func__, be32_to_cpu(*args)); - } else if (frame_mode == MVS_FRAME_MODE_G711A_UL) { - /* Extract G711A frame type. */ - buf_node->frame.frame_type = be32_to_cpu(*args); - - pr_debug("%s: UL G711A frame_type %d\n", - __func__, be32_to_cpu(*args)); - } else if ((frame_mode == MVS_FRAME_MODE_GSM_UL) || - (frame_mode == MVS_FRAME_MODE_HR_UL)) { - /* Extract EFR, FR and HR frame type. */ - buf_node->frame.frame_type = be32_to_cpu(*args); - - pr_debug("%s: UL EFR,FR,HR frame_type %d\n", - __func__, be32_to_cpu(*args)); - } else { - pr_debug("%s: UL Unknown frame mode %d\n", - __func__, frame_mode); - } - - list_add_tail(&buf_node->list, &audio->out_queue); - } else { - pr_err("%s: UL data dropped, read is slow\n", __func__); - } - - mutex_unlock(&audio->out_lock); - - wake_up(&audio->out_wait); - - /* Send UL message accept to modem. */ - memset(&ul_reply, 0, sizeof(ul_reply)); - ul_reply.reply_hdr.xid = cpu_to_be32(xid); - ul_reply.reply_hdr.type = cpu_to_be32(RPC_TYPE_REPLY); - ul_reply.reply_hdr.reply_stat = cpu_to_be32( - RPCMSG_REPLYSTAT_ACCEPTED); - - ul_reply.reply_hdr.data.acc_hdr.accept_stat = cpu_to_be32( - RPC_ACCEPTSTAT_SUCCESS); - ul_reply.reply_hdr.data.acc_hdr.verf_flavor = 0; - ul_reply.reply_hdr.data.acc_hdr.verf_length = 0; - - ul_reply.valid_pkt_status_ptr = cpu_to_be32(0x00000001); - ul_reply.pkt_status = cpu_to_be32(0x00000000); - - rc = msm_rpc_write(audio->rpc_endpt, - &ul_reply, - sizeof(ul_reply)); - - if (rc < 0) - pr_err("%s: RPC write for UL response failed %d\n", - __func__, rc); - - break; - } - - case MVS_PACKET_DL_FN_TYPE_PROC: { - struct audio_mvs_dl_cb_func_args *args = data; - struct audio_mvs_dl_reply dl_reply; - uint32_t frame_mode; - struct audio_mvs_buf_node *buf_node = NULL; - - pr_debug("%s: MVS DL CB CB_FUNC_ID 0x%x\n", - __func__, be32_to_cpu(args->cb_func_id)); - - frame_mode = be32_to_cpu(args->frame_mode); - pr_debug("%s: DL frame_mode %d\n", __func__, frame_mode); - - /* Prepare and send the DL packets to modem. */ - memset(&dl_reply, 0, sizeof(dl_reply)); - dl_reply.reply_hdr.xid = cpu_to_be32(xid); - dl_reply.reply_hdr.type = cpu_to_be32(RPC_TYPE_REPLY); - dl_reply.reply_hdr.reply_stat = cpu_to_be32( - RPCMSG_REPLYSTAT_ACCEPTED); - - dl_reply.reply_hdr.data.acc_hdr.accept_stat = cpu_to_be32( - RPC_ACCEPTSTAT_SUCCESS); - dl_reply.reply_hdr.data.acc_hdr.verf_flavor = 0; - dl_reply.reply_hdr.data.acc_hdr.verf_length = 0; - - mutex_lock(&audio->in_lock); - - if (!list_empty(&audio->in_queue)) { - buf_node = list_first_entry(&audio->in_queue, - struct audio_mvs_buf_node, - list); - list_del(&buf_node->list); - - memcpy(&dl_reply.voc_pkt, - &buf_node->frame.voc_pkt[0], - buf_node->frame.len); - - pr_debug("%s:frame mode %d\n", __func__, frame_mode); - if (frame_mode == MVS_FRAME_MODE_AMR_DL) { - dl_reply.cdc_param.gnr_arg.param1 = cpu_to_be32( - buf_node->frame.frame_type); - dl_reply.cdc_param.gnr_arg.param2 = - cpu_to_be32(audio->rate_type); - dl_reply.cdc_param.\ - gnr_arg.valid_pkt_status_ptr = - cpu_to_be32(0x00000001); - dl_reply.cdc_param.gnr_arg.pkt_status = - cpu_to_be32(AUDIO_MVS_PKT_NORMAL); - } else if (frame_mode == MVS_FRAME_MODE_PCM_DL) { - dl_reply.cdc_param.gnr_arg.param1 = 0; - dl_reply.cdc_param.gnr_arg.param2 = 0; - dl_reply.cdc_param.\ - gnr_arg.valid_pkt_status_ptr = - cpu_to_be32(0x00000001); - dl_reply.cdc_param.gnr_arg.pkt_status = - cpu_to_be32(AUDIO_MVS_PKT_NORMAL); - } else if (frame_mode == MVS_FRAME_MODE_VOC_RX) { - dl_reply.cdc_param.gnr_arg.param1 = - cpu_to_be32(buf_node->frame.frame_type); - dl_reply.cdc_param.gnr_arg.param2 = 0; - dl_reply.cdc_param.\ - gnr_arg.valid_pkt_status_ptr = - cpu_to_be32(0x00000001); - dl_reply.cdc_param.gnr_arg.pkt_status = - cpu_to_be32(AUDIO_MVS_PKT_NORMAL); - } else if (frame_mode == MVS_FRAME_MODE_G711_DL) { - dl_reply.cdc_param.g711_arg.param1 = - cpu_to_be32(buf_node->frame.frame_type); - dl_reply.cdc_param.\ - g711_arg.valid_pkt_status_ptr = - cpu_to_be32(0x00000001); - dl_reply.cdc_param.g711_arg.pkt_status = - cpu_to_be32(AUDIO_MVS_PKT_NORMAL); - } else if (frame_mode == MVS_FRAME_MODE_G729A_DL) { - dl_reply.cdc_param.gnr_arg.param1 = cpu_to_be32( - buf_node->frame.frame_type); - dl_reply.cdc_param.gnr_arg.param2 = - cpu_to_be32(audio->rate_type); - dl_reply.cdc_param.\ - gnr_arg.valid_pkt_status_ptr = - cpu_to_be32(0x00000001); - dl_reply.cdc_param.gnr_arg.pkt_status = - cpu_to_be32(AUDIO_MVS_PKT_NORMAL); - } else if (frame_mode == MVS_FRAME_MODE_G722_DL) { - dl_reply.cdc_param.gnr_arg.param1 = cpu_to_be32( - buf_node->frame.frame_type); - dl_reply.cdc_param.gnr_arg.param2 = - cpu_to_be32(audio->rate_type); - dl_reply.cdc_param.\ - gnr_arg.valid_pkt_status_ptr = - cpu_to_be32(0x00000001); - dl_reply.cdc_param.gnr_arg.pkt_status = - cpu_to_be32(AUDIO_MVS_PKT_NORMAL); - } else if (frame_mode == MVS_FRAME_MODE_G711A_DL) { - dl_reply.cdc_param.gnr_arg.param1 = cpu_to_be32( - buf_node->frame.frame_type); - dl_reply.cdc_param.gnr_arg.param2 = - cpu_to_be32(audio->rate_type); - dl_reply.cdc_param.\ - gnr_arg.valid_pkt_status_ptr = - cpu_to_be32(0x00000001); - dl_reply.cdc_param.gnr_arg.pkt_status = - cpu_to_be32(AUDIO_MVS_PKT_NORMAL); - } else if ((frame_mode == MVS_FRAME_MODE_GSM_DL) || - (frame_mode == MVS_FRAME_MODE_HR_DL)) { - dl_reply.cdc_param.gnr_arg.param1 = cpu_to_be32( - buf_node->frame.frame_type); - dl_reply.cdc_param.gnr_arg.param2 = - cpu_to_be32(audio->rate_type); - dl_reply.cdc_param.\ - gnr_arg.valid_pkt_status_ptr = - cpu_to_be32(0x00000001); - dl_reply.cdc_param.gnr_arg.pkt_status = - cpu_to_be32(AUDIO_MVS_PKT_NORMAL); - } else { - pr_err("%s: DL Unknown frame mode %d\n", - __func__, frame_mode); - } - list_add_tail(&buf_node->list, &audio->free_in_queue); - } else { - pr_debug("%s: No DL data available to send to MVS\n", - __func__); - if (frame_mode == MVS_FRAME_MODE_G711_DL) { - dl_reply.cdc_param.\ - g711_arg.valid_pkt_status_ptr = - cpu_to_be32(0x00000001); - dl_reply.cdc_param.g711_arg.pkt_status = - cpu_to_be32(AUDIO_MVS_PKT_SLOW); - } else { - dl_reply.cdc_param.\ - gnr_arg.valid_pkt_status_ptr = - cpu_to_be32(0x00000001); - dl_reply.cdc_param.gnr_arg.pkt_status = - cpu_to_be32(AUDIO_MVS_PKT_SLOW); - } - } - - mutex_unlock(&audio->in_lock); - - dl_reply.valid_frame_info_ptr = cpu_to_be32(0x00000001); - - dl_reply.frame_mode = cpu_to_be32(audio->frame_mode); - dl_reply.frame_mode_again = cpu_to_be32(audio->frame_mode); - - dl_reply.frame_info_hdr.frame_mode = - cpu_to_be32(audio->frame_mode); - dl_reply.frame_info_hdr.mvs_mode = cpu_to_be32(audio->mvs_mode); - dl_reply.frame_info_hdr.buf_free_cnt = 0; - - rc = msm_rpc_write(audio->rpc_endpt, - &dl_reply, - sizeof(dl_reply)); - - if (rc < 0) - pr_err("%s: RPC write for DL response failed %d\n", - __func__, rc); - - break; - } - - default: - pr_err("%s: Unknown CB type %d\n", __func__, procedure); - } -} - -static int audio_mvs_thread(void *data) -{ - struct audio_mvs_info_type *audio = data; - struct rpc_request_hdr *rpc_hdr = NULL; - - pr_info("%s:\n", __func__); - - while (!kthread_should_stop()) { - - int rpc_hdr_len = msm_rpc_read(audio->rpc_endpt, - (void **) &rpc_hdr, - -1, - -1); - - if (rpc_hdr_len < 0) { - pr_err("%s: RPC read failed %d\n", - __func__, rpc_hdr_len); - - break; - } else if (rpc_hdr_len < RPC_COMMON_HDR_SZ) { - continue; - } else { - uint32_t rpc_type = be32_to_cpu(rpc_hdr->type); - if (rpc_type == RPC_TYPE_REPLY) { - struct rpc_reply_hdr *rpc_reply = - (void *) rpc_hdr; - uint32_t reply_status; - - if (rpc_hdr_len < RPC_REPLY_HDR_SZ) - continue; - - reply_status = - be32_to_cpu(rpc_reply->reply_stat); - - if (reply_status != RPCMSG_REPLYSTAT_ACCEPTED) { - /* If the command is not accepted, there - * will be no response callback. Wake - * the caller and report error. */ - audio->rpc_status = RPC_STATUS_REJECT; - - wake_up(&audio->wait); - - pr_err("%s: RPC reply status denied\n", - __func__); - } - } else if (rpc_type == RPC_TYPE_REQUEST) { - if (rpc_hdr_len < RPC_REQUEST_HDR_SZ) - continue; - - audio_mvs_process_rpc_request( - be32_to_cpu(rpc_hdr->procedure), - be32_to_cpu(rpc_hdr->xid), - (void *) (rpc_hdr + 1), - (rpc_hdr_len - sizeof(*rpc_hdr)), - audio); - } else { - pr_err("%s: Unexpected RPC type %d\n", - __func__, rpc_type); - } - } - - kfree(rpc_hdr); - rpc_hdr = NULL; - } - - pr_info("%s: MVS thread stopped\n", __func__); - - return 0; -} - -static int audio_mvs_alloc_buf(struct audio_mvs_info_type *audio) -{ - int i = 0; - struct audio_mvs_buf_node *buf_node = NULL; - struct list_head *ptr = NULL; - struct list_head *next = NULL; - - pr_debug("%s:\n", __func__); - - /* Allocate input buffers. */ - for (i = 0; i < MVS_MAX_Q_LEN; i++) { - buf_node = kmalloc(sizeof(struct audio_mvs_buf_node), - GFP_KERNEL); - - if (buf_node != NULL) { - list_add_tail(&buf_node->list, - &audio->free_in_queue); - } else { - pr_err("%s: No memory for IO buffers\n", - __func__); - goto err; - } - buf_node = NULL; - } - - /* Allocate output buffers. */ - for (i = 0; i < MVS_MAX_Q_LEN; i++) { - buf_node = kmalloc(sizeof(struct audio_mvs_buf_node), - GFP_KERNEL); - - if (buf_node != NULL) { - list_add_tail(&buf_node->list, - &audio->free_out_queue); - } else { - pr_err("%s: No memory for IO buffers\n", - __func__); - goto err; - } - buf_node = NULL; - } - - return 0; - -err: - list_for_each_safe(ptr, next, &audio->free_in_queue) { - buf_node = list_entry(ptr, struct audio_mvs_buf_node, list); - list_del(&buf_node->list); - kfree(buf_node); - buf_node = NULL; - } - - ptr = next = NULL; - list_for_each_safe(ptr, next, &audio->free_out_queue) { - buf_node = list_entry(ptr, struct audio_mvs_buf_node, list); - list_del(&buf_node->list); - kfree(buf_node); - buf_node = NULL; - } - - return -ENOMEM; -} - -static void audio_mvs_free_buf(struct audio_mvs_info_type *audio) -{ - struct list_head *ptr = NULL; - struct list_head *next = NULL; - struct audio_mvs_buf_node *buf_node = NULL; - - pr_debug("%s:\n", __func__); - - mutex_lock(&audio->in_lock); - /* Free input buffers. */ - list_for_each_safe(ptr, next, &audio->in_queue) { - buf_node = list_entry(ptr, struct audio_mvs_buf_node, list); - list_del(&buf_node->list); - kfree(buf_node); - buf_node = NULL; - } - - ptr = next = NULL; - /* Free free_input buffers. */ - list_for_each_safe(ptr, next, &audio->free_in_queue) { - buf_node = list_entry(ptr, struct audio_mvs_buf_node, list); - list_del(&buf_node->list); - kfree(buf_node); - buf_node = NULL; - } - mutex_unlock(&audio->in_lock); - - mutex_lock(&audio->out_lock); - ptr = next = NULL; - /* Free output buffers. */ - list_for_each_safe(ptr, next, &audio->out_queue) { - buf_node = list_entry(ptr, struct audio_mvs_buf_node, list); - list_del(&buf_node->list); - kfree(buf_node); - buf_node = NULL; - } - - /* Free free_ioutput buffers. */ - ptr = next = NULL; - list_for_each_safe(ptr, next, &audio->free_out_queue) { - buf_node = list_entry(ptr, struct audio_mvs_buf_node, list); - list_del(&buf_node->list); - kfree(buf_node); - buf_node = NULL; - } - mutex_unlock(&audio->out_lock); -} - -static int audio_mvs_open(struct inode *inode, struct file *file) -{ - int rc = 0; - - pr_info("%s:\n", __func__); - - mutex_lock(&audio_mvs_info.lock); - - if (audio_mvs_info.state == AUDIO_MVS_CLOSED) { - - if (audio_mvs_info.task != NULL || - audio_mvs_info.rpc_endpt != NULL) { - rc = audio_mvs_alloc_buf(&audio_mvs_info); - - if (rc == 0) { - audio_mvs_info.state = AUDIO_MVS_OPENED; - file->private_data = &audio_mvs_info; - } - } else { - pr_err("%s: MVS thread and RPC end point do not exist\n", - __func__); - - rc = -ENODEV; - } - } else { - pr_err("%s: MVS driver exists, state %d\n", - __func__, audio_mvs_info.state); - - rc = -EBUSY; - } - - mutex_unlock(&audio_mvs_info.lock); - - return rc; -} - -static int audio_mvs_release(struct inode *inode, struct file *file) -{ - - struct audio_mvs_info_type *audio = file->private_data; - - pr_info("%s:\n", __func__); - - mutex_lock(&audio->lock); - if (audio->state == AUDIO_MVS_STARTED) - audio_mvs_stop(audio); - audio_mvs_free_buf(audio); - audio->state = AUDIO_MVS_CLOSED; - mutex_unlock(&audio->lock); - - pr_debug("%s: Release done\n", __func__); - return 0; -} - -static ssize_t audio_mvs_read(struct file *file, - char __user *buf, - size_t count, - loff_t *pos) -{ - int rc = 0; - struct audio_mvs_buf_node *buf_node = NULL; - struct audio_mvs_info_type *audio = file->private_data; - - pr_debug("%s:\n", __func__); - - rc = wait_event_interruptible_timeout(audio->out_wait, - (!list_empty(&audio->out_queue) || - audio->state == AUDIO_MVS_STOPPED), - 1 * HZ); - - if (rc > 0) { - mutex_lock(&audio->out_lock); - if ((audio->state == AUDIO_MVS_STARTED) && - (!list_empty(&audio->out_queue))) { - - if (count >= sizeof(struct q5v2_msm_audio_mvs_frame)) { - buf_node = list_first_entry(&audio->out_queue, - struct audio_mvs_buf_node, - list); - list_del(&buf_node->list); - - rc = copy_to_user(buf, - &buf_node->frame, - sizeof(struct q5v2_msm_audio_mvs_frame) - ); - - if (rc == 0) { - rc = buf_node->frame.len + - sizeof(buf_node->frame.frame_type) + - sizeof(buf_node->frame.len); - } else { - pr_err("%s: Copy to user retuned %d", - __func__, rc); - - rc = -EFAULT; - } - - list_add_tail(&buf_node->list, - &audio->free_out_queue); - } else { - pr_err("%s: Read count %d < sizeof(frame) %d", - __func__, count, - sizeof(struct q5v2_msm_audio_mvs_frame)); - - rc = -ENOMEM; - } - } else { - pr_err("%s: Read performed in state %d\n", - __func__, audio->state); - - rc = -EPERM; - } - mutex_unlock(&audio->out_lock); - - } else if (rc == 0) { - pr_err("%s: No UL data available\n", __func__); - - rc = -ETIMEDOUT; - } else { - pr_err("%s: Read was interrupted\n", __func__); - - rc = -ERESTARTSYS; - } - - return rc; -} - -static ssize_t audio_mvs_write(struct file *file, - const char __user *buf, - size_t count, - loff_t *pos) -{ - int rc = 0; - struct audio_mvs_buf_node *buf_node = NULL; - struct audio_mvs_info_type *audio = file->private_data; - - pr_debug("%s:\n", __func__); - - mutex_lock(&audio->in_lock); - if (audio->state == AUDIO_MVS_STARTED) { - if (count <= sizeof(struct q5v2_msm_audio_mvs_frame)) { - if (!list_empty(&audio->free_in_queue)) { - buf_node = - list_first_entry(&audio->free_in_queue, - struct audio_mvs_buf_node, - list); - list_del(&buf_node->list); - - rc = copy_from_user(&buf_node->frame, - buf, - count); - - list_add_tail(&buf_node->list, - &audio->in_queue); - } else { - pr_err("%s: No free DL buffs\n", __func__); - } - } else { - pr_err("%s: Write count %d < sizeof(frame) %d", - __func__, count, - sizeof(struct q5v2_msm_audio_mvs_frame)); - - rc = -ENOMEM; - } - } else { - pr_err("%s: Write performed in invalid state %d\n", - __func__, audio->state); - - rc = -EPERM; - } - mutex_unlock(&audio->in_lock); - - return rc; -} - -static long audio_mvs_ioctl(struct file *file, - unsigned int cmd, - unsigned long arg) -{ - int rc = 0; - - struct audio_mvs_info_type *audio = file->private_data; - - pr_info("%s:\n", __func__); - - switch (cmd) { - case AUDIO_GET_MVS_CONFIG: { - struct msm_audio_mvs_config config; - - pr_debug("%s: IOCTL GET_MVS_CONFIG\n", __func__); - - mutex_lock(&audio->lock); - config.mvs_mode = audio->mvs_mode; - config.rate_type = audio->rate_type; - config.min_max_rate.min_rate = audio->min_max_rate.min_rate; - config.min_max_rate.max_rate = audio->min_max_rate.max_rate; - mutex_unlock(&audio->lock); - - rc = copy_to_user((void *)arg, &config, sizeof(config)); - if (rc == 0) - rc = sizeof(config); - else - pr_err("%s: Config copy failed %d\n", __func__, rc); - - break; - } - - case AUDIO_SET_MVS_CONFIG: { - struct msm_audio_mvs_config config; - - pr_debug("%s: IOCTL SET_MVS_CONFIG\n", __func__); - - rc = copy_from_user(&config, (void *)arg, sizeof(config)); - if (rc == 0) { - mutex_lock(&audio->lock); - - if (audio->state == AUDIO_MVS_OPENED) { - audio->mvs_mode = config.mvs_mode; - audio->rate_type = config.rate_type; - audio->dtx_mode = config.dtx_mode; - audio->min_max_rate.min_rate = - config.min_max_rate.min_rate; - audio->min_max_rate.max_rate = - config.min_max_rate.max_rate; - } else { - pr_err("%s: Set confg called in state %d\n", - __func__, audio->state); - - rc = -EPERM; - } - - mutex_unlock(&audio->lock); - } else { - pr_err("%s: Config copy failed %d\n", __func__, rc); - } - - break; - } - - case AUDIO_START: { - pr_debug("%s: IOCTL START\n", __func__); - - mutex_lock(&audio->lock); - - if (audio->state == AUDIO_MVS_OPENED || - audio->state == AUDIO_MVS_STOPPED) { - rc = audio_mvs_start(audio); - - if (rc != 0) - audio_mvs_stop(audio); - } else { - pr_err("%s: Start called in invalid state %d\n", - __func__, audio->state); - - rc = -EPERM; - } - - mutex_unlock(&audio->lock); - - break; - } - - case AUDIO_STOP: { - pr_debug("%s: IOCTL STOP\n", __func__); - - mutex_lock(&audio->lock); - - if (audio->state == AUDIO_MVS_STARTED) { - rc = audio_mvs_stop(audio); - } else { - pr_err("%s: Stop called in invalid state %d\n", - __func__, audio->state); - - rc = -EPERM; - } - - mutex_unlock(&audio->lock); - break; - } - - default: { - pr_err("%s: Unknown IOCTL %d\n", __func__, cmd); - } - } - - return rc; -} - -static const struct file_operations audio_mvs_fops = { - .owner = THIS_MODULE, - .open = audio_mvs_open, - .release = audio_mvs_release, - .read = audio_mvs_read, - .write = audio_mvs_write, - .unlocked_ioctl = audio_mvs_ioctl -}; - -struct miscdevice audio_mvs_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_mvs", - .fops = &audio_mvs_fops -}; - -static int __init audio_mvs_init(void) -{ - int rc; - - pr_info("%s:\n", __func__); - - memset(&audio_mvs_info, 0, sizeof(audio_mvs_info)); - mutex_init(&audio_mvs_info.lock); - mutex_init(&audio_mvs_info.in_lock); - mutex_init(&audio_mvs_info.out_lock); - - init_waitqueue_head(&audio_mvs_info.wait); - init_waitqueue_head(&audio_mvs_info.mode_wait); - init_waitqueue_head(&audio_mvs_info.out_wait); - - INIT_LIST_HEAD(&audio_mvs_info.in_queue); - INIT_LIST_HEAD(&audio_mvs_info.free_in_queue); - INIT_LIST_HEAD(&audio_mvs_info.out_queue); - INIT_LIST_HEAD(&audio_mvs_info.free_out_queue); - - wake_lock_init(&audio_mvs_info.suspend_lock, - WAKE_LOCK_SUSPEND, - "audio_mvs_suspend"); - pm_qos_add_request(&audio_mvs_info.pm_qos_req, PM_QOS_CPU_DMA_LATENCY, - PM_QOS_DEFAULT_VALUE); - - audio_mvs_info.rpc_endpt = msm_rpc_connect_compatible(MVS_PROG, - MVS_VERS_COMP_VER5, - MSM_RPC_UNINTERRUPTIBLE); - - if (IS_ERR(audio_mvs_info.rpc_endpt)) { - pr_err("%s: MVS RPC connect failed ver 0x%x\n", __func__, - MVS_VERS_COMP_VER5); - audio_mvs_info.rpc_endpt = msm_rpc_connect_compatible(MVS_PROG, - MVS_VERS_COMP_VER4, - MSM_RPC_UNINTERRUPTIBLE); - if (IS_ERR(audio_mvs_info.rpc_endpt)) { - pr_err("%s: MVS RPC connect failed ver 0x%x\n", - __func__, MVS_VERS_COMP_VER4); - audio_mvs_info.rpc_endpt = - msm_rpc_connect_compatible(MVS_PROG, - MVS_VERS, - MSM_RPC_UNINTERRUPTIBLE); - if (IS_ERR(audio_mvs_info.rpc_endpt)) { - pr_err("%s: MVS RPC connect failed ver 0x%x\n", - __func__, MVS_VERS); - rc = PTR_ERR(audio_mvs_info.rpc_endpt); - audio_mvs_info.rpc_endpt = NULL; - goto done; - } else { - pr_debug("%s: MVS RPC connect succeeded ver\ - 0x%x\n", __func__, MVS_VERS); - audio_mvs_info.rpc_prog = MVS_PROG; - audio_mvs_info.rpc_ver = MVS_VERS; - } - } else { - pr_debug("%s: MVS RPC connect succeeded ver 0x%x\n", - __func__, MVS_VERS_COMP_VER4); - audio_mvs_info.rpc_prog = MVS_PROG; - audio_mvs_info.rpc_ver = MVS_VERS_COMP_VER4; - } - } else { - pr_debug("%s: MVS RPC connect succeeded ver 0x%x\n", __func__, - MVS_VERS_COMP_VER5); - audio_mvs_info.rpc_prog = MVS_PROG; - audio_mvs_info.rpc_ver = MVS_VERS_COMP_VER5; - } - audio_mvs_info.task = kthread_run(audio_mvs_thread, - &audio_mvs_info, - "audio_mvs"); - if (IS_ERR(audio_mvs_info.task)) { - pr_err("%s: MVS thread create failed\n", __func__); - rc = PTR_ERR(audio_mvs_info.task); - audio_mvs_info.task = NULL; - msm_rpc_close(audio_mvs_info.rpc_endpt); - audio_mvs_info.rpc_endpt = NULL; - goto done; - } - - rc = misc_register(&audio_mvs_misc); -done: - return rc; -} - -static void __exit audio_mvs_exit(void) -{ - pr_info("%s:\n", __func__); - - misc_deregister(&audio_mvs_misc); -} - -module_init(audio_mvs_init); -module_exit(audio_mvs_exit); - -MODULE_DESCRIPTION("MSM MVS driver"); -MODULE_LICENSE("GPL v2"); - diff --git a/arch/arm/mach-msm/qdsp5v2/audio_out.c b/arch/arm/mach-msm/qdsp5v2/audio_out.c deleted file mode 100644 index c62f2e18c972fa07515f9aef595e511deefbf04b..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_out.c +++ /dev/null @@ -1,730 +0,0 @@ -/* - * pcm audio output device - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define BUFSZ (960 * 5) -#define DMASZ (BUFSZ * 2) - -#define HOSTPCM_STREAM_ID 5 - -struct buffer { - void *data; - unsigned size; - unsigned used; - unsigned addr; -}; - -struct audio { - struct buffer out[2]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t wait; - - /* configuration to use on next enable */ - uint32_t out_sample_rate; - uint32_t out_channel_mode; - uint32_t out_weight; - uint32_t out_buffer_size; - uint32_t device_events; - int16_t source; - - /* data allocated for various buffers */ - char *data; - dma_addr_t phys; - void *map_v_write; - int teos; /* valid only if tunnel mode & no data left for decoder */ - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - uint16_t dec_id; - int voice_state; - - struct wake_lock wakelock; - struct pm_qos_request pm_qos_req; - - struct audpp_cmd_cfg_object_params_volume vol_pan; -}; - -static void audio_out_listener(u32 evt_id, union auddev_evt_data *evt_payload, - void *private_data) -{ - struct audio *audio = private_data; - switch (evt_id) { - case AUDDEV_EVT_DEV_RDY: - MM_DBG(":AUDDEV_EVT_DEV_RDY\n"); - audio->source |= (0x1 << evt_payload->routing_id); - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - break; - case AUDDEV_EVT_DEV_RLS: - MM_DBG(":AUDDEV_EVT_DEV_RLS\n"); - audio->source &= ~(0x1 << evt_payload->routing_id); - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - break; - case AUDDEV_EVT_STREAM_VOL_CHG: - audio->vol_pan.volume = evt_payload->session_vol; - MM_DBG(":AUDDEV_EVT_STREAM_VOL_CHG, stream vol %d\n", - audio->vol_pan.volume); - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - break; - case AUDDEV_EVT_VOICE_STATE_CHG: - MM_DBG("AUDDEV_EVT_VOICE_STATE_CHG, state = %d\n", - evt_payload->voice_state); - audio->voice_state = evt_payload->voice_state; - /* Voice uplink Rx case */ - if (audio->running && - (audio->source & AUDPP_MIXER_UPLINK_RX) && - (audio->voice_state == VOICE_STATE_OFFCALL)) { - MM_DBG("Voice is terminated, Wake up write: %x %x\n", - audio->voice_state, audio->source); - wake_up(&audio->wait); - } - break; - default: - MM_ERR("ERROR:wrong event\n"); - break; - } -} - -static void audio_prevent_sleep(struct audio *audio) -{ - MM_DBG("\n"); /* Macro prints the file name and function */ - wake_lock(&audio->wakelock); - pm_qos_update_request(&audio->pm_qos_req, - msm_cpuidle_get_deep_idle_latency()); -} - -static void audio_allow_sleep(struct audio *audio) -{ - pm_qos_update_request(&audio->pm_qos_req, PM_QOS_DEFAULT_VALUE); - wake_unlock(&audio->wakelock); - MM_DBG("\n"); /* Macro prints the file name and function */ -} - -static int audio_dsp_out_enable(struct audio *audio, int yes); -static int audio_dsp_send_buffer(struct audio *audio, unsigned id, - unsigned len); - -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg); - -/* must be called with audio->lock held */ -static int audio_enable(struct audio *audio) -{ - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (audio->enabled) - return 0; - - /* refuse to start if we're not ready */ - if (!audio->out[0].used || !audio->out[1].used) - return -EIO; - - /* we start buffers 0 and 1, so buffer 0 will be the - * next one the dsp will want - */ - audio->out_tail = 0; - audio->out_needed = 0; - - audio_prevent_sleep(audio); - - if (audpp_enable(-1, audio_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - audio_allow_sleep(audio); - return -ENODEV; - } - - audio->enabled = 1; - htc_pwrsink_set(PWRSINK_AUDIO, 100); - return 0; -} - -/* must be called with audio->lock held */ -static int audio_disable(struct audio *audio) -{ - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audio_dsp_out_enable(audio, 0); - - audpp_disable(-1, audio); - - wake_up(&audio->wait); - audio->out_needed = 0; - audio_allow_sleep(audio); - } - return 0; -} - -/* ------------------- dsp --------------------- */ -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - struct buffer *frame; - unsigned long flags; - static unsigned long pcmdmamsd_time; - - switch (id) { - case AUDPP_MSG_HOST_PCM_INTF_MSG: { - unsigned id = msg[3]; - unsigned idx = msg[4] - 1; - - MM_DBG("HOST_PCM id %d idx %d\n", id, idx); - if (id != AUDPP_MSG_HOSTPCM_ID_ARM_RX) { - MM_ERR("bogus id\n"); - break; - } - if (idx > 1) { - MM_ERR("bogus buffer idx\n"); - break; - } - spin_lock_irqsave(&audio->dsp_lock, flags); - if (audio->running) { - atomic_add(audio->out[idx].used, &audio->out_bytes); - audio->out[idx].used = 0; - frame = audio->out + audio->out_tail; - if (frame->used) { - /* Reset teos flag to avoid stale - * PCMDMAMISS been considered - */ - audio->teos = 0; - audio_dsp_send_buffer( - audio, audio->out_tail, frame->used); - audio->out_tail ^= 1; - } else { - audio->out_needed++; - } - wake_up(&audio->wait); - } - spin_unlock_irqrestore(&audio->dsp_lock, flags); - break; - } - case AUDPP_MSG_PCMDMAMISSED: - /* prints only if 1 second is elapsed since the last time - * this message has been printed */ - if (printk_timed_ratelimit(&pcmdmamsd_time, 1000)) - printk(KERN_INFO "[%s:%s] PCMDMAMISSED %d\n", - __MM_FILE__, __func__, msg[0]); - audio->teos++; - MM_DBG("PCMDMAMISSED Count per Buffer %d\n", audio->teos); - wake_up(&audio->wait); - break; - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - audio->out_needed = 0; - audio->running = 1; - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - audpp_route_stream(audio->dec_id, audio->source); - audio_dsp_out_enable(audio, 1); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audio->running = 0; - } else { - MM_ERR("CFG_MSG %d?\n", msg[0]); - } - break; - default: - MM_ERR("UNKNOWN (%d)\n", id); - } -} - -static int audio_dsp_out_enable(struct audio *audio, int yes) -{ - struct audpp_cmd_pcm_intf cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_PCM_INTF; - cmd.stream = AUDPP_CMD_POPP_STREAM; - cmd.stream_id = audio->dec_id; - cmd.config = AUDPP_CMD_PCM_INTF_CONFIG_CMD_V; - cmd.intf_type = AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V; - - if (yes) { - cmd.write_buf1LSW = audio->out[0].addr; - cmd.write_buf1MSW = audio->out[0].addr >> 16; - if (audio->out[0].used) - cmd.write_buf1_len = audio->out[0].used; - else - cmd.write_buf1_len = audio->out[0].size; - cmd.write_buf2LSW = audio->out[1].addr; - cmd.write_buf2MSW = audio->out[1].addr >> 16; - if (audio->out[1].used) - cmd.write_buf2_len = audio->out[1].used; - else - cmd.write_buf2_len = audio->out[1].size; - cmd.arm_to_rx_flag = AUDPP_CMD_PCM_INTF_ENA_V; - cmd.weight_decoder_to_rx = audio->out_weight; - cmd.weight_arm_to_rx = 1; - cmd.partition_number_arm_to_dsp = 0; - cmd.sample_rate = audio->out_sample_rate; - cmd.channel_mode = audio->out_channel_mode; - } - - return audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static int audio_dsp_send_buffer(struct audio *audio, unsigned idx, - unsigned len) -{ - struct audpp_cmd_pcm_intf_send_buffer cmd; - - cmd.cmd_id = AUDPP_CMD_PCM_INTF; - cmd.stream = AUDPP_CMD_POPP_STREAM; - cmd.stream_id = audio->dec_id; - cmd.config = AUDPP_CMD_PCM_INTF_BUFFER_CMD_V; - cmd.intf_type = AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V; - cmd.dsp_to_arm_buf_id = 0; - cmd.arm_to_dsp_buf_id = idx + 1; - cmd.arm_to_dsp_buf_len = len; - - return audpp_send_queue2(&cmd, sizeof(cmd)); -} - -/* ------------------- device --------------------- */ -static void audio_flush(struct audio *audio) -{ - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->stopped = 0; -} - -static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - unsigned long flags = 0; - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = atomic_read(&audio->out_bytes); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - switch (cmd) { - case AUDIO_SET_VOLUME: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.volume = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - return 0; - - case AUDIO_SET_PAN: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.pan = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - if ((audio->voice_state != VOICE_STATE_INCALL) - && (audio->source & AUDPP_MIXER_UPLINK_RX)) { - MM_ERR("Unable to Start : state %d source %d\n", - audio->voice_state, audio->source); - rc = -EPERM; - break; - } - rc = audio_enable(audio); - break; - case AUDIO_STOP: - rc = audio_disable(audio); - audio->stopped = 1; - break; - case AUDIO_FLUSH: - if (audio->stopped) { - /* Make sure we're stopped and we wake any threads - * that might be blocked holding the write_lock. - * While audio->stopped write threads will always - * exit immediately. - */ - wake_up(&audio->wait); - mutex_lock(&audio->write_lock); - audio_flush(audio); - mutex_unlock(&audio->write_lock); - } - case AUDIO_SET_CONFIG: { - struct msm_audio_config config; - if (copy_from_user(&config, (void *) arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.channel_count == 1) - config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V; - else if (config.channel_count == 2) - config.channel_count = AUDPP_CMD_PCM_INTF_STEREO_V; - else { - rc = -EINVAL; - break; - } - audio->out_sample_rate = config.sample_rate; - audio->out_channel_mode = config.channel_count; - rc = 0; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config config; - config.buffer_size = BUFSZ; - config.buffer_count = 2; - config.sample_rate = audio->out_sample_rate; - if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) - config.channel_count = 1; - else - config.channel_count = 2; - - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *) arg, &config, sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_GET_SESSION_ID: { - if (copy_to_user((void *) arg, &audio->dec_id, - sizeof(unsigned short))) - return -EFAULT; - rc = 0; - break; - } - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -static int audio_fsync(struct file *file, loff_t ppos1, loff_t ppos2, int datasync) -{ - struct audio *audio = file->private_data; - int rc = 0; - - if (!audio->running) - return -EINVAL; - - mutex_lock(&audio->write_lock); - - /* PCM DMAMISS message is sent only once in - * hpcm interface. So, wait for buffer complete - * and teos flag. - */ - rc = wait_event_interruptible(audio->wait, - (!audio->out[0].used && - !audio->out[1].used)); - - if (rc < 0) - goto done; - - rc = wait_event_interruptible(audio->wait, - audio->teos); -done: - mutex_unlock(&audio->write_lock); - return rc; -} - -static ssize_t audio_read(struct file *file, char __user *buf, - size_t count, loff_t *pos) -{ - return -EINVAL; -} - -static inline int rt_policy(int policy) -{ - if (unlikely(policy == SCHED_FIFO) || unlikely(policy == SCHED_RR)) - return 1; - return 0; -} - -static inline int task_has_rt_policy(struct task_struct *p) -{ - return rt_policy(p->policy); -} - -static ssize_t audio_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct sched_param s = { .sched_priority = 1 }; - struct audio *audio = file->private_data; - unsigned long flags; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - int old_prio = current->rt_priority; - int old_policy = current->policy; - int cap_nice = cap_raised(current_cap(), CAP_SYS_NICE); - int rc = 0; - - - if ((audio->voice_state == VOICE_STATE_OFFCALL) - && (audio->source & AUDPP_MIXER_UPLINK_RX) && - audio->running) { - MM_ERR("Not Permitted Voice Terminated: state %d source %x \ - running %d\n", - audio->voice_state, audio->source, audio->running); - return -EPERM; - } - /* just for this write, set us real-time */ - if (!task_has_rt_policy(current)) { - struct cred *new = prepare_creds(); - cap_raise(new->cap_effective, CAP_SYS_NICE); - commit_creds(new); - if ((sched_setscheduler(current, SCHED_RR, &s)) < 0) - MM_ERR("sched_setscheduler failed\n"); - } - - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->wait, - (frame->used == 0) || (audio->stopped) || - ((audio->voice_state == VOICE_STATE_OFFCALL) && - (audio->source & AUDPP_MIXER_UPLINK_RX))); - - if (rc < 0) - break; - if (audio->stopped) { - rc = -EBUSY; - break; - } else if ((audio->voice_state == VOICE_STATE_OFFCALL) && - (audio->source & AUDPP_MIXER_UPLINK_RX)) { - MM_ERR("Not Permitted Voice Terminated: %d\n", - audio->voice_state); - rc = -EPERM; - break; - } - - xfer = count > frame->size ? frame->size : count; - if (copy_from_user(frame->data, buf, xfer)) { - rc = -EFAULT; - break; - } - frame->used = xfer; - audio->out_head ^= 1; - count -= xfer; - buf += xfer; - - spin_lock_irqsave(&audio->dsp_lock, flags); - frame = audio->out + audio->out_tail; - if (frame->used && audio->out_needed) { - /* Reset teos flag to avoid stale - * PCMDMAMISS been considered - */ - audio->teos = 0; - audio_dsp_send_buffer(audio, audio->out_tail, - frame->used); - audio->out_tail ^= 1; - audio->out_needed--; - } - spin_unlock_irqrestore(&audio->dsp_lock, flags); - } - - mutex_unlock(&audio->write_lock); - - /* restore scheduling policy and priority */ - if (!rt_policy(old_policy)) { - struct sched_param v = { .sched_priority = old_prio }; - if ((sched_setscheduler(current, old_policy, &v)) < 0) - MM_ERR("sched_setscheduler failed\n"); - if (likely(!cap_nice)) { - struct cred *new = prepare_creds(); - cap_lower(new->cap_effective, CAP_SYS_NICE); - commit_creds(new); - } - } - - if (buf > start) - return buf - start; - return rc; -} - -static int audio_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - auddev_unregister_evt_listner(AUDDEV_CLNT_DEC, audio->dec_id); - audio_disable(audio); - audio_flush(audio); - audio->opened = 0; - mutex_unlock(&audio->lock); - htc_pwrsink_set(PWRSINK_AUDIO, 0); - return 0; -} - -static struct audio the_audio; - -static int audio_open(struct inode *inode, struct file *file) -{ - struct audio *audio = &the_audio; - int rc; - - mutex_lock(&audio->lock); - - if (audio->opened) { - MM_ERR("busy\n"); - rc = -EBUSY; - goto done; - } - - - audio->dec_id = HOSTPCM_STREAM_ID; - - audio->out_buffer_size = BUFSZ; - audio->out_sample_rate = 44100; - audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V; - audio->out_weight = 100; - - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = BUFSZ; - - audio->out[1].data = audio->data + BUFSZ; - audio->out[1].addr = audio->phys + BUFSZ; - audio->out[1].size = BUFSZ; - - audio->vol_pan.volume = 0x2000; - audio->vol_pan.pan = 0x0; - audio->source = 0x0; - - audio_flush(audio); - audio->voice_state = msm_get_voice_state(); - MM_DBG("voice_state = %x\n", audio->voice_state); - audio->device_events = AUDDEV_EVT_DEV_RDY - |AUDDEV_EVT_DEV_RLS| - AUDDEV_EVT_STREAM_VOL_CHG| - AUDDEV_EVT_VOICE_STATE_CHG; - - MM_DBG("register for event callback pdata %p\n", audio); - rc = auddev_register_evt_listner(audio->device_events, - AUDDEV_CLNT_DEC, - audio->dec_id, - audio_out_listener, - (void *)audio); - if (rc) { - MM_ERR("%s: failed to register listener\n", __func__); - goto done; - } - - file->private_data = audio; - audio->opened = 1; - rc = 0; -done: - mutex_unlock(&audio->lock); - return rc; -} - -static const struct file_operations audio_fops = { - .owner = THIS_MODULE, - .open = audio_open, - .release = audio_release, - .read = audio_read, - .write = audio_write, - .unlocked_ioctl = audio_ioctl, - .fsync = audio_fsync, -}; - -struct miscdevice audio_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_pcm_out", - .fops = &audio_fops, -}; - -static int __init audio_init(void) -{ - the_audio.phys = allocate_contiguous_ebi_nomap(DMASZ, SZ_4K); - if (the_audio.phys) { - the_audio.map_v_write = ioremap(the_audio.phys, DMASZ); - if (IS_ERR(the_audio.map_v_write)) { - MM_ERR("could not map physical buffers\n"); - free_contiguous_memory_by_paddr(the_audio.phys); - return -ENOMEM; - } - the_audio.data = the_audio.map_v_write; - } else { - MM_ERR("could not allocate physical buffers\n"); - return -ENOMEM; - } - MM_DBG("Memory addr = 0x%8x phy addr = 0x%8x\n",\ - (int) the_audio.data, (int) the_audio.phys); - mutex_init(&the_audio.lock); - mutex_init(&the_audio.write_lock); - spin_lock_init(&the_audio.dsp_lock); - init_waitqueue_head(&the_audio.wait); - wake_lock_init(&the_audio.wakelock, WAKE_LOCK_SUSPEND, "audio_pcm"); - pm_qos_add_request(&the_audio.pm_qos_req, PM_QOS_CPU_DMA_LATENCY, - PM_QOS_DEFAULT_VALUE); - return misc_register(&audio_misc); -} - -late_initcall(audio_init); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_pcm.c b/arch/arm/mach-msm/qdsp5v2/audio_pcm.c deleted file mode 100644 index ea8fc8312b0072090736d84cbec5f01985b7ff3f..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_pcm.c +++ /dev/null @@ -1,1707 +0,0 @@ -/* arch/arm/mach-msm/qdsp5v2/audio_pcm.c - * - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ADRV_STATUS_AIO_INTF 0x00000001 -#define ADRV_STATUS_OBUF_GIVEN 0x00000002 -#define ADRV_STATUS_IBUF_GIVEN 0x00000004 -#define ADRV_STATUS_FSYNC 0x00000008 - -/* Size must be power of 2 */ -#define BUFSZ_MAX 32768 -#define BUFSZ_MIN 4096 -#define DMASZ_MAX (BUFSZ_MAX * 2) -#define DMASZ_MIN (BUFSZ_MIN * 2) - -#define AUDDEC_DEC_PCM 0 - -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDPCM_EVENT_NUM 10 /* Default number of pre-allocated event packets */ - -#define __CONTAINS(r, v, l) ({ \ - typeof(r) __r = r; \ - typeof(v) __v = v; \ - typeof(v) __e = __v + l; \ - int res = ((__v >= __r->vaddr) && \ - (__e <= __r->vaddr + __r->len)); \ - res; \ -}) - -#define CONTAINS(r1, r2) ({ \ - typeof(r2) __r2 = r2; \ - __CONTAINS(r1, __r2->vaddr, __r2->len); \ -}) - -#define IN_RANGE(r, v) ({ \ - typeof(r) __r = r; \ - typeof(v) __vv = v; \ - int res = ((__vv >= __r->vaddr) && \ - (__vv < (__r->vaddr + __r->len))); \ - res; \ -}) - -#define OVERLAPS(r1, r2) ({ \ - typeof(r1) __r1 = r1; \ - typeof(r2) __r2 = r2; \ - typeof(__r2->vaddr) __v = __r2->vaddr; \ - typeof(__v) __e = __v + __r2->len - 1; \ - int res = (IN_RANGE(__r1, __v) || IN_RANGE(__r1, __e)); \ - res; \ -}) - -struct audio; - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audpcm_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct audpcm_event { - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audpcm_pmem_region { - struct list_head list; - struct file *file; - int fd; - void *vaddr; - unsigned long paddr; - unsigned long kvaddr; - unsigned long len; - unsigned ref_cnt; -}; - -struct audpcm_buffer_node { - struct list_head list; - struct msm_audio_aio_buf buf; - unsigned long paddr; -}; - -struct audpcm_drv_operations { - void (*send_data)(struct audio *, unsigned); - void (*out_flush)(struct audio *); - int (*fsync)(struct audio *); -}; - -struct audio { - struct buffer out[2]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - unsigned out_dma_sz; - struct list_head out_queue; /* queue to retain output buffers */ - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - struct msm_adsp_module *audplay; - - /* configuration to use on next enable */ - uint32_t out_sample_rate; - uint32_t out_channel_mode; - uint32_t out_bits; /* bits per sample */ - - /* data allocated for various buffers */ - char *data; - int32_t phys; - void *map_v_write; - uint32_t drv_status; - int wflush; /* Write flush */ - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - int teos; /* valid only if tunnel mode & no data left for decoder */ - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - int reserved; /* A byte is being reserved */ - char rsv_byte; /* Handle odd length user data */ - - const char *module_name; - unsigned queue_id; - uint32_t device_events; - - unsigned volume; - - uint16_t dec_id; - int16_t source; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audpcm_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - /* AV sync Info */ - int avsync_flag; /* Flag to indicate feedback from DSP */ - wait_queue_head_t avsync_wait;/* Wait queue for AV Sync Message */ - /* flags, 48 bits sample/bytes counter per channel */ - uint16_t avsync[AUDPP_AVSYNC_CH_COUNT * AUDPP_AVSYNC_NUM_WORDS + 1]; - - struct list_head pmem_region_queue; - struct audpcm_drv_operations drv_ops; -}; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audpp_cmd_cfg_adec_params(struct audio *audio); -static void audplay_send_data(struct audio *audio, unsigned needed); -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg); -static void audpcm_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); -static unsigned long audpcm_pmem_fixup(struct audio *audio, void *addr, - unsigned long len, int ref_up); - -static void pcm_listner(u32 evt_id, union auddev_evt_data *evt_payload, - void *private_data) -{ - struct audio *audio = (struct audio *) private_data; - switch (evt_id) { - case AUDDEV_EVT_DEV_RDY: - MM_DBG("AUDDEV_EVT_DEV_RDY\n"); - audio->source |= (0x1 << evt_payload->routing_id); - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - break; - case AUDDEV_EVT_DEV_RLS: - MM_DBG("AUDDEV_EVT_DEV_RLS\n"); - audio->source &= ~(0x1 << evt_payload->routing_id); - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - break; - case AUDDEV_EVT_STREAM_VOL_CHG: - audio->volume = evt_payload->session_vol; - MM_DBG("AUDDEV_EVT_STREAM_VOL_CHG, stream vol %d\n", - audio->volume); - if (audio->running) - audpp_set_volume_and_pan(audio->dec_id, audio->volume, - 0, POPP); - break; - default: - MM_ERR("ERROR:wrong event\n"); - break; - } -} -/* must be called with audio->lock held */ -static int audio_enable(struct audio *audio) -{ - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (audio->enabled) - return 0; - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_tail = 0; - audio->out_needed = 0; - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - return -ENODEV; - } - - audio->enabled = 1; - return 0; -} - -/* must be called with audio->lock held */ -static int audio_disable(struct audio *audio) -{ - int rc = 0; - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - wake_up(&audio->write_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - audio->out_needed = 0; - } - return rc; -} - -/* ------------------- dsp --------------------- */ -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - getevent(msg, sizeof(msg)); - - MM_DBG("msg_id=%x\n", id); - - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audio->drv_ops.send_data(audio, 1); - break; - - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event:module audplaytask\n"); - break; - - default: - MM_ERR("unexpected message from decoder\n"); - break; - } -} - -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status:sleep reason=0x%04x\n", - reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init \n"); - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg \n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play \n"); - audpp_route_stream(audio->dec_id, - audio->source); - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - default: - MM_ERR("unknown decoder status\n"); - break; - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - audpp_set_volume_and_pan(audio->dec_id, audio->volume, - 0, POPP); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audio->running = 0; - } else { - MM_ERR("audio_dsp_event: CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - wake_up(&audio->write_wait); - break; - - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - - case AUDPP_MSG_AVSYNC_MSG: - pr_info("%s: AVSYNC_MSG\n", __func__); - memcpy(&audio->avsync[0], msg, sizeof(audio->avsync)); - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); - break; - - default: - MM_DBG("audio_dsp_event: UNKNOWN (%d)\n", id); - } - -} - - -struct msm_adsp_ops audpcmdec_adsp_ops = { - .event = audplay_dsp_event, -}; - - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id, \ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - struct audpp_cmd_cfg_dec_type cfg_dec_cmd; - - memset(&cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - - cfg_dec_cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE; - if (enable) - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_PCM; - else - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - cfg_dec_cmd.dm_mode = 0x0; - cfg_dec_cmd.stream_id = audio->dec_id; - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} - -static void audpp_cmd_cfg_adec_params(struct audio *audio) -{ - struct audpp_cmd_cfg_adec_params_wav cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_WAV_LEN >> 1; - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = audio->out_sample_rate; - cmd.stereo_cfg = audio->out_channel_mode; - cmd.pcm_width = audio->out_bits; - cmd.sign = 0; - audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static int audplay_dsp_send_data_avail(struct audio *audio, - unsigned idx, unsigned len) -{ - struct audplay_cmd_bitstream_data_avail cmd; - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL; - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = audio->out[idx].addr; - cmd.buf_size = len/2; - cmd.partition_number = 0; - /* complete writes to the input buffer */ - wmb(); - return audplay_send_queue0(audio, &cmd, sizeof(cmd)); -} - -static void audpcm_async_send_data(struct audio *audio, unsigned needed) -{ - unsigned long flags; - - if (!audio->running) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - - if (needed && !audio->wflush) { - audio->out_needed = 1; - if (audio->drv_status & ADRV_STATUS_OBUF_GIVEN) { - /* pop one node out of queue */ - union msm_audio_event_payload payload; - struct audpcm_buffer_node *used_buf; - - MM_DBG("consumed\n"); - - BUG_ON(list_empty(&audio->out_queue)); - used_buf = list_first_entry(&audio->out_queue, - struct audpcm_buffer_node, list); - list_del(&used_buf->list); - payload.aio_buf = used_buf->buf; - audpcm_post_event(audio, AUDIO_EVENT_WRITE_DONE, - payload); - kfree(used_buf); - audio->drv_status &= ~ADRV_STATUS_OBUF_GIVEN; - } - } - if (audio->out_needed) { - struct audpcm_buffer_node *next_buf; - struct audplay_cmd_bitstream_data_avail cmd; - if (!list_empty(&audio->out_queue)) { - next_buf = list_first_entry(&audio->out_queue, - struct audpcm_buffer_node, list); - MM_DBG("next_buf %p\n", next_buf); - if (next_buf) { - MM_DBG("next buf phy %lx len %d\n", - next_buf->paddr, next_buf->buf.data_len); - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL; - if (next_buf->buf.data_len) - cmd.decoder_id = audio->dec_id; - else { - cmd.decoder_id = -1; - MM_DBG("input EOS signaled\n"); - } - cmd.buf_ptr = (unsigned) next_buf->paddr; - cmd.buf_size = next_buf->buf.data_len >> 1; - cmd.partition_number = 0; - /* complete writes to the input buffer */ - wmb(); - audplay_send_queue0(audio, &cmd, sizeof(cmd)); - audio->out_needed = 0; - audio->drv_status |= ADRV_STATUS_OBUF_GIVEN; - } - } - } - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audplay_send_data(struct audio *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - - if (!audio->running) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - MM_DBG("frame %d busy\n", audio->out_tail); - audplay_dsp_send_data_avail(audio, audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ -static void audpcm_async_flush(struct audio *audio) -{ - struct audpcm_buffer_node *buf_node; - struct list_head *ptr, *next; - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - list_for_each_safe(ptr, next, &audio->out_queue) { - buf_node = list_entry(ptr, struct audpcm_buffer_node, list); - list_del(&buf_node->list); - payload.aio_buf = buf_node->buf; - audpcm_post_event(audio, AUDIO_EVENT_WRITE_DONE, - payload); - kfree(buf_node); - } - audio->drv_status &= ~ADRV_STATUS_OBUF_GIVEN; - audio->out_needed = 0; - atomic_set(&audio->out_bytes, 0); -} - -static void audio_flush(struct audio *audio) -{ - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->reserved = 0; - audio->out_needed = 0; - atomic_set(&audio->out_bytes, 0); -} - -static void audio_ioport_reset(struct audio *audio) -{ - if (audio->drv_status & ADRV_STATUS_AIO_INTF) { - /* If fsync is in progress, make sure - * return value of fsync indicates - * abort due to flush - */ - if (audio->drv_status & ADRV_STATUS_FSYNC) { - MM_DBG("fsync in progress\n"); - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audio->drv_ops.out_flush(audio); - mutex_unlock(&audio->write_lock); - } else - audio->drv_ops.out_flush(audio); - } else { - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audio->drv_ops.out_flush(audio); - mutex_unlock(&audio->write_lock); - } - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); -} - -static int audpcm_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audpcm_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audpcm_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audpcm_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audpcm_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - -static long audpcm_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audpcm_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - audio->event_wait, audpcm_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audpcm_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audpcm_event, list); - list_del(&drv_evt->list); - } - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - if (drv_evt && drv_evt->event_type == AUDIO_EVENT_WRITE_DONE) { - mutex_lock(&audio->lock); - audpcm_pmem_fixup(audio, drv_evt->payload.aio_buf.buf_addr, - drv_evt->payload.aio_buf.buf_len, 0); - mutex_unlock(&audio->lock); - } - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audpcm_pmem_check(struct audio *audio, - void *vaddr, unsigned long len) -{ - struct audpcm_pmem_region *region_elt; - struct audpcm_pmem_region t = { .vaddr = vaddr, .len = len }; - - list_for_each_entry(region_elt, &audio->pmem_region_queue, list) { - if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) || - OVERLAPS(region_elt, &t)) { - MM_ERR("region (vaddr %p len %ld)" - " clashes with registered region" - " (vaddr %p paddr %p len %ld)\n", - vaddr, len, - region_elt->vaddr, - (void *)region_elt->paddr, - region_elt->len); - return -EINVAL; - } - } - - return 0; -} - -static int audpcm_pmem_add(struct audio *audio, - struct msm_audio_pmem_info *info) -{ - unsigned long paddr, kvaddr, len; - struct file *file; - struct audpcm_pmem_region *region; - int rc = -EINVAL; - - MM_DBG("\n"); /* Macro prints the file name and function */ - region = kmalloc(sizeof(*region), GFP_KERNEL); - if (!region) - return -ENOMEM; - - if (get_pmem_file(info->fd, &paddr, &kvaddr, &len, &file)) { - kfree(region); - return -EINVAL; - } - - rc = audpcm_pmem_check(audio, info->vaddr, len); - if (rc < 0) { - put_pmem_file(file); - kfree(region); - return rc; - } - - region->vaddr = info->vaddr; - region->fd = info->fd; - region->paddr = paddr; - region->kvaddr = kvaddr; - region->len = len; - region->file = file; - region->ref_cnt = 0; - MM_DBG("add region paddr %lx vaddr %p, len %lu\n", region->paddr, - region->vaddr, region->len); - list_add_tail(®ion->list, &audio->pmem_region_queue); - return rc; -} - -static int audpcm_pmem_remove(struct audio *audio, - struct msm_audio_pmem_info *info) -{ - struct audpcm_pmem_region *region; - struct list_head *ptr, *next; - int rc = -EINVAL; - - MM_DBG("info fd %d vaddr %p\n", info->fd, info->vaddr); - - list_for_each_safe(ptr, next, &audio->pmem_region_queue) { - region = list_entry(ptr, struct audpcm_pmem_region, list); - - if ((region->fd == info->fd) && - (region->vaddr == info->vaddr)) { - if (region->ref_cnt) { - MM_DBG("region %p in use ref_cnt %d\n", region, - region->ref_cnt); - break; - } - MM_DBG("remove region fd %d vaddr %p \n", info->fd, - info->vaddr); - list_del(®ion->list); - put_pmem_file(region->file); - kfree(region); - rc = 0; - break; - } - } - - return rc; -} - -static int audpcm_pmem_lookup_vaddr(struct audio *audio, void *addr, - unsigned long len, struct audpcm_pmem_region **region) -{ - struct audpcm_pmem_region *region_elt; - - int match_count = 0; - - *region = NULL; - - /* returns physical address or zero */ - list_for_each_entry(region_elt, &audio->pmem_region_queue, - list) { - if (addr >= region_elt->vaddr && - addr < region_elt->vaddr + region_elt->len && - addr + len <= region_elt->vaddr + region_elt->len) { - /* offset since we could pass vaddr inside a registerd - * pmem buffer - */ - match_count++; - if (!*region) - *region = region_elt; - } - } - - if (match_count > 1) { - MM_ERR("multiple hits for vaddr %p, len %ld\n", addr, len); - list_for_each_entry(region_elt, - &audio->pmem_region_queue, list) { - if (addr >= region_elt->vaddr && - addr < region_elt->vaddr + region_elt->len && - addr + len <= region_elt->vaddr + region_elt->len) - MM_ERR("\t%p, %ld --> %p\n", - region_elt->vaddr, - region_elt->len, - (void *)region_elt->paddr); - } - } - - return *region ? 0 : -1; -} - -static unsigned long audpcm_pmem_fixup(struct audio *audio, void *addr, - unsigned long len, int ref_up) -{ - struct audpcm_pmem_region *region; - unsigned long paddr; - int ret; - - ret = audpcm_pmem_lookup_vaddr(audio, addr, len, ®ion); - if (ret) { - MM_ERR("lookup (%p, %ld) failed\n", addr, len); - return 0; - } - if (ref_up) - region->ref_cnt++; - else - region->ref_cnt--; - MM_DBG("found region %p ref_cnt %d\n", region, region->ref_cnt); - paddr = region->paddr + (addr - region->vaddr); - return paddr; -} - -/* audio -> lock must be held at this point */ -static int audpcm_aio_buf_add(struct audio *audio, unsigned dir, - void __user *arg) -{ - unsigned long flags; - struct audpcm_buffer_node *buf_node; - - buf_node = kmalloc(sizeof(*buf_node), GFP_KERNEL); - - if (!buf_node) - return -ENOMEM; - - if (copy_from_user(&buf_node->buf, arg, sizeof(buf_node->buf))) { - kfree(buf_node); - return -EFAULT; - } - - MM_DBG("node %p dir %x buf_addr %p buf_len %d data_len %d\n", - buf_node, dir, buf_node->buf.buf_addr, - buf_node->buf.buf_len, buf_node->buf.data_len); - - buf_node->paddr = audpcm_pmem_fixup( - audio, buf_node->buf.buf_addr, - buf_node->buf.buf_len, 1); - if (dir) { - /* write */ - if (!buf_node->paddr || - (buf_node->paddr & 0x1) || - (buf_node->buf.data_len & 0x1) || - (!buf_node->buf.data_len)) { - kfree(buf_node); - return -EINVAL; - } - spin_lock_irqsave(&audio->dsp_lock, flags); - list_add_tail(&buf_node->list, &audio->out_queue); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - audio->drv_ops.send_data(audio, 0); - } - - MM_DBG("Add buf_node %p paddr %lx\n", buf_node, buf_node->paddr); - - return 0; -} - -static int audio_get_avsync_data(struct audio *audio, - struct msm_audio_stats *stats) -{ - int rc = -EINVAL; - unsigned long flags; - - local_irq_save(flags); - if (audio->dec_id == audio->avsync[0] && audio->avsync_flag) { - /* av_sync sample count */ - stats->sample_count = (audio->avsync[2] << 16) | - (audio->avsync[3]); - - /* av_sync byte_count */ - stats->byte_count = (audio->avsync[5] << 16) | - (audio->avsync[6]); - - audio->avsync_flag = 0; - rc = 0; - } - local_irq_restore(flags); - return rc; - -} - -static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = 0; - - MM_DBG("cmd = %d\n", cmd); - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - - audio->avsync_flag = 0; - memset(&stats, 0, sizeof(stats)); - if (audpp_query_avsync(audio->dec_id) < 0) - return rc; - - rc = wait_event_interruptible_timeout(audio->avsync_wait, - (audio->avsync_flag == 1), - msecs_to_jiffies(AUDPP_AVSYNC_EVENT_TIMEOUT)); - - if (rc < 0) - return rc; - else if ((rc > 0) || ((rc == 0) && (audio->avsync_flag == 1))) { - if (audio_get_avsync_data(audio, &stats) < 0) - return rc; - - if (copy_to_user((void *)arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } else - return -EAGAIN; - } - if (cmd == AUDIO_SET_VOLUME) { - unsigned long flags; - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->volume = arg; - if (audio->running) - audpp_set_volume_and_pan(audio->dec_id, arg, 0, - POPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - return 0; - } - if (cmd == AUDIO_GET_EVENT) { - MM_DBG("AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audpcm_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audio_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) - rc = -ENODEV; - else - rc = 0; - } - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audio_disable(audio); - audio->stopped = 1; - audio_ioport_reset(audio); - audio->stopped = 0; - break; - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH\n"); - audio->wflush = 1; - audio_ioport_reset(audio); - if (audio->running) { - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->wflush = 0; - } - break; - - case AUDIO_SET_CONFIG: { - struct msm_audio_config config; - if (copy_from_user(&config, (void *) arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.channel_count == 1) { - config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V; - } else if (config.channel_count == 2) { - config.channel_count = AUDPP_CMD_PCM_INTF_STEREO_V; - } else { - rc = -EINVAL; - break; - } - if (config.bits == 8) - config.bits = AUDPP_CMD_WAV_PCM_WIDTH_8; - else if (config.bits == 16) - config.bits = AUDPP_CMD_WAV_PCM_WIDTH_16; - else if (config.bits == 24) - config.bits = AUDPP_CMD_WAV_PCM_WIDTH_24; - else { - rc = -EINVAL; - break; - } - audio->out_sample_rate = config.sample_rate; - audio->out_channel_mode = config.channel_count; - audio->out_bits = config.bits; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config config; - config.buffer_size = (audio->out_dma_sz >> 1); - config.buffer_count = 2; - config.sample_rate = audio->out_sample_rate; - if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) - config.channel_count = 1; - else - config.channel_count = 2; - if (audio->out_bits == AUDPP_CMD_WAV_PCM_WIDTH_8) - config.bits = 8; - else if (audio->out_bits == AUDPP_CMD_WAV_PCM_WIDTH_24) - config.bits = 24; - else - config.bits = 16; - config.unused[0] = 0; - config.unused[1] = 0; - - if (copy_to_user((void *) arg, &config, sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - - case AUDIO_PAUSE: - MM_DBG("AUDIO_PAUSE %ld\n", arg); - rc = audpp_pause(audio->dec_id, (int) arg); - break; - - case AUDIO_REGISTER_PMEM: { - struct msm_audio_pmem_info info; - MM_DBG("AUDIO_REGISTER_PMEM\n"); - if (copy_from_user(&info, (void *) arg, sizeof(info))) - rc = -EFAULT; - else - rc = audpcm_pmem_add(audio, &info); - break; - } - - case AUDIO_DEREGISTER_PMEM: { - struct msm_audio_pmem_info info; - MM_DBG("AUDIO_DEREGISTER_PMEM\n"); - if (copy_from_user(&info, (void *) arg, sizeof(info))) - rc = -EFAULT; - else - rc = audpcm_pmem_remove(audio, &info); - break; - } - - case AUDIO_ASYNC_WRITE: - if (audio->drv_status & ADRV_STATUS_FSYNC) - rc = -EBUSY; - else - rc = audpcm_aio_buf_add(audio, 1, (void __user *) arg); - break; - - case AUDIO_ASYNC_READ: - MM_ERR("AUDIO_ASYNC_READ not supported\n"); - rc = -EPERM; - break; - - case AUDIO_GET_SESSION_ID: - if (copy_to_user((void *) arg, &audio->dec_id, - sizeof(unsigned short))) - return -EFAULT; - break; - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -int audpcm_async_fsync(struct audio *audio) -{ - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - /* Blocking client sends more data */ - mutex_lock(&audio->lock); - audio->drv_status |= ADRV_STATUS_FSYNC; - mutex_unlock(&audio->lock); - - mutex_lock(&audio->write_lock); - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - (audio->teos && audio->out_needed && - list_empty(&audio->out_queue)) - || audio->wflush || audio->stopped); - - if (audio->stopped || audio->wflush) - rc = -EBUSY; - - mutex_unlock(&audio->write_lock); - mutex_lock(&audio->lock); - audio->drv_status &= ~ADRV_STATUS_FSYNC; - mutex_unlock(&audio->lock); - - return rc; -} - -int audpcm_sync_fsync(struct audio *audio) -{ - struct buffer *frame; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (audio->reserved) { - MM_DBG("send reserved byte\n"); - frame = audio->out + audio->out_tail; - ((char *) frame->data)[0] = audio->rsv_byte; - ((char *) frame->data)[1] = 0; - frame->used = 2; - audio->drv_ops.send_data(audio, 0); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - } - - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush); - - if (audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); - return rc; -} - -int audpcm_fsync(struct file *file, loff_t ppos1, loff_t ppos2, int datasync) -{ - struct audio *audio = file->private_data; - - if (!audio->running) - return -EINVAL; - - return audio->drv_ops.fsync(audio); -} - -static ssize_t audio_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - char *cpy_ptr; - int rc = 0; - unsigned dsize; - - if (audio->drv_status & ADRV_STATUS_AIO_INTF) - return -EPERM; - - MM_DBG("cnt=%d\n", count); - - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - cpy_ptr = frame->data; - dsize = 0; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - break; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - break; - } - - if (audio->reserved) { - MM_DBG("append reserved byte %x\n", audio->rsv_byte); - *cpy_ptr = audio->rsv_byte; - xfer = (count > (frame->size - 1)) ? - frame->size - 1 : count; - cpy_ptr++; - dsize = 1; - audio->reserved = 0; - } else - xfer = (count > frame->size) ? frame->size : count; - - if (copy_from_user(cpy_ptr, buf, xfer)) { - rc = -EFAULT; - break; - } - - dsize += xfer; - if (dsize & 1) { - audio->rsv_byte = ((char *) frame->data)[dsize - 1]; - MM_DBG("odd length buf reserve last byte %x\n", - audio->rsv_byte); - audio->reserved = 1; - dsize--; - } - count -= xfer; - buf += xfer; - - if (dsize > 0) { - audio->out_head ^= 1; - frame->used = dsize; - audio->drv_ops.send_data(audio, 0); - } - } - mutex_unlock(&audio->write_lock); - if (buf > start) - return buf - start; - - return rc; -} - -static void audpcm_reset_pmem_region(struct audio *audio) -{ - struct audpcm_pmem_region *region; - struct list_head *ptr, *next; - - list_for_each_safe(ptr, next, &audio->pmem_region_queue) { - region = list_entry(ptr, struct audpcm_pmem_region, list); - list_del(®ion->list); - put_pmem_file(region->file); - kfree(region); - } - - return; -} - -static int audio_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_INFO("audio instance 0x%08x freeing\n", (int)audio); - - mutex_lock(&audio->lock); - auddev_unregister_evt_listner(AUDDEV_CLNT_DEC, audio->dec_id); - audio_disable(audio); - audio->drv_ops.out_flush(audio); - audpcm_reset_pmem_region(audio); - - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->opened = 0; - audio->event_abort = 1; - wake_up(&audio->event_wait); - audpcm_reset_event_queue(audio); - if (audio->data) { - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - } - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - kfree(audio); - return 0; -} - -static void audpcm_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audpcm_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audpcm_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audpcm_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audpcm_suspend(struct early_suspend *h) -{ - struct audpcm_suspend_ctl *ctl = - container_of(h, struct audpcm_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audpcm_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audpcm_resume(struct early_suspend *h) -{ - struct audpcm_suspend_ctl *ctl = - container_of(h, struct audpcm_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audpcm_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audpcm_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audpcm_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 4096; - static char buffer[4096]; - int n = 0; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_buf_sz %d\n", audio->out[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %x \n", audio->volume); - n += scnprintf(buffer + n, debug_bufmax - n, - "sample rate %d \n", audio->out_sample_rate); - n += scnprintf(buffer + n, debug_bufmax - n, - "channel mode %d \n", audio->out_channel_mode); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d \n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d \n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d \n", audio->out_needed); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_head %d \n", audio->out_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_tail %d \n", audio->out_tail); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[0].used %d \n", audio->out[0].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[1].used %d \n", audio->out[1].used); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audpcm_debug_fops = { - .read = audpcm_debug_read, - .open = audpcm_debug_open, -}; -#endif - -static int audio_open(struct inode *inode, struct file *file) -{ - struct audio *audio = NULL; - int rc, i, dec_attrb, decid; - struct audpcm_event *e_node = NULL; - unsigned pmem_sz = DMASZ_MAX; - -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_pcm_dec_" + 5]; -#endif - - /* Allocate audio instance, set to zero */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("no memory to allocate audio instance \n"); - rc = -ENOMEM; - goto done; - } - MM_INFO("audio instance 0x%08x created\n", (int)audio); - - /* Allocate the decoder */ - dec_attrb = AUDDEC_DEC_PCM; - if (file->f_mode & FMODE_READ) { - MM_ERR("Non-Tunneled mode not supported\n"); - rc = -EPERM; - kfree(audio); - goto done; - } else - dec_attrb |= MSM_AUD_MODE_TUNNEL; - - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - if (decid < 0) { - MM_ERR("No free decoder available, freeing instance 0x%08x\n", - (int)audio); - rc = -ENODEV; - kfree(audio); - goto done; - } - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - /* AIO interface */ - if (file->f_flags & O_NONBLOCK) { - MM_DBG("set to aio interface\n"); - audio->drv_status |= ADRV_STATUS_AIO_INTF; - audio->drv_ops.send_data = audpcm_async_send_data; - audio->drv_ops.out_flush = audpcm_async_flush; - audio->drv_ops.fsync = audpcm_async_fsync; - } else { - MM_DBG("set to std io interface\n"); - while (pmem_sz >= DMASZ_MIN) { - MM_DBG("pmemsz = %d\n", pmem_sz); - audio->phys = allocate_contiguous_ebi_nomap(pmem_sz, - SZ_4K); - if (audio->phys) { - audio->map_v_write = ioremap( - audio->phys, pmem_sz); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write phys\ - address freeing instance \ - 0x%08x\n", (int)audio); - rc = -ENOMEM; - free_contiguous_memory_by_paddr( - audio->phys); - audpp_adec_free(audio->dec_id); - kfree(audio); - goto done; - } - audio->data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x \ - kernel addr 0x%08x\n", - audio->phys, (int)audio->data); - break; - } else if (pmem_sz == DMASZ_MIN) { - MM_ERR("could not allocate write buffers \ - freeing instance 0x%08x\n", (int)audio); - rc = -ENOMEM; - audpp_adec_free(audio->dec_id); - kfree(audio); - goto done; - } else - pmem_sz >>= 1; - } - audio->out_dma_sz = pmem_sz; - audio->drv_ops.send_data = audplay_send_data; - audio->drv_ops.out_flush = audio_flush; - audio->drv_ops.fsync = audpcm_sync_fsync; - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = (audio->out_dma_sz >> 1); - - audio->out[1].data = audio->data + audio->out[0].size; - audio->out[1].addr = audio->phys + audio->out[0].size; - audio->out[1].size = audio->out[0].size; - } - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audpcmdec_adsp_ops, audio); - if (rc) { - MM_ERR("failed to get %s module, freeing instance 0x%08x\n", - audio->module_name, (int)audio); - goto err; - } - - /* Initialize all locks of audio instance */ - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - init_waitqueue_head(&audio->write_wait); - INIT_LIST_HEAD(&audio->out_queue); - INIT_LIST_HEAD(&audio->pmem_region_queue); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - spin_lock_init(&audio->event_queue_lock); - init_waitqueue_head(&audio->avsync_wait); - - audio->out_sample_rate = 44100; - audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V; - audio->out_bits = AUDPP_CMD_WAV_PCM_WIDTH_16; - audio->volume = 0x7FFF; - audio->drv_ops.out_flush(audio); - - file->private_data = audio; - audio->opened = 1; - - audio->device_events = AUDDEV_EVT_DEV_RDY - |AUDDEV_EVT_DEV_RLS| - AUDDEV_EVT_STREAM_VOL_CHG; - - rc = auddev_register_evt_listner(audio->device_events, - AUDDEV_CLNT_DEC, - audio->dec_id, - pcm_listner, - (void *)audio); - if (rc) { - MM_ERR("failed to register listnet\n"); - goto event_err; - } - -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_pcm_dec_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, &audpcm_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_ERR("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audpcm_resume; - audio->suspend_ctl.node.suspend = audpcm_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (i = 0; i < AUDPCM_EVENT_NUM; i++) { - e_node = kmalloc(sizeof(struct audpcm_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } -done: - return rc; -event_err: - msm_adsp_put(audio->audplay); -err: - if (audio->data) { - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - } - audpp_adec_free(audio->dec_id); - kfree(audio); - return rc; -} - -static const struct file_operations audio_pcm_fops = { - .owner = THIS_MODULE, - .open = audio_open, - .release = audio_release, - .write = audio_write, - .unlocked_ioctl = audio_ioctl, - .fsync = audpcm_fsync, -}; - -struct miscdevice audio_pcm_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_pcm_dec", - .fops = &audio_pcm_fops, -}; - -static int __init audio_init(void) -{ - return misc_register(&audio_pcm_misc); -} - -device_initcall(audio_init); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_pcm_in.c b/arch/arm/mach-msm/qdsp5v2/audio_pcm_in.c deleted file mode 100644 index b41995a821e38559f446131d335f9af55ef0601c..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_pcm_in.c +++ /dev/null @@ -1,976 +0,0 @@ -/* - * pcm audio input device - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -/* FRAME_NUM must be a power of two */ -#define FRAME_NUM (8) -#define FRAME_HEADER_SIZE (8) /*4 half words*/ -/* size of a mono frame with 256 samples */ -#define MONO_DATA_SIZE_256 (512) /* in bytes*/ -/*size of a mono frame with 512 samples */ -#define MONO_DATA_SIZE_512 (1024) /* in bytes*/ -/*size of a mono frame with 1024 samples */ -#define MONO_DATA_SIZE_1024 (2048) /* in bytes */ - -/*size of a stereo frame with 256 samples per channel */ -#define STEREO_DATA_SIZE_256 (1024) /* in bytes*/ -/*size of a stereo frame with 512 samples per channel */ -#define STEREO_DATA_SIZE_512 (2048) /* in bytes*/ -/*size of a stereo frame with 1024 samples per channel */ -#define STEREO_DATA_SIZE_1024 (4096) /* in bytes */ - -#define MAX_FRAME_SIZE ((STEREO_DATA_SIZE_1024) + FRAME_HEADER_SIZE) -#define DMASZ (MAX_FRAME_SIZE * FRAME_NUM) - -struct buffer { - void *data; - uint32_t size; - uint32_t read; - uint32_t addr; -}; - -struct audio_in { - struct buffer in[FRAME_NUM]; - - spinlock_t dsp_lock; - - atomic_t in_bytes; - atomic_t in_samples; - - struct mutex lock; - struct mutex read_lock; - wait_queue_head_t wait; - wait_queue_head_t wait_enable; - - struct msm_adsp_module *audrec; - - /* configuration to use on next enable */ - uint32_t samp_rate; - uint32_t channel_mode; - uint32_t buffer_size; /* 2048 for mono, 4096 for stereo */ - uint32_t enc_type; - - uint32_t dsp_cnt; - uint32_t in_head; /* next buffer dsp will write */ - uint32_t in_tail; /* next buffer read() will read */ - uint32_t in_count; /* number of buffers available to read() */ - uint32_t mode; - - const char *module_name; - unsigned queue_ids; - uint16_t enc_id; /* Session Id */ - - uint16_t source; /* Encoding source bit mask */ - uint32_t device_events; /* device events interested in */ - uint32_t in_call; - uint32_t dev_cnt; - int voice_state; - spinlock_t dev_lock; - - struct audrec_session_info session_info; /*audrec session info*/ - /* data allocated for various buffers */ - char *data; - dma_addr_t phys; - void *map_v_read; - - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - int abort; /* set when error, like sample rate mismatch */ - int dual_mic_config; - char *build_id; -}; - -static struct audio_in the_audio_in; - -struct audio_frame { - uint16_t frame_count_lsw; - uint16_t frame_count_msw; - uint16_t frame_length; - uint16_t erased_pcm; - unsigned char raw_bitstream[]; /* samples */ -} __attribute__((packed)); - -/* Audrec Queue command sent macro's */ -#define audrec_send_bitstreamqueue(audio, cmd, len) \ - msm_adsp_write(audio->audrec, ((audio->queue_ids & 0xFFFF0000) >> 16),\ - cmd, len) - -#define audrec_send_audrecqueue(audio, cmd, len) \ - msm_adsp_write(audio->audrec, (audio->queue_ids & 0x0000FFFF),\ - cmd, len) - -/* DSP command send functions */ -static int audpcm_in_enc_config(struct audio_in *audio, int enable); -static int audpcm_in_param_config(struct audio_in *audio); -static int audpcm_in_mem_config(struct audio_in *audio); -static int audpcm_in_record_config(struct audio_in *audio, int enable); -static int audpcm_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt); - -static void audpcm_in_get_dsp_frames(struct audio_in *audio); - -static void audpcm_in_flush(struct audio_in *audio); - -static void pcm_in_listener(u32 evt_id, union auddev_evt_data *evt_payload, - void *private_data) -{ - struct audio_in *audio = (struct audio_in *) private_data; - unsigned long flags; - - MM_DBG("evt_id = 0x%8x\n", evt_id); - switch (evt_id) { - case AUDDEV_EVT_DEV_RDY: { - MM_DBG("AUDDEV_EVT_DEV_RDY\n"); - spin_lock_irqsave(&audio->dev_lock, flags); - audio->dev_cnt++; - if (!audio->in_call) - audio->source |= (0x1 << evt_payload->routing_id); - spin_unlock_irqrestore(&audio->dev_lock, flags); - - if ((audio->running == 1) && (audio->enabled == 1)) - audpcm_in_record_config(audio, 1); - - break; - } - case AUDDEV_EVT_DEV_RLS: { - MM_DBG("AUDDEV_EVT_DEV_RLS\n"); - spin_lock_irqsave(&audio->dev_lock, flags); - audio->dev_cnt--; - if (!audio->in_call) - audio->source &= ~(0x1 << evt_payload->routing_id); - spin_unlock_irqrestore(&audio->dev_lock, flags); - - if (!audio->running || !audio->enabled) - break; - - /* Turn of as per source */ - if (audio->source) - audpcm_in_record_config(audio, 1); - else - /* Turn off all */ - audpcm_in_record_config(audio, 0); - - break; - } - case AUDDEV_EVT_VOICE_STATE_CHG: { - MM_DBG("AUDDEV_EVT_VOICE_STATE_CHG, state = %d\n", - evt_payload->voice_state); - audio->voice_state = evt_payload->voice_state; - if (audio->in_call && audio->running) { - if (audio->voice_state == VOICE_STATE_INCALL) - audpcm_in_record_config(audio, 1); - else if (audio->voice_state == VOICE_STATE_OFFCALL) { - audpcm_in_record_config(audio, 0); - wake_up(&audio->wait); - } - } - break; - } - case AUDDEV_EVT_FREQ_CHG: { - MM_DBG("Encoder Driver got sample rate change event\n"); - MM_DBG("sample rate %d\n", evt_payload->freq_info.sample_rate); - MM_DBG("dev_type %d\n", evt_payload->freq_info.dev_type); - MM_DBG("acdb_dev_id %d\n", evt_payload->freq_info.acdb_dev_id); - if (audio->running == 1) { - /* Stop Recording sample rate does not match - with device sample rate */ - if (evt_payload->freq_info.sample_rate != - audio->samp_rate) { - audpcm_in_record_config(audio, 0); - audio->abort = 1; - wake_up(&audio->wait); - } - } - break; - } - default: - MM_ERR("wrong event %d\n", evt_id); - break; - } -} - -/* ------------------- dsp preproc event handler--------------------- */ -static void audpreproc_dsp_event(void *data, unsigned id, void *msg) -{ - struct audio_in *audio = data; - - switch (id) { - case AUDPREPROC_ERROR_MSG: { - struct audpreproc_err_msg *err_msg = msg; - - MM_ERR("ERROR_MSG: stream id %d err idx %d\n", - err_msg->stream_id, err_msg->aud_preproc_err_idx); - /* Error case */ - wake_up(&audio->wait_enable); - break; - } - case AUDPREPROC_CMD_CFG_DONE_MSG: { - MM_DBG("CMD_CFG_DONE_MSG \n"); - break; - } - case AUDPREPROC_CMD_ENC_CFG_DONE_MSG: { - struct audpreproc_cmd_enc_cfg_done_msg *enc_cfg_msg = msg; - - MM_DBG("CMD_ENC_CFG_DONE_MSG: stream id %d enc type \ - 0x%8x\n", enc_cfg_msg->stream_id, - enc_cfg_msg->rec_enc_type); - /* Encoder enable success */ - if (enc_cfg_msg->rec_enc_type & ENCODE_ENABLE) - audpcm_in_param_config(audio); - else { /* Encoder disable success */ - audio->running = 0; - audpcm_in_record_config(audio, 0); - } - break; - } - case AUDPREPROC_CMD_ENC_PARAM_CFG_DONE_MSG: { - MM_DBG("CMD_ENC_PARAM_CFG_DONE_MSG \n"); - audpcm_in_mem_config(audio); - break; - } - case AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG_DONE_MSG: { - MM_DBG("AFE_CMD_AUDIO_RECORD_CFG_DONE_MSG \n"); - wake_up(&audio->wait_enable); - break; - } - default: - MM_ERR("Unknown Event id %d\n", id); - } -} - -/* ------------------- dsp audrec event handler--------------------- */ -static void audrec_dsp_event(void *data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - struct audio_in *audio = data; - - switch (id) { - case AUDREC_CMD_MEM_CFG_DONE_MSG: { - MM_DBG("CMD_MEM_CFG_DONE MSG DONE\n"); - audio->running = 1; - if ((!audio->in_call && (audio->dev_cnt > 0)) || - (audio->in_call && - (audio->voice_state == VOICE_STATE_INCALL))) - audpcm_in_record_config(audio, 1); - break; - } - case AUDREC_FATAL_ERR_MSG: { - struct audrec_fatal_err_msg fatal_err_msg; - - getevent(&fatal_err_msg, AUDREC_FATAL_ERR_MSG_LEN); - MM_ERR("FATAL_ERR_MSG: err id %d\n", - fatal_err_msg.audrec_err_id); - /* Error stop the encoder */ - audio->stopped = 1; - wake_up(&audio->wait); - break; - } - case AUDREC_UP_PACKET_READY_MSG: { - struct audrec_up_pkt_ready_msg pkt_ready_msg; - - getevent(&pkt_ready_msg, AUDREC_UP_PACKET_READY_MSG_LEN); - MM_DBG("UP_PACKET_READY_MSG: write cnt lsw %d \ - write cnt msw %d read cnt lsw %d read cnt msw %d \n",\ - pkt_ready_msg.audrec_packet_write_cnt_lsw, \ - pkt_ready_msg.audrec_packet_write_cnt_msw, \ - pkt_ready_msg.audrec_up_prev_read_cnt_lsw, \ - pkt_ready_msg.audrec_up_prev_read_cnt_msw); - - audpcm_in_get_dsp_frames(audio); - break; - } - case ADSP_MESSAGE_ID: { - MM_DBG("Received ADSP event :module audrectask\n"); - break; - } - default: - MM_ERR("Unknown Event id %d\n", id); - } -} - -static void audpcm_in_get_dsp_frames(struct audio_in *audio) -{ - struct audio_frame *frame; - uint32_t index; - unsigned long flags; - - index = audio->in_head; - - frame = (void *) (((char *)audio->in[index].data) - \ - sizeof(*frame)); - - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->in[index].size = frame->frame_length; - - /* statistics of read */ - atomic_add(audio->in[index].size, &audio->in_bytes); - atomic_add(1, &audio->in_samples); - - audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1); - - /* If overflow, move the tail index foward. */ - if (audio->in_head == audio->in_tail) - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - else - audio->in_count++; - - audpcm_dsp_read_buffer(audio, audio->dsp_cnt++); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - - wake_up(&audio->wait); -} - -struct msm_adsp_ops audrec_adsp_ops = { - .event = audrec_dsp_event, -}; - -static int audpcm_in_enc_config(struct audio_in *audio, int enable) -{ - struct audpreproc_audrec_cmd_enc_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - if (audio->build_id[17] == '1') { - cmd.cmd_id = AUDPREPROC_AUDREC_CMD_ENC_CFG_2; - MM_ERR("sending AUDPREPROC_AUDREC_CMD_ENC_CFG_2 command"); - } else { - cmd.cmd_id = AUDPREPROC_AUDREC_CMD_ENC_CFG; - MM_ERR("sending AUDPREPROC_AUDREC_CMD_ENC_CFG command"); - } - cmd.stream_id = audio->enc_id; - - if (enable) - cmd.audrec_enc_type = audio->enc_type | ENCODE_ENABLE; - else - cmd.audrec_enc_type &= ~(ENCODE_ENABLE); - - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); -} - -static int audpcm_in_param_config(struct audio_in *audio) -{ - struct audpreproc_audrec_cmd_parm_cfg_wav cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPREPROC_AUDREC_CMD_PARAM_CFG; - cmd.common.stream_id = audio->enc_id; - - cmd.aud_rec_samplerate_idx = audio->samp_rate; - if (audio->dual_mic_config) - cmd.aud_rec_stereo_mode = DUAL_MIC_STEREO_RECORDING; - else - cmd.aud_rec_stereo_mode = audio->channel_mode; - - if (audio->channel_mode == AUDREC_CMD_MODE_MONO) - cmd.aud_rec_frame_size = audio->buffer_size/2; - else - cmd.aud_rec_frame_size = audio->buffer_size/4; - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); -} - -/* To Do: msm_snddev_route_enc(audio->enc_id); */ -static int audpcm_in_record_config(struct audio_in *audio, int enable) -{ - struct audpreproc_afe_cmd_audio_record_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG; - cmd.stream_id = audio->enc_id; - if (enable) - cmd.destination_activity = AUDIO_RECORDING_TURN_ON; - else - cmd.destination_activity = AUDIO_RECORDING_TURN_OFF; - - cmd.source_mix_mask = audio->source; - if (audio->enc_id == 2) { - if ((cmd.source_mix_mask & - INTERNAL_CODEC_TX_SOURCE_MIX_MASK) || - (cmd.source_mix_mask & AUX_CODEC_TX_SOURCE_MIX_MASK) || - (cmd.source_mix_mask & VOICE_UL_SOURCE_MIX_MASK) || - (cmd.source_mix_mask & VOICE_DL_SOURCE_MIX_MASK)) { - cmd.pipe_id = SOURCE_PIPE_1; - } - if (cmd.source_mix_mask & - AUDPP_A2DP_PIPE_SOURCE_MIX_MASK) - cmd.pipe_id |= SOURCE_PIPE_0; - } - - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); -} - -static int audpcm_in_mem_config(struct audio_in *audio) -{ - struct audrec_cmd_arecmem_cfg cmd; - uint16_t *data = (void *) audio->data; - int n; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_MEM_CFG_CMD; - cmd.audrec_up_pkt_intm_count = 1; - cmd.audrec_ext_pkt_start_addr_msw = audio->phys >> 16; - cmd.audrec_ext_pkt_start_addr_lsw = audio->phys; - cmd.audrec_ext_pkt_buf_number = FRAME_NUM; - - /* prepare buffer pointers: - * Mono: 1024 samples + 4 halfword header - * Stereo: 2048 samples + 4 halfword header - */ - for (n = 0; n < FRAME_NUM; n++) { - /* word increment*/ - audio->in[n].data = data + (FRAME_HEADER_SIZE/2); - data += ((FRAME_HEADER_SIZE/2) + (audio->buffer_size/2)); - MM_DBG("0x%8x\n", (int)(audio->in[n].data - FRAME_HEADER_SIZE)); - } - - return audrec_send_audrecqueue(audio, &cmd, sizeof(cmd)); -} - -static int audpcm_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt) -{ - struct up_audrec_packet_ext_ptr cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = UP_AUDREC_PACKET_EXT_PTR; - cmd.audrec_up_curr_read_count_msw = read_cnt >> 16; - cmd.audrec_up_curr_read_count_lsw = read_cnt; - - return audrec_send_bitstreamqueue(audio, &cmd, sizeof(cmd)); -} - -/* must be called with audio->lock held */ -static int audpcm_in_enable(struct audio_in *audio) -{ - if (audio->enabled) - return 0; - - if (audpreproc_enable(audio->enc_id, &audpreproc_dsp_event, audio)) { - MM_ERR("msm_adsp_enable(audpreproc) failed\n"); - return -ENODEV; - } - - if (msm_adsp_enable(audio->audrec)) { - MM_ERR("msm_adsp_enable(audrec) failed\n"); - audpreproc_disable(audio->enc_id, audio); - return -ENODEV; - } - audio->enabled = 1; - audpcm_in_enc_config(audio, 1); - - return 0; -} - -/* must be called with audio->lock held */ -static int audpcm_in_disable(struct audio_in *audio) -{ - if (audio->enabled) { - audio->enabled = 0; - audpcm_in_enc_config(audio, 0); - wake_up(&audio->wait); - wait_event_interruptible_timeout(audio->wait_enable, - audio->running == 0, 1*HZ); - msm_adsp_disable(audio->audrec); - audpreproc_disable(audio->enc_id, audio); - } - return 0; -} - -static void audpcm_in_flush(struct audio_in *audio) -{ - int i; - - audio->dsp_cnt = 0; - audio->in_head = 0; - audio->in_tail = 0; - audio->in_count = 0; - for (i = 0; i < FRAME_NUM; i++) { - audio->in[i].size = 0; - audio->in[i].read = 0; - } - MM_DBG("in_bytes %d\n", atomic_read(&audio->in_bytes)); - MM_DBG("in_samples %d\n", atomic_read(&audio->in_samples)); - atomic_set(&audio->in_bytes, 0); - atomic_set(&audio->in_samples, 0); -} - -/* ------------------- device --------------------- */ -static long audpcm_in_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct audio_in *audio = file->private_data; - int rc = 0; - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = atomic_read(&audio->in_bytes); - stats.sample_count = atomic_read(&audio->in_samples); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return rc; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: { - uint32_t freq; - /* Poll at 48KHz always */ - freq = 48000; - MM_DBG("AUDIO_START\n"); - if (audio->in_call && (audio->voice_state != - VOICE_STATE_INCALL)) { - rc = -EPERM; - break; - } - rc = msm_snddev_request_freq(&freq, audio->enc_id, - SNDDEV_CAP_TX, AUDDEV_CLNT_ENC); - MM_DBG("sample rate configured %d sample rate requested %d\n", - freq, audio->samp_rate); - if (rc < 0) { - MM_DBG("sample rate can not be set, return code %d\n",\ - rc); - msm_snddev_withdraw_freq(audio->enc_id, - SNDDEV_CAP_TX, AUDDEV_CLNT_ENC); - MM_DBG("msm_snddev_withdraw_freq\n"); - break; - } - audio->dual_mic_config = msm_get_dual_mic_config(audio->enc_id); - /*DSP supports fluence block and by default ACDB layer will - applies the fluence pre-processing feature, if dual MIC config - is enabled implies client want to record pure dual MIC sample - for this we need to over ride the fluence pre processing - feature at ACDB layer to not to apply if fluence preprocessing - feature supported*/ - if (audio->dual_mic_config) { - MM_INFO("dual MIC config = %d, over ride the fluence " - "feature\n", audio->dual_mic_config); - fluence_feature_update(audio->dual_mic_config, - audio->enc_id); - } - /*update aurec session info in audpreproc layer*/ - audio->session_info.session_id = audio->enc_id; - audio->session_info.sampling_freq = audio->samp_rate; - audpreproc_update_audrec_info(&audio->session_info); - rc = audpcm_in_enable(audio); - if (!rc) { - rc = - wait_event_interruptible_timeout(audio->wait_enable, - audio->running != 0, 1*HZ); - MM_DBG("state %d rc = %d\n", audio->running, rc); - - if (audio->running == 0) - rc = -ENODEV; - else - rc = 0; - } - audio->stopped = 0; - break; - } - case AUDIO_STOP: { - /*reset the sampling frequency information at audpreproc layer*/ - audio->session_info.sampling_freq = 0; - audpreproc_update_audrec_info(&audio->session_info); - rc = audpcm_in_disable(audio); - rc = msm_snddev_withdraw_freq(audio->enc_id, - SNDDEV_CAP_TX, AUDDEV_CLNT_ENC); - MM_DBG("msm_snddev_withdraw_freq\n"); - audio->stopped = 1; - audio->abort = 0; - break; - } - case AUDIO_FLUSH: { - if (audio->stopped) { - /* Make sure we're stopped and we wake any threads - * that might be blocked holding the read_lock. - * While audio->stopped read threads will always - * exit immediately. - */ - wake_up(&audio->wait); - mutex_lock(&audio->read_lock); - audpcm_in_flush(audio); - mutex_unlock(&audio->read_lock); - } - break; - } - case AUDIO_SET_CONFIG: { - struct msm_audio_config cfg; - if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - if (audio->build_id[17] == '1') { - audio->enc_type = ENC_TYPE_EXT_WAV | audio->mode; - if (cfg.channel_count == 1) { - cfg.channel_count = AUDREC_CMD_MODE_MONO; - if ((cfg.buffer_size == MONO_DATA_SIZE_256) || - (cfg.buffer_size == - MONO_DATA_SIZE_512) || - (cfg.buffer_size == - MONO_DATA_SIZE_1024)) { - audio->buffer_size = cfg.buffer_size; - } else { - rc = -EINVAL; - break; - } - } else if (cfg.channel_count == 2) { - cfg.channel_count = AUDREC_CMD_MODE_STEREO; - if ((cfg.buffer_size == - STEREO_DATA_SIZE_256) || - (cfg.buffer_size == - STEREO_DATA_SIZE_512) || - (cfg.buffer_size == - STEREO_DATA_SIZE_1024)) { - audio->buffer_size = cfg.buffer_size; - } else { - rc = -EINVAL; - break; - } - } else { - rc = -EINVAL; - break; - } - } else if (audio->build_id[17] == '0') { - audio->enc_type = ENC_TYPE_WAV | audio->mode; - if (cfg.channel_count == 1) { - cfg.channel_count = AUDREC_CMD_MODE_MONO; - audio->buffer_size = MONO_DATA_SIZE_1024; - } else if (cfg.channel_count == 2) { - cfg.channel_count = AUDREC_CMD_MODE_STEREO; - audio->buffer_size = STEREO_DATA_SIZE_1024; - } - } else { - MM_ERR("wrong build_id = %s\n", audio->build_id); - return -ENODEV; - } - audio->samp_rate = cfg.sample_rate; - audio->channel_mode = cfg.channel_count; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config cfg; - memset(&cfg, 0, sizeof(cfg)); - cfg.buffer_size = audio->buffer_size; - cfg.buffer_count = FRAME_NUM; - cfg.sample_rate = audio->samp_rate; - if (audio->channel_mode == AUDREC_CMD_MODE_MONO) - cfg.channel_count = 1; - else - cfg.channel_count = 2; - if (copy_to_user((void *) arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - break; - } - case AUDIO_SET_INCALL: { - struct msm_voicerec_mode cfg; - unsigned long flags; - if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - if (cfg.rec_mode != VOC_REC_BOTH && - cfg.rec_mode != VOC_REC_UPLINK && - cfg.rec_mode != VOC_REC_DOWNLINK) { - MM_ERR("invalid rec_mode\n"); - rc = -EINVAL; - break; - } else { - spin_lock_irqsave(&audio->dev_lock, flags); - if (cfg.rec_mode == VOC_REC_UPLINK) - audio->source = VOICE_UL_SOURCE_MIX_MASK; - else if (cfg.rec_mode == VOC_REC_DOWNLINK) - audio->source = VOICE_DL_SOURCE_MIX_MASK; - else - audio->source = VOICE_DL_SOURCE_MIX_MASK | - VOICE_UL_SOURCE_MIX_MASK ; - audio->in_call = 1; - spin_unlock_irqrestore(&audio->dev_lock, flags); - } - break; - } - case AUDIO_GET_SESSION_ID: { - if (copy_to_user((void *) arg, &audio->enc_id, - sizeof(unsigned short))) { - rc = -EFAULT; - } - break; - } - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -static ssize_t audpcm_in_read(struct file *file, - char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_in *audio = file->private_data; - unsigned long flags; - const char __user *start = buf; - void *data; - uint32_t index; - uint32_t size; - int rc = 0; - - mutex_lock(&audio->read_lock); - while (count > 0) { - rc = wait_event_interruptible( - audio->wait, (audio->in_count > 0) || audio->stopped || - audio->abort || (audio->in_call && audio->running && - (audio->voice_state == VOICE_STATE_OFFCALL))); - if (rc < 0) - break; - - if (!audio->in_count) { - if (audio->stopped) { - MM_DBG("Driver in stop state, No more \ - buffer to read"); - rc = 0;/* End of File */ - break; - } else if (audio->in_call && audio->running && - (audio->voice_state == VOICE_STATE_OFFCALL)) { - MM_DBG("Not Permitted Voice Terminated\n"); - rc = -EPERM; /* Voice Call stopped */ - break; - } - } - - if (audio->abort) { - rc = -EPERM; /* Not permitted due to abort */ - break; - } - - index = audio->in_tail; - data = (uint8_t *) audio->in[index].data; - size = audio->in[index].size; - if (count >= size) { - if (copy_to_user(buf, data, size)) { - rc = -EFAULT; - break; - } - spin_lock_irqsave(&audio->dsp_lock, flags); - if (index != audio->in_tail) { - /* overrun -- data is - * invalid and we need to retry */ - spin_unlock_irqrestore(&audio->dsp_lock, flags); - continue; - } - audio->in[index].size = 0; - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - audio->in_count--; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - count -= size; - buf += size; - } else { - MM_ERR("short read count %d\n", count); - break; - } - } - mutex_unlock(&audio->read_lock); - - if (buf > start) - return buf - start; - - return rc; -} - -static ssize_t audpcm_in_write(struct file *file, - const char __user *buf, - size_t count, loff_t *pos) -{ - return -EINVAL; -} - -static int audpcm_in_release(struct inode *inode, struct file *file) -{ - struct audio_in *audio = file->private_data; - - mutex_lock(&audio->lock); - audio->in_call = 0; - /* with draw frequency for session - incase not stopped the driver */ - msm_snddev_withdraw_freq(audio->enc_id, SNDDEV_CAP_TX, - AUDDEV_CLNT_ENC); - auddev_unregister_evt_listner(AUDDEV_CLNT_ENC, audio->enc_id); - /*reset the sampling frequency information at audpreproc layer*/ - audio->session_info.sampling_freq = 0; - audpreproc_update_audrec_info(&audio->session_info); - audpcm_in_disable(audio); - audpcm_in_flush(audio); - msm_adsp_put(audio->audrec); - audpreproc_aenc_free(audio->enc_id); - audio->audrec = NULL; - audio->opened = 0; - if (audio->data) { - iounmap(audio->map_v_read); - free_contiguous_memory_by_paddr(audio->phys); - audio->data = NULL; - } - mutex_unlock(&audio->lock); - return 0; -} - -static int audpcm_in_open(struct inode *inode, struct file *file) -{ - struct audio_in *audio = &the_audio_in; - int rc; - int encid; - - mutex_lock(&audio->lock); - if (audio->opened) { - rc = -EBUSY; - goto done; - } - audio->phys = allocate_contiguous_ebi_nomap(DMASZ, SZ_4K); - if (audio->phys) { - audio->map_v_read = ioremap(audio->phys, DMASZ); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("could not map read phys buffers\n"); - rc = -ENOMEM; - free_contiguous_memory_by_paddr(audio->phys); - goto done; - } - audio->data = audio->map_v_read; - } else { - MM_ERR("could not allocate read buffers\n"); - rc = -ENOMEM; - goto done; - } - MM_DBG("Memory addr = 0x%8x phy addr = 0x%8x\n",\ - (int) audio->data, (int) audio->phys); - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - rc = -EACCES; - MM_ERR("Non tunnel encoding is not supported\n"); - goto done; - } else if (!(file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - audio->mode = MSM_AUD_ENC_MODE_TUNNEL; - MM_DBG("Opened for tunnel mode encoding\n"); - } else { - rc = -EACCES; - goto done; - } - /* Settings will be re-config at AUDIO_SET_CONFIG, - * but at least we need to have initial config - */ - audio->channel_mode = AUDREC_CMD_MODE_MONO; - audio->buffer_size = MONO_DATA_SIZE_1024; - audio->samp_rate = 8000; - audio->enc_type = ENC_TYPE_EXT_WAV | audio->mode; - - encid = audpreproc_aenc_alloc(audio->enc_type, &audio->module_name, - &audio->queue_ids); - if (encid < 0) { - MM_ERR("No free encoder available\n"); - rc = -ENODEV; - goto done; - } - audio->enc_id = encid; - - rc = msm_adsp_get(audio->module_name, &audio->audrec, - &audrec_adsp_ops, audio); - - if (rc) { - audpreproc_aenc_free(audio->enc_id); - goto done; - } - - audio->stopped = 0; - audio->source = 0; - audio->abort = 0; - audpcm_in_flush(audio); - audio->device_events = AUDDEV_EVT_DEV_RDY | AUDDEV_EVT_DEV_RLS | - AUDDEV_EVT_FREQ_CHG | - AUDDEV_EVT_VOICE_STATE_CHG; - - audio->voice_state = msm_get_voice_state(); - rc = auddev_register_evt_listner(audio->device_events, - AUDDEV_CLNT_ENC, audio->enc_id, - pcm_in_listener, (void *) audio); - if (rc) { - MM_ERR("failed to register device event listener\n"); - goto evt_error; - } - file->private_data = audio; - audio->opened = 1; - rc = 0; - audio->build_id = socinfo_get_build_id(); - MM_DBG("Modem build id = %s\n", audio->build_id); -done: - mutex_unlock(&audio->lock); - return rc; -evt_error: - msm_adsp_put(audio->audrec); - audpreproc_aenc_free(audio->enc_id); - mutex_unlock(&audio->lock); - return rc; -} - -static const struct file_operations audio_in_fops = { - .owner = THIS_MODULE, - .open = audpcm_in_open, - .release = audpcm_in_release, - .read = audpcm_in_read, - .write = audpcm_in_write, - .unlocked_ioctl = audpcm_in_ioctl, -}; - -struct miscdevice audio_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_pcm_in", - .fops = &audio_in_fops, -}; - -static int __init audpcm_in_init(void) -{ - mutex_init(&the_audio_in.lock); - mutex_init(&the_audio_in.read_lock); - spin_lock_init(&the_audio_in.dsp_lock); - spin_lock_init(&the_audio_in.dev_lock); - init_waitqueue_head(&the_audio_in.wait); - init_waitqueue_head(&the_audio_in.wait_enable); - return misc_register(&audio_in_misc); -} - -device_initcall(audpcm_in_init); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c b/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c deleted file mode 100644 index bb360be75777d17a9a3bbe660e5153b57360dbde..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c +++ /dev/null @@ -1,1639 +0,0 @@ -/* - * qcelp 13k audio decoder device - * - * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved. - * - * This code is based in part on audio_mp3.c, which is - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org. - * - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define BUFSZ 1094 /* QCELP 13K Hold 600ms packet data = 36 * 30 and - 14 bytes of meta in */ -#define BUF_COUNT 2 -#define DMASZ (BUFSZ * BUF_COUNT) - -#define PCM_BUFSZ_MIN 1624 /* 100ms worth of data and - 24 bytes of meta out */ -#define PCM_BUF_MAX_COUNT 5 - -#define AUDDEC_DEC_QCELP 9 - -#define ROUTING_MODE_FTRT 1 -#define ROUTING_MODE_RT 2 -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDQCELP_METAFIELD_MASK 0xFFFF0000 -#define AUDQCELP_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */ -#define AUDQCELP_EOS_FLG_MASK 0x01 -#define AUDQCELP_EOS_NONE 0x0 /* No EOS detected */ -#define AUDQCELP_EOS_SET 0x1 /* EOS set in meta field */ - -#define AUDQCELP_EVENT_NUM 10 /* Default number of pre-allocated event pkts */ - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; - unsigned short mfield_sz; /*only useful for data has meta field */ -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audqcelp_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct audqcelp_event{ - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audio { - struct buffer out[BUF_COUNT]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - /* Host PCM section - START */ - struct buffer in[PCM_BUF_MAX_COUNT]; - struct mutex read_lock; - wait_queue_head_t read_wait; /* Wait queue for read */ - char *read_data; /* pointer to reader buffer */ - int32_t read_phys; /* physical address of reader buffer */ - uint8_t read_next; /* index to input buffers to be read next */ - uint8_t fill_next; /* index to buffer that DSP should be filling */ - uint8_t pcm_buf_count; /* number of pcm buffer allocated */ - /* Host PCM section - END */ - - struct msm_adsp_module *audplay; - - /* data allocated for various buffers */ - char *data; - int32_t phys; /* physical address of write buffer */ - void *map_v_read; - void *map_v_write; - - int mfield; /* meta field embedded in data */ - int rflush; /* Read flush */ - int wflush; /* Write flush */ - uint8_t opened:1; - uint8_t enabled:1; - uint8_t running:1; - uint8_t stopped:1; /* set when stopped, cleared on flush */ - uint8_t pcm_feedback:1; /* set when non-tunnel mode */ - uint8_t buf_refresh:1; - int teos; /* valid only if tunnel mode & no data left for decoder */ - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - - const char *module_name; - unsigned queue_id; - uint16_t dec_id; - int16_t source; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audqcelp_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - /* AV sync Info */ - int avsync_flag; /* Flag to indicate feedback from DSP */ - wait_queue_head_t avsync_wait;/* Wait queue for AV Sync Message */ - /* flags, 48 bits sample/bytes counter per channel */ - uint16_t avsync[AUDPP_AVSYNC_CH_COUNT * AUDPP_AVSYNC_NUM_WORDS + 1]; - - uint32_t device_events; - - int eq_enable; - int eq_needs_commit; - struct audpp_cmd_cfg_object_params_eqalizer eq; - struct audpp_cmd_cfg_object_params_volume vol_pan; -}; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audpp_cmd_cfg_adec_params(struct audio *audio); -static void audpp_cmd_cfg_routing_mode(struct audio *audio); -static void audqcelp_send_data(struct audio *audio, unsigned needed); -static void audqcelp_config_hostpcm(struct audio *audio); -static void audqcelp_buffer_refresh(struct audio *audio); -static void audqcelp_dsp_event(void *private, unsigned id, uint16_t *msg); -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audqcelp_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); -#endif - -/* must be called with audio->lock held */ -static int audqcelp_enable(struct audio *audio) -{ - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) - return 0; - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_tail = 0; - audio->out_needed = 0; - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audqcelp_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - return -ENODEV; - } - audio->enabled = 1; - return 0; -} - -static void qcelp_listner(u32 evt_id, union auddev_evt_data *evt_payload, - void *private_data) -{ - struct audio *audio = (struct audio *) private_data; - switch (evt_id) { - case AUDDEV_EVT_DEV_RDY: - MM_DBG(":AUDDEV_EVT_DEV_RDY\n"); - audio->source |= (0x1 << evt_payload->routing_id); - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - break; - case AUDDEV_EVT_DEV_RLS: - MM_DBG(":AUDDEV_EVT_DEV_RLS\n"); - audio->source &= ~(0x1 << evt_payload->routing_id); - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - break; - case AUDDEV_EVT_STREAM_VOL_CHG: - audio->vol_pan.volume = evt_payload->session_vol; - MM_DBG(":AUDDEV_EVT_STREAM_VOL_CHG, stream vol %d\n", - audio->vol_pan.volume); - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - break; - default: - MM_ERR(":ERROR:wrong event\n"); - break; - } -} -/* must be called with audio->lock held */ -static int audqcelp_disable(struct audio *audio) -{ - int rc = 0; - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - wake_up(&audio->write_wait); - wake_up(&audio->read_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - audio->out_needed = 0; - } - return rc; -} - -/* ------------------- dsp --------------------- */ -static void audqcelp_update_pcm_buf_entry(struct audio *audio, - uint32_t *payload) -{ - uint8_t index; - unsigned long flags; - - if (audio->rflush) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < payload[1]; index++) { - if (audio->in[audio->fill_next].addr == - payload[2 + index * 2]) { - MM_DBG("in[%d] ready\n", audio->fill_next); - audio->in[audio->fill_next].used = - payload[3 + index * 2]; - if ((++audio->fill_next) == audio->pcm_buf_count) - audio->fill_next = 0; - } else { - MM_ERR("expected=%x ret=%x\n", - audio->in[audio->fill_next].addr, - payload[1 + index * 2]); - break; - } - } - if (audio->in[audio->fill_next].used == 0) { - audqcelp_buffer_refresh(audio); - } else { - MM_DBG("read cannot keep up\n"); - audio->buf_refresh = 1; - } - wake_up(&audio->read_wait); - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - getevent(msg, sizeof(msg)); - - MM_DBG("msg_id=%x\n", id); - - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audqcelp_send_data(audio, 1); - break; - - case AUDPLAY_MSG_BUFFER_UPDATE: - audqcelp_update_pcm_buf_entry(audio, msg); - break; - - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audplaytask)\n"); - break; - - default: - MM_ERR("unexpected message from decoder \n"); - } -} - -static void audqcelp_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status:sleep reason = \ - 0x%04x\n", reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init \n"); - if (audio->pcm_feedback) - audpp_cmd_cfg_routing_mode(audio); - else - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg \n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play \n"); - /* send mixer command */ - audpp_route_stream(audio->dec_id, - audio->source); - if (audio->pcm_feedback) { - audqcelp_config_hostpcm(audio); - audqcelp_buffer_refresh(audio); - } - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - default: - MM_ERR("unknown decoder status\n"); - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - audpp_dsp_set_eq(audio->dec_id, audio->eq_enable, - &audio->eq, POPP); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audio->running = 0; - } else { - MM_DBG("CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_ROUTING_ACK: - MM_DBG("ROUTING_ACK mode=%d\n", msg[1]); - audpp_cmd_cfg_adec_params(audio); - break; - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - audio->rflush = 0; - wake_up(&audio->write_wait); - if (audio->pcm_feedback) - audqcelp_buffer_refresh(audio); - break; - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - - case AUDPP_MSG_AVSYNC_MSG: - MM_DBG("AUDPP_MSG_AVSYNC_MSG\n"); - memcpy(&audio->avsync[0], msg, sizeof(audio->avsync)); - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); - break; - - default: - MM_ERR("UNKNOWN (%d)\n", id); - } - -} - -struct msm_adsp_ops audplay_adsp_ops_qcelp = { - .event = audplay_dsp_event, -}; - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id, \ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - struct audpp_cmd_cfg_dec_type cfg_dec_cmd; - - memset(&cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - - cfg_dec_cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE; - if (enable) - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_QCELP; - else - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - cfg_dec_cmd.dm_mode = 0x0; - cfg_dec_cmd.stream_id = audio->dec_id; - - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} - -static void audpp_cmd_cfg_adec_params(struct audio *audio) -{ - struct audpp_cmd_cfg_adec_params_v13k cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN; - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = 8000; - cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V; - - audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static void audpp_cmd_cfg_routing_mode(struct audio *audio) -{ - struct audpp_cmd_routing_mode cmd; - MM_DBG("\n"); /* Macro prints the file name and function */ - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; - cmd.object_number = audio->dec_id; - if (audio->pcm_feedback) - cmd.routing_mode = ROUTING_MODE_FTRT; - else - cmd.routing_mode = ROUTING_MODE_RT; - audpp_send_queue1(&cmd, sizeof(cmd)); -} - -static int audplay_dsp_send_data_avail(struct audio *audio, - unsigned idx, unsigned len) -{ - struct audplay_cmd_bitstream_data_avail_nt2 cmd; - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2; - if (audio->mfield) - cmd.decoder_id = AUDQCELP_METAFIELD_MASK | - (audio->out[idx].mfield_sz >> 1); - else - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = audio->out[idx].addr; - cmd.buf_size = len / 2; - cmd.partition_number = 0; - return audplay_send_queue0(audio, &cmd, sizeof(cmd)); -} - -static void audqcelp_buffer_refresh(struct audio *audio) -{ - struct audplay_cmd_buffer_refresh refresh_cmd; - - refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; - refresh_cmd.num_buffers = 1; - refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; - refresh_cmd.buf0_length = audio->in[audio->fill_next].size; - refresh_cmd.buf_read_count = 0; - MM_DBG("buf0_addr=%x buf0_len=%d\n", refresh_cmd.buf0_address, - refresh_cmd.buf0_length); - - (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); -} - -static void audqcelp_config_hostpcm(struct audio *audio) -{ - struct audplay_cmd_hpcm_buf_cfg cfg_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; - cfg_cmd.max_buffers = 1; - cfg_cmd.byte_swap = 0; - cfg_cmd.hostpcm_config = (0x8000) | (0x4000); - cfg_cmd.feedback_frequency = 1; - cfg_cmd.partition_number = 0; - - (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); -} - -static void audqcelp_send_data(struct audio *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - MM_DBG("frame %d busy\n", audio->out_tail); - audplay_dsp_send_data_avail(audio, audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } - done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ - -static void audqcelp_flush(struct audio *audio) -{ - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->out_needed = 0; -} - -static void audqcelp_flush_pcm_buf(struct audio *audio) -{ - uint8_t index; - - for (index = 0; index < PCM_BUF_MAX_COUNT; index++) - audio->in[index].used = 0; - - audio->buf_refresh = 0; - audio->read_next = 0; - audio->fill_next = 0; -} - -static void audqcelp_ioport_reset(struct audio *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audqcelp_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->read_wait); - mutex_lock(&audio->read_lock); - audqcelp_flush_pcm_buf(audio); - mutex_unlock(&audio->read_lock); - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); -} - -static int audqcelp_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audqcelp_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audqcelp_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audqcelp_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audqcelp_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - - -static long audqcelp_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audqcelp_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - audio->event_wait, audqcelp_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audqcelp_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - rc = 0; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audqcelp_event, list); - list_del(&drv_evt->list); - } - - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audio_enable_eq(struct audio *audio, int enable) -{ - if (audio->eq_enable == enable && !audio->eq_needs_commit) - return 0; - - audio->eq_enable = enable; - - if (audio->running) { - audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq, POPP); - audio->eq_needs_commit = 0; - } - return 0; -} - -static int audio_get_avsync_data(struct audio *audio, - struct msm_audio_stats *stats) -{ - int rc = -EINVAL; - unsigned long flags; - - local_irq_save(flags); - if (audio->dec_id == audio->avsync[0] && audio->avsync_flag) { - /* av_sync sample count */ - stats->sample_count = (audio->avsync[2] << 16) | - (audio->avsync[3]); - - /* av_sync byte_count */ - stats->byte_count = (audio->avsync[5] << 16) | - (audio->avsync[6]); - - audio->avsync_flag = 0; - rc = 0; - } - local_irq_restore(flags); - return rc; - -} - -static long audqcelp_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - unsigned long flags = 0; - uint16_t enable_mask; - int enable; - int prev_state; - - MM_DBG("cmd = %d\n", cmd); - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - - audio->avsync_flag = 0; - memset(&stats, 0, sizeof(stats)); - if (audpp_query_avsync(audio->dec_id) < 0) - return rc; - - rc = wait_event_interruptible_timeout(audio->avsync_wait, - (audio->avsync_flag == 1), - msecs_to_jiffies(AUDPP_AVSYNC_EVENT_TIMEOUT)); - - if (rc < 0) - return rc; - else if ((rc > 0) || ((rc == 0) && (audio->avsync_flag == 1))) { - if (audio_get_avsync_data(audio, &stats) < 0) - return rc; - - if (copy_to_user((void *)arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } else - return -EAGAIN; - } - - switch (cmd) { - case AUDIO_ENABLE_AUDPP: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - spin_lock_irqsave(&audio->dsp_lock, flags); - enable = (enable_mask & EQ_ENABLE) ? 1 : 0; - audio_enable_eq(audio, enable); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - case AUDIO_SET_VOLUME: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.volume = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_PAN: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.pan = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_EQ: - prev_state = audio->eq_enable; - audio->eq_enable = 0; - if (copy_from_user(&audio->eq.num_bands, (void *) arg, - sizeof(audio->eq) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) { - rc = -EFAULT; - break; - } - audio->eq_enable = prev_state; - audio->eq_needs_commit = 1; - rc = 0; - break; - } - - if (-EINVAL != rc) - return rc; - - if (cmd == AUDIO_GET_EVENT) { - MM_DBG("AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audqcelp_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audqcelp_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) - rc = -ENODEV; - else - rc = 0; - } - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audqcelp_disable(audio); - audio->stopped = 1; - audqcelp_ioport_reset(audio); - audio->stopped = 0; - break; - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audqcelp_ioport_reset(audio); - if (audio->running) { - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - case AUDIO_SET_CONFIG:{ - struct msm_audio_config config; - if (copy_from_user(&config, (void *)arg, - sizeof(config))) { - rc = -EFAULT; - break; - } - audio->mfield = config.meta_field; - MM_DBG("AUDIO_SET_CONFIG applicable \ - for metafield configuration\n"); - rc = 0; - break; - } - case AUDIO_GET_CONFIG:{ - struct msm_audio_config config; - config.buffer_size = BUFSZ; - config.buffer_count = BUF_COUNT; - config.sample_rate = 8000; - config.channel_count = 1; - config.meta_field = 0; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - - break; - } - case AUDIO_GET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - - config.pcm_feedback = audio->pcm_feedback; - config.buffer_count = PCM_BUF_MAX_COUNT; - config.buffer_size = PCM_BUFSZ_MIN; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - - if (copy_from_user(&config, (void *)arg, - sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.pcm_feedback != audio->pcm_feedback) { - MM_ERR("Not sufficient permission to" - "change the playback mode\n"); - rc = -EACCES; - break; - } - if ((config.buffer_count > PCM_BUF_MAX_COUNT) || - (config.buffer_count == 1)) - config.buffer_count = PCM_BUF_MAX_COUNT; - - if (config.buffer_size < PCM_BUFSZ_MIN) - config.buffer_size = PCM_BUFSZ_MIN; - - /* Check if pcm feedback is required */ - if ((config.pcm_feedback) && (!audio->read_data)) { - MM_DBG("allocate PCM buf %d\n", - config.buffer_count * config.buffer_size); - audio->read_phys = - allocate_contiguous_ebi_nomap( - config.buffer_size * - config.buffer_count, - SZ_4K); - if (!audio->read_phys) { - rc = -ENOMEM; - break; - } - audio->map_v_read = ioremap( - audio->read_phys, - config.buffer_size * - config.buffer_count); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("failed to map read buf\n"); - rc = -ENOMEM; - free_contiguous_memory_by_paddr( - audio->read_phys); - } else { - uint8_t index; - uint32_t offset = 0; - audio->read_data = - audio->map_v_read; - audio->buf_refresh = 0; - audio->pcm_buf_count = - config.buffer_count; - audio->read_next = 0; - audio->fill_next = 0; - - for (index = 0; - index < config.buffer_count; index++) { - audio->in[index].data = - audio->read_data + offset; - audio->in[index].addr = - audio->read_phys + offset; - audio->in[index].size = - config.buffer_size; - audio->in[index].used = 0; - offset += config.buffer_size; - } - MM_DBG("read buf: phy addr 0x%08x \ - kernel addr 0x%08x\n", - audio->read_phys, - (int)audio->read_data); - rc = 0; - } - } else { - rc = 0; - } - break; - } - case AUDIO_PAUSE: - MM_DBG("AUDIO_PAUSE %ld\n", arg); - rc = audpp_pause(audio->dec_id, (int) arg); - break; - case AUDIO_GET_SESSION_ID: - if (copy_to_user((void *) arg, &audio->dec_id, - sizeof(unsigned short))) - rc = -EFAULT; - else - rc = 0; - break; - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -static int audqcelp_fsync(struct file *file, loff_t ppos1, loff_t ppos2, int datasync) -{ - struct audio *audio = file->private_data; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - if (!audio->running || audio->pcm_feedback) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush); - - if (audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; -} - -static ssize_t audqcelp_read(struct file *file, char __user *buf, size_t count, - loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - int rc = 0; - - if (!audio->pcm_feedback) - return 0; /* PCM feedback is not enabled. Nothing to read */ - - mutex_lock(&audio->read_lock); - MM_DBG("%d\n", count); - while (count > 0) { - rc = wait_event_interruptible(audio->read_wait, - (audio->in[audio->read_next].used > 0) || - (audio->stopped) || (audio->rflush)); - if (rc < 0) - break; - - if (audio->stopped || audio->rflush) { - rc = -EBUSY; - break; - } - - if (count < audio->in[audio->read_next].used) { - /* Read must happen in frame boundary. Since driver does - not know frame size, read count must be greater or equal - to size of PCM samples */ - MM_DBG("read stop - partial frame\n"); - break; - } else { - MM_DBG("read from in[%d]\n", audio->read_next); - - if (copy_to_user(buf, - audio->in[audio->read_next].data, - audio->in[audio->read_next].used)) { - MM_ERR("invalid addr %x\n", (unsigned int)buf); - rc = -EFAULT; - break; - } - count -= audio->in[audio->read_next].used; - buf += audio->in[audio->read_next].used; - audio->in[audio->read_next].used = 0; - if ((++audio->read_next) == audio->pcm_buf_count) - audio->read_next = 0; - break; - /* Force to exit while loop - * to prevent output thread - * sleep too long if data is - * not ready at this moment. - */ - } - } - - /* don't feed output buffer to HW decoder during flushing - * buffer refresh command will be sent once flush completes - * send buf refresh command here can confuse HW decoder - */ - if (audio->buf_refresh && !audio->rflush) { - audio->buf_refresh = 0; - MM_DBG("kick start pcm feedback again\n"); - audqcelp_buffer_refresh(audio); - } - - mutex_unlock(&audio->read_lock); - - if (buf > start) - rc = buf - start; - - MM_DBG("read %d bytes\n", rc); - return rc; -} - -static int audqcelp_process_eos(struct audio *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - struct buffer *frame; - int rc = 0; - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - audqcelp_send_data(audio, 0); - -done: - return rc; -} - -static ssize_t audqcelp_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - char *cpy_ptr; - int rc = 0, eos_condition = AUDQCELP_EOS_NONE; - unsigned short mfield_size = 0; - - MM_DBG("cnt=%d\n", count); - - if (count & 1) - return -EINVAL; - - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - cpy_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - MM_DBG("buffer available\n"); - if (rc < 0) - break; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - break; - } - - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - break; - } else if (mfield_size > count) { - rc = -EINVAL; - break; - } - MM_DBG("mf offset_val %x\n", mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - break; - } - /* Check if EOS flag is set and buffer has - * contains just meta field - */ - if (cpy_ptr[AUDQCELP_EOS_FLG_OFFSET] & - AUDQCELP_EOS_FLG_MASK) { - MM_DBG("EOS SET\n"); - eos_condition = AUDQCELP_EOS_SET; - if (mfield_size == count) { - buf += mfield_size; - break; - } else - cpy_ptr[AUDQCELP_EOS_FLG_OFFSET] &= - ~AUDQCELP_EOS_FLG_MASK; - } - cpy_ptr += mfield_size; - count -= mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - - xfer = (count > (frame->size - mfield_size)) ? - (frame->size - mfield_size) : count; - if (copy_from_user(cpy_ptr, buf, xfer)) { - rc = -EFAULT; - break; - } - - frame->used = xfer + mfield_size; - audio->out_head ^= 1; - count -= xfer; - buf += xfer; - audqcelp_send_data(audio, 0); - } - if (eos_condition == AUDQCELP_EOS_SET) - rc = audqcelp_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - if (!rc) { - if (buf > start) - return buf - start; - } - return rc; -} - -static int audqcelp_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_INFO("audio instance 0x%08x freeing\n", (int) audio); - mutex_lock(&audio->lock); - auddev_unregister_evt_listner(AUDDEV_CLNT_DEC, audio->dec_id); - audqcelp_disable(audio); - audqcelp_flush(audio); - audqcelp_flush_pcm_buf(audio); - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->opened = 0; - audio->event_abort = 1; - wake_up(&audio->event_wait); - audqcelp_reset_event_queue(audio); - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - if (audio->read_data) { - iounmap(audio->map_v_read); - free_contiguous_memory_by_paddr(audio->read_phys); - } - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - kfree(audio); - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audqcelp_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audqcelp_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audqcelp_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audqcelp_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -static void audqcelp_suspend(struct early_suspend *h) -{ - struct audqcelp_suspend_ctl *ctl = - container_of(h, struct audqcelp_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audqcelp_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audqcelp_resume(struct early_suspend *h) -{ - struct audqcelp_suspend_ctl *ctl = - container_of(h, struct audqcelp_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audqcelp_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audqcelp_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audqcelp_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 1024; - static char buffer[1024]; - int n = 0, i; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_feedback %d\n", audio->pcm_feedback); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_buf_sz %d\n", audio->out[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_count %d \n", audio->pcm_buf_count); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_sz %d \n", audio->in[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %x \n", audio->vol_pan.volume); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "rflush %d\n", audio->rflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d \n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d \n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d \n", audio->out_needed); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_head %d \n", audio->out_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_tail %d \n", audio->out_tail); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[0].used %d \n", audio->out[0].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[1].used %d \n", audio->out[1].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "buffer_refresh %d \n", audio->buf_refresh); - n += scnprintf(buffer + n, debug_bufmax - n, - "read_next %d \n", audio->read_next); - n += scnprintf(buffer + n, debug_bufmax - n, - "fill_next %d \n", audio->fill_next); - for (i = 0; i < audio->pcm_buf_count; i++) - n += scnprintf(buffer + n, debug_bufmax - n, - "in[%d].size %d \n", i, audio->in[i].used); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audqcelp_debug_fops = { - .read = audqcelp_debug_read, - .open = audqcelp_debug_open, -}; -#endif - -static int audqcelp_open(struct inode *inode, struct file *file) -{ - struct audio *audio = NULL; - int rc, dec_attrb, decid, i; - struct audqcelp_event *e_node = NULL; -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_qcelp_" + 5]; -#endif - - /* Create audio instance, set to zero */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("no memory to allocate audio instance\n"); - rc = -ENOMEM; - goto done; - } - MM_INFO("audio instance 0x%08x created\n", (int)audio); - - /* Allocate the decoder */ - dec_attrb = AUDDEC_DEC_QCELP; - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_NONTUNNEL; - audio->pcm_feedback = NON_TUNNEL_MODE_PLAYBACK; - } else if ((file->f_mode & FMODE_WRITE) && - !(file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_TUNNEL; - audio->pcm_feedback = TUNNEL_MODE_PLAYBACK; - } else { - kfree(audio); - rc = -EACCES; - goto done; - } - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - if (decid < 0) { - MM_ERR("No free decoder available, freeing instance 0x%08x\n", - (int)audio); - rc = -ENODEV; - kfree(audio); - goto done; - } - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - audio->phys = allocate_contiguous_ebi_nomap(DMASZ, SZ_4K); - if (!audio->phys) { - MM_ERR("could not allocate write buffers, freeing instance \ - 0x%08x\n", (int)audio); - rc = -ENOMEM; - audpp_adec_free(audio->dec_id); - kfree(audio); - goto done; - } else { - audio->map_v_write = ioremap(audio->phys, DMASZ); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write phys address, freeing \ - instance 0x%08x\n", (int)audio); - rc = -ENOMEM; - free_contiguous_memory_by_paddr(audio->phys); - audpp_adec_free(audio->dec_id); - kfree(audio); - goto done; - } - audio->data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->phys, (int)audio->data); - } - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audplay_adsp_ops_qcelp, audio); - if (rc) { - MM_ERR("failed to get %s module, freeing instance 0x%08x\n", - audio->module_name, (int)audio); - goto err; - } - - /* Initialize all locks of audio instance */ - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->read_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - init_waitqueue_head(&audio->write_wait); - init_waitqueue_head(&audio->read_wait); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - spin_lock_init(&audio->event_queue_lock); - init_waitqueue_head(&audio->avsync_wait); - - /* Initialize buffer */ - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = BUFSZ; - - audio->out[1].data = audio->data + BUFSZ; - audio->out[1].addr = audio->phys + BUFSZ; - audio->out[1].size = BUFSZ; - - audio->vol_pan.volume = 0x2000; - - audqcelp_flush(audio); - - file->private_data = audio; - audio->opened = 1; - - audio->device_events = AUDDEV_EVT_DEV_RDY - |AUDDEV_EVT_DEV_RLS| - AUDDEV_EVT_STREAM_VOL_CHG; - - rc = auddev_register_evt_listner(audio->device_events, - AUDDEV_CLNT_DEC, - audio->dec_id, - qcelp_listner, - (void *)audio); - if (rc) { - MM_ERR("%s: failed to register listnet\n", __func__); - goto event_err; - } - -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_qcelp_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, &audqcelp_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audqcelp_resume; - audio->suspend_ctl.node.suspend = audqcelp_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (i = 0; i < AUDQCELP_EVENT_NUM; i++) { - e_node = kmalloc(sizeof(struct audqcelp_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } -done: - return rc; -event_err: - msm_adsp_put(audio->audplay); -err: - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - audpp_adec_free(audio->dec_id); - kfree(audio); - return rc; -} - -static const struct file_operations audio_qcelp_fops = { - .owner = THIS_MODULE, - .open = audqcelp_open, - .release = audqcelp_release, - .read = audqcelp_read, - .write = audqcelp_write, - .unlocked_ioctl = audqcelp_ioctl, - .fsync = audqcelp_fsync, -}; - -struct miscdevice audio_qcelp_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_qcelp", - .fops = &audio_qcelp_fops, -}; - -static int __init audqcelp_init(void) -{ - return misc_register(&audio_qcelp_misc); -} - -static void __exit audqcelp_exit(void) -{ - misc_deregister(&audio_qcelp_misc); -} - -module_init(audqcelp_init); -module_exit(audqcelp_exit); - -MODULE_DESCRIPTION("MSM QCELP 13K driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c b/arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c deleted file mode 100644 index d42f717160047db7208d691ef4a05c73d6dcd0da..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c +++ /dev/null @@ -1,1513 +0,0 @@ -/* - * qcelp audio input device - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define META_OUT_SIZE 24 -/* FRAME_NUM must be a power of two */ -#define FRAME_NUM 8 -#define QCELP_FRAME_SIZE 36 /* 36 bytes data */ -#define FRAME_SIZE (22 * 2) /* 36 bytes data */ - /* 36 bytes data + 24 meta field*/ -#define NT_FRAME_SIZE (QCELP_FRAME_SIZE + META_OUT_SIZE) -#define DMASZ (NT_FRAME_SIZE * FRAME_NUM) -#define OUT_FRAME_NUM (2) -#define OUT_BUFFER_SIZE (4 * 1024 + META_OUT_SIZE) -#define BUFFER_SIZE (OUT_BUFFER_SIZE * OUT_FRAME_NUM) - - -#define AUDPREPROC_QCELP_EOS_FLG_OFFSET 0x0A -#define AUDPREPROC_QCELP_EOS_FLG_MASK 0x01 -#define AUDPREPROC_QCELP_EOS_NONE 0x0 /* No EOS detected */ -#define AUDPREPROC_QCELP_EOS_SET 0x1 /* EOS set in meta field */ - -struct buffer { - void *data; - uint32_t size; - uint32_t read; - uint32_t addr; - uint32_t used; - uint32_t mfield_sz; -}; - -struct audio_in { - struct buffer in[FRAME_NUM]; - - spinlock_t dsp_lock; - - atomic_t in_bytes; - atomic_t in_samples; - - struct mutex lock; - struct mutex read_lock; - wait_queue_head_t wait; - wait_queue_head_t wait_enable; - /*write section*/ - struct buffer out[OUT_FRAME_NUM]; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - uint32_t out_count; - - struct mutex write_lock; - wait_queue_head_t write_wait; - int32_t out_phys; /* physical address of write buffer */ - char *out_data; - int mfield; /* meta field embedded in data */ - int wflush; /*write flush */ - int rflush; /*read flush*/ - int out_frame_cnt; - - struct msm_adsp_module *audrec; - - struct audrec_session_info session_info; /*audrec session info*/ - - /* configuration to use on next enable */ - uint32_t buffer_size; /* Frame size (36 bytes) */ - uint32_t samp_rate; - uint32_t channel_mode; - uint32_t enc_type; - - struct msm_audio_qcelp_enc_config cfg; - uint32_t rec_mode; - - uint32_t dsp_cnt; - uint32_t in_head; /* next buffer dsp will write */ - uint32_t in_tail; /* next buffer read() will read */ - uint32_t in_count; /* number of buffers available to read() */ - uint32_t mode; - uint32_t eos_ack; - uint32_t flush_ack; - - const char *module_name; - unsigned queue_ids; - uint16_t enc_id; - - uint16_t source; /* Encoding source bit mask */ - uint32_t device_events; - uint32_t in_call; - uint32_t dev_cnt; - int voice_state; - spinlock_t dev_lock; - - /* data allocated for various buffers */ - char *data; - dma_addr_t phys; - void *map_v_read; - void *map_v_write; - - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - char *build_id; -}; - -struct audio_frame { - uint16_t frame_count_lsw; - uint16_t frame_count_msw; - uint16_t frame_length; - uint16_t erased_pcm; - unsigned char raw_bitstream[]; /* samples */ -} __attribute__((packed)); - -struct audio_frame_nt { - uint16_t metadata_len; - uint16_t frame_count_lsw; - uint16_t frame_count_msw; - uint16_t frame_length; - uint16_t erased_pcm; - uint16_t reserved; - uint16_t time_stamp_dword_lsw; - uint16_t time_stamp_dword_msw; - uint16_t time_stamp_lsw; - uint16_t time_stamp_msw; - uint16_t nflag_lsw; - uint16_t nflag_msw; - unsigned char raw_bitstream[]; /* samples */ -} __attribute__((packed)); - -struct qcelp_encoded_meta_out { - uint16_t metadata_len; - uint16_t time_stamp_dword_lsw; - uint16_t time_stamp_dword_msw; - uint16_t time_stamp_lsw; - uint16_t time_stamp_msw; - uint16_t nflag_lsw; - uint16_t nflag_msw; -}; - -/* Audrec Queue command sent macro's */ -#define audrec_send_bitstreamqueue(audio, cmd, len) \ - msm_adsp_write(audio->audrec, ((audio->queue_ids & 0xFFFF0000) >> 16),\ - cmd, len) - -#define audrec_send_audrecqueue(audio, cmd, len) \ - msm_adsp_write(audio->audrec, (audio->queue_ids & 0x0000FFFF),\ - cmd, len) - -/* DSP command send functions */ -static int audqcelp_in_enc_config(struct audio_in *audio, int enable); -static int audqcelp_in_param_config(struct audio_in *audio); -static int audqcelp_in_mem_config(struct audio_in *audio); -static int audqcelp_in_record_config(struct audio_in *audio, int enable); -static int audqcelp_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt); - -static void audqcelp_in_get_dsp_frames(struct audio_in *audio); -static int audpcm_config(struct audio_in *audio); -static void audqcelp_out_flush(struct audio_in *audio); -static int audpreproc_cmd_cfg_routing_mode(struct audio_in *audio); -static void audpreproc_pcm_send_data(struct audio_in *audio, unsigned needed); -static void audqcelp_nt_in_get_dsp_frames(struct audio_in *audio); - -static void audqcelp_in_flush(struct audio_in *audio); - -static void qcelp_in_listener(u32 evt_id, union auddev_evt_data *evt_payload, - void *private_data) -{ - struct audio_in *audio = (struct audio_in *) private_data; - unsigned long flags; - - MM_DBG("evt_id = 0x%8x\n", evt_id); - switch (evt_id) { - case AUDDEV_EVT_DEV_RDY: { - MM_DBG("AUDDEV_EVT_DEV_RDY\n"); - spin_lock_irqsave(&audio->dev_lock, flags); - audio->dev_cnt++; - if (!audio->in_call) - audio->source |= (0x1 << evt_payload->routing_id); - spin_unlock_irqrestore(&audio->dev_lock, flags); - - if ((audio->running == 1) && (audio->enabled == 1) && - (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)) - audqcelp_in_record_config(audio, 1); - } - break; - case AUDDEV_EVT_DEV_RLS: { - MM_DBG("AUDDEV_EVT_DEV_RLS\n"); - spin_lock_irqsave(&audio->dev_lock, flags); - audio->dev_cnt--; - if (!audio->in_call) - audio->source &= ~(0x1 << evt_payload->routing_id); - spin_unlock_irqrestore(&audio->dev_lock, flags); - - if ((!audio->running) || (!audio->enabled)) - break; - - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - /* Turn of as per source */ - if (audio->source) - audqcelp_in_record_config(audio, 1); - else - /* Turn off all */ - audqcelp_in_record_config(audio, 0); - } - } - break; - case AUDDEV_EVT_VOICE_STATE_CHG: { - MM_DBG("AUDDEV_EVT_VOICE_STATE_CHG, state = %d\n", - evt_payload->voice_state); - audio->voice_state = evt_payload->voice_state; - if (audio->in_call && audio->running && - (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)) { - if (audio->voice_state == VOICE_STATE_INCALL) - audqcelp_in_record_config(audio, 1); - else if (audio->voice_state == VOICE_STATE_OFFCALL) { - audqcelp_in_record_config(audio, 0); - wake_up(&audio->wait); - } - } - - break; - } - default: - MM_ERR("wrong event %d\n", evt_id); - break; - } -} - -/* ------------------- dsp preproc event handler--------------------- */ -static void audpreproc_dsp_event(void *data, unsigned id, void *msg) -{ - struct audio_in *audio = data; - - switch (id) { - case AUDPREPROC_ERROR_MSG: { - struct audpreproc_err_msg *err_msg = msg; - - MM_ERR("ERROR_MSG: stream id %d err idx %d\n", - err_msg->stream_id, err_msg->aud_preproc_err_idx); - /* Error case */ - wake_up(&audio->wait_enable); - break; - } - case AUDPREPROC_CMD_CFG_DONE_MSG: { - MM_DBG("CMD_CFG_DONE_MSG \n"); - break; - } - case AUDPREPROC_CMD_ENC_CFG_DONE_MSG: { - struct audpreproc_cmd_enc_cfg_done_msg *enc_cfg_msg = msg; - - MM_DBG("CMD_ENC_CFG_DONE_MSG: stream id %d enc type \ - 0x%8x\n", enc_cfg_msg->stream_id, - enc_cfg_msg->rec_enc_type); - /* Encoder enable success */ - if (enc_cfg_msg->rec_enc_type & ENCODE_ENABLE) { - if(audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) { - MM_DBG("routing command\n"); - audpreproc_cmd_cfg_routing_mode(audio); - } else { - audqcelp_in_param_config(audio); - } - } else { /* Encoder disable success */ - audio->running = 0; - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - audqcelp_in_record_config(audio, 0); - else - wake_up(&audio->wait_enable); - } - break; - } - case AUDPREPROC_CMD_ENC_PARAM_CFG_DONE_MSG: { - MM_DBG("CMD_ENC_PARAM_CFG_DONE_MSG\n"); - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) - audqcelp_in_mem_config(audio); - else - audpcm_config(audio); - break; - } - case AUDPREPROC_CMD_ROUTING_MODE_DONE_MSG: { - struct audpreproc_cmd_routing_mode_done\ - *routing_cfg_done_msg = msg; - if (routing_cfg_done_msg->configuration == 0) { - MM_INFO("routing configuration failed\n"); - audio->running = 0; - } else - audqcelp_in_param_config(audio); - break; - } - case AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG_DONE_MSG: { - MM_DBG("AFE_CMD_AUDIO_RECORD_CFG_DONE_MSG \n"); - wake_up(&audio->wait_enable); - break; - } - default: - MM_ERR("Unknown Event id %d\n", id); - } -} - -/* ------------------- dsp audrec event handler--------------------- */ -static void audrec_dsp_event(void *data, unsigned id, size_t len, - void (*getevent)(void *ptr, size_t len)) -{ - struct audio_in *audio = data; - - switch (id) { - case AUDREC_CMD_MEM_CFG_DONE_MSG: { - MM_DBG("CMD_MEM_CFG_DONE MSG DONE\n"); - audio->running = 1; - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - if ((!audio->in_call && (audio->dev_cnt > 0)) || - (audio->in_call && - (audio->voice_state \ - == VOICE_STATE_INCALL))) - audqcelp_in_record_config(audio, 1); - } else { - audpreproc_pcm_send_data(audio, 1); - wake_up(&audio->wait_enable); - } - break; - } - case AUDREC_FATAL_ERR_MSG: { - struct audrec_fatal_err_msg fatal_err_msg; - - getevent(&fatal_err_msg, AUDREC_FATAL_ERR_MSG_LEN); - MM_ERR("FATAL_ERR_MSG: err id %d\n", - fatal_err_msg.audrec_err_id); - /* Error stop the encoder */ - audio->stopped = 1; - wake_up(&audio->wait); - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) - wake_up(&audio->write_wait); - break; - } - case AUDREC_UP_PACKET_READY_MSG: { - struct audrec_up_pkt_ready_msg pkt_ready_msg; - - getevent(&pkt_ready_msg, AUDREC_UP_PACKET_READY_MSG_LEN); - MM_DBG("UP_PACKET_READY_MSG: write cnt lsw %d \ - write cnt msw %d read cnt lsw %d read cnt msw %d \n",\ - pkt_ready_msg.audrec_packet_write_cnt_lsw, \ - pkt_ready_msg.audrec_packet_write_cnt_msw, \ - pkt_ready_msg.audrec_up_prev_read_cnt_lsw, \ - pkt_ready_msg.audrec_up_prev_read_cnt_msw); - - audqcelp_in_get_dsp_frames(audio); - break; - } - case AUDREC_CMD_PCM_BUFFER_PTR_UPDATE_ARM_TO_ENC_MSG: { - MM_DBG("ptr_update recieved from DSP\n"); - audpreproc_pcm_send_data(audio, 1); - break; - } - case AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG: { - MM_ERR("AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG"); - audqcelp_in_mem_config(audio); - break; - } - case AUDREC_UP_NT_PACKET_READY_MSG: { - struct audrec_up_nt_packet_ready_msg pkt_ready_msg; - - getevent(&pkt_ready_msg, AUDREC_UP_NT_PACKET_READY_MSG_LEN); - MM_DBG("UP_NT_PACKET_READY_MSG: write cnt lsw %d \ - write cnt msw %d read cnt lsw %d read cnt msw %d \n",\ - pkt_ready_msg.audrec_packetwrite_cnt_lsw, \ - pkt_ready_msg.audrec_packetwrite_cnt_msw, \ - pkt_ready_msg.audrec_upprev_readcount_lsw, \ - pkt_ready_msg.audrec_upprev_readcount_msw); - - audqcelp_nt_in_get_dsp_frames(audio); - break; - } - case AUDREC_CMD_EOS_ACK_MSG: { - MM_DBG("eos ack recieved\n"); - break; - } - case AUDREC_CMD_FLUSH_DONE_MSG: { - audio->wflush = 0; - audio->rflush = 0; - audio->flush_ack = 1; - wake_up(&audio->write_wait); - MM_DBG("flush ack recieved\n"); - break; - } - case ADSP_MESSAGE_ID: { - MM_DBG("Received ADSP event:module audrectask\n"); - break; - } - default: - MM_ERR("Unknown Event id %d\n", id); - } -} - -static void audqcelp_in_get_dsp_frames(struct audio_in *audio) -{ - struct audio_frame *frame; - uint32_t index; - unsigned long flags; - - MM_DBG("head = %d\n", audio->in_head); - index = audio->in_head; - - frame = (void *) (((char *)audio->in[index].data) - \ - sizeof(*frame)); - - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->in[index].size = frame->frame_length; - - /* statistics of read */ - atomic_add(audio->in[index].size, &audio->in_bytes); - atomic_add(1, &audio->in_samples); - - audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1); - - /* If overflow, move the tail index foward. */ - if (audio->in_head == audio->in_tail) { - MM_ERR("Error! not able to keep up the read\n"); - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - MM_ERR("in_count = %d\n", audio->in_count); - } else - audio->in_count++; - - audqcelp_dsp_read_buffer(audio, audio->dsp_cnt++); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - - wake_up(&audio->wait); -} - -static void audqcelp_nt_in_get_dsp_frames(struct audio_in *audio) -{ - struct audio_frame_nt *nt_frame; - uint32_t index; - unsigned long flags; - MM_DBG("head = %d\n", audio->in_head); - index = audio->in_head; - nt_frame = (void *) (((char *)audio->in[index].data) - \ - sizeof(struct audio_frame_nt)); - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->in[index].size = nt_frame->frame_length; - /* statistics of read */ - atomic_add(audio->in[index].size, &audio->in_bytes); - atomic_add(1, &audio->in_samples); - - audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1); - - /* If overflow, move the tail index foward. */ - if (audio->in_head == audio->in_tail) - MM_DBG("Error! not able to keep up the read\n"); - else - audio->in_count++; - - spin_unlock_irqrestore(&audio->dsp_lock, flags); - wake_up(&audio->wait); -} - - -struct msm_adsp_ops audrec_qcelp_adsp_ops = { - .event = audrec_dsp_event, -}; - -static int audpreproc_pcm_buffer_ptr_refresh(struct audio_in *audio, - unsigned idx, unsigned len) -{ - struct audrec_cmd_pcm_buffer_ptr_refresh_arm_enc cmd; - - if (len == META_OUT_SIZE) - len = len / 2; - else - len = (len + META_OUT_SIZE) / 2; - MM_DBG("len = %d\n", len); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_PCM_BUFFER_PTR_REFRESH_ARM_TO_ENC; - cmd.num_buffers = 1; - if (cmd.num_buffers == 1) { - cmd.buf_address_length[0] = (audio->out[idx].addr & - 0xffff0000) >> 16; - cmd.buf_address_length[1] = (audio->out[idx].addr & - 0x0000ffff); - cmd.buf_address_length[2] = (len & 0xffff0000) >> 16; - cmd.buf_address_length[3] = (len & 0x0000ffff); - } - audio->out_frame_cnt++; - return audrec_send_audrecqueue(audio, (void *)&cmd, - (unsigned int)sizeof(cmd)); -} - - -static int audpcm_config(struct audio_in *audio) -{ - struct audrec_cmd_pcm_cfg_arm_to_enc cmd; - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_PCM_CFG_ARM_TO_ENC; - cmd.config_update_flag = AUDREC_PCM_CONFIG_UPDATE_FLAG_ENABLE; - cmd.enable_flag = AUDREC_ENABLE_FLAG_VALUE; - cmd.sampling_freq = audio->samp_rate; - if (!audio->channel_mode) - cmd.channels = 1; - else - cmd.channels = 2; - cmd.frequency_of_intimation = 1; - cmd.max_number_of_buffers = OUT_FRAME_NUM; - return audrec_send_audrecqueue(audio, (void *)&cmd, - (unsigned int)sizeof(cmd)); -} - - -static int audpreproc_cmd_cfg_routing_mode(struct audio_in *audio) -{ - struct audpreproc_audrec_cmd_routing_mode cmd; - - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPREPROC_AUDREC_CMD_ROUTING_MODE; - cmd.stream_id = audio->enc_id; - if (audio->mode == MSM_ADSP_ENC_MODE_NON_TUNNEL) - cmd.routing_mode = 1; - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); -} - - - -static int audqcelp_in_enc_config(struct audio_in *audio, int enable) -{ - struct audpreproc_audrec_cmd_enc_cfg cmd; - - memset(&cmd, 0, sizeof(cmd)); - if (audio->build_id[17] == '1') { - cmd.cmd_id = AUDPREPROC_AUDREC_CMD_ENC_CFG_2; - MM_ERR("sending AUDPREPROC_AUDREC_CMD_ENC_CFG_2 command"); - } else { - cmd.cmd_id = AUDPREPROC_AUDREC_CMD_ENC_CFG; - MM_ERR("sending AUDPREPROC_AUDREC_CMD_ENC_CFG command"); - } - cmd.stream_id = audio->enc_id; - - if (enable) - cmd.audrec_enc_type = audio->enc_type | ENCODE_ENABLE; - else - cmd.audrec_enc_type &= ~(ENCODE_ENABLE); - - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); -} - -static int audqcelp_in_param_config(struct audio_in *audio) -{ - struct audpreproc_audrec_cmd_parm_cfg_qcelp13k cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPREPROC_AUDREC_CMD_PARAM_CFG; - cmd.common.stream_id = audio->enc_id; - - cmd.enc_min_rate = audio->cfg.min_bit_rate; - cmd.enc_max_rate = audio->cfg.max_bit_rate; - cmd.rate_modulation_cmd = 0; /* Default set to 0 */ - cmd.reduced_rate_level = 0; /* Default set to 0 */ - - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); -} - -/* To Do: msm_snddev_route_enc(audio->enc_id); */ -static int audqcelp_in_record_config(struct audio_in *audio, int enable) -{ - struct audpreproc_afe_cmd_audio_record_cfg cmd; - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG; - cmd.stream_id = audio->enc_id; - if (enable) - cmd.destination_activity = AUDIO_RECORDING_TURN_ON; - else - cmd.destination_activity = AUDIO_RECORDING_TURN_OFF; - - cmd.source_mix_mask = audio->source; - if (audio->enc_id == 2) { - if ((cmd.source_mix_mask & - INTERNAL_CODEC_TX_SOURCE_MIX_MASK) || - (cmd.source_mix_mask & AUX_CODEC_TX_SOURCE_MIX_MASK) || - (cmd.source_mix_mask & VOICE_UL_SOURCE_MIX_MASK) || - (cmd.source_mix_mask & VOICE_DL_SOURCE_MIX_MASK)) { - cmd.pipe_id = SOURCE_PIPE_1; - } - if (cmd.source_mix_mask & - AUDPP_A2DP_PIPE_SOURCE_MIX_MASK) - cmd.pipe_id |= SOURCE_PIPE_0; - } - MM_DBG("stream_id %x destination_activity %x \ - source_mix_mask %x pipe_id %x",\ - cmd.stream_id, cmd.destination_activity, - cmd.source_mix_mask, cmd.pipe_id); - return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd)); -} - -static int audqcelp_in_mem_config(struct audio_in *audio) -{ - struct audrec_cmd_arecmem_cfg cmd; - uint16_t *data = (void *) audio->data; - int n; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_MEM_CFG_CMD; - cmd.audrec_up_pkt_intm_count = 1; - cmd.audrec_ext_pkt_start_addr_msw = audio->phys >> 16; - cmd.audrec_ext_pkt_start_addr_lsw = audio->phys; - cmd.audrec_ext_pkt_buf_number = FRAME_NUM; - MM_DBG("audio->phys = %x\n", audio->phys); - /* prepare buffer pointers: - * T:36 bytes qcelp ppacket + 4 halfword header - * NT:36 bytes qcelp packet + 12 halfword header - */ - for (n = 0; n < FRAME_NUM; n++) { - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - audio->in[n].data = data + 4; - data += (FRAME_SIZE/2); - MM_DBG("0x%8x\n", (int)(audio->in[n].data - 8)); - } else { - audio->in[n].data = data + 12; - data += ((QCELP_FRAME_SIZE) / 2) + 12; - MM_DBG("0x%8x\n", (int)(audio->in[n].data - 24)); - } - } - return audrec_send_audrecqueue(audio, &cmd, sizeof(cmd)); -} - -static int audqcelp_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt) -{ - struct up_audrec_packet_ext_ptr cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = UP_AUDREC_PACKET_EXT_PTR; - cmd.audrec_up_curr_read_count_msw = read_cnt >> 16; - cmd.audrec_up_curr_read_count_lsw = read_cnt; - - return audrec_send_bitstreamqueue(audio, &cmd, sizeof(cmd)); -} -static int audqcelp_flush_command(struct audio_in *audio) -{ - struct audrec_cmd_flush cmd; - MM_DBG("\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDREC_CMD_FLUSH; - return audrec_send_audrecqueue(audio, &cmd, sizeof(cmd)); -} - -/* must be called with audio->lock held */ -static int audqcelp_in_enable(struct audio_in *audio) -{ - if (audio->enabled) - return 0; - - if (audpreproc_enable(audio->enc_id, &audpreproc_dsp_event, audio)) { - MM_ERR("msm_adsp_enable(audpreproc) failed\n"); - return -ENODEV; - } - - if (msm_adsp_enable(audio->audrec)) { - MM_ERR("msm_adsp_enable(audrec) failed\n"); - audpreproc_disable(audio->enc_id, audio); - return -ENODEV; - } - audio->enabled = 1; - audqcelp_in_enc_config(audio, 1); - - return 0; -} - -/* must be called with audio->lock held */ -static int audqcelp_in_disable(struct audio_in *audio) -{ - if (audio->enabled) { - audio->enabled = 0; - audqcelp_in_enc_config(audio, 0); - wake_up(&audio->wait); - wait_event_interruptible_timeout(audio->wait_enable, - audio->running == 0, 1*HZ); - msm_adsp_disable(audio->audrec); - audpreproc_disable(audio->enc_id, audio); - } - return 0; -} - -static void audqcelp_ioport_reset(struct audio_in *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audqcelp_in_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->wait); - mutex_lock(&audio->read_lock); - audqcelp_out_flush(audio); - mutex_unlock(&audio->read_lock); -} - -static void audqcelp_in_flush(struct audio_in *audio) -{ - int i; - - audio->dsp_cnt = 0; - audio->in_head = 0; - audio->in_tail = 0; - audio->in_count = 0; - audio->eos_ack = 0; - for (i = 0; i < FRAME_NUM; i++) { - audio->in[i].size = 0; - audio->in[i].read = 0; - } - MM_DBG("in_bytes %d\n", atomic_read(&audio->in_bytes)); - MM_DBG("in_samples %d\n", atomic_read(&audio->in_samples)); - atomic_set(&audio->in_bytes, 0); - atomic_set(&audio->in_samples, 0); -} - -static void audqcelp_out_flush(struct audio_in *audio) -{ - int i; - - audio->out_head = 0; - audio->out_tail = 0; - audio->out_count = 0; - for (i = 0; i < OUT_FRAME_NUM; i++) { - audio->out[i].size = 0; - audio->out[i].read = 0; - audio->out[i].used = 0; - } -} - -/* ------------------- device --------------------- */ -static long audqcelp_in_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct audio_in *audio = file->private_data; - int rc = 0; - - MM_DBG("\n"); - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - stats.byte_count = atomic_read(&audio->in_bytes); - stats.sample_count = atomic_read(&audio->in_samples); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return rc; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: { - uint32_t freq; - freq = 48000; - MM_DBG("AUDIO_START\n"); - if (audio->in_call && (audio->voice_state != - VOICE_STATE_INCALL)) { - rc = -EPERM; - break; - } - rc = msm_snddev_request_freq(&freq, audio->enc_id, - SNDDEV_CAP_TX, AUDDEV_CLNT_ENC); - MM_DBG("sample rate configured %d\n", freq); - if (rc < 0) { - MM_DBG(" Sample rate can not be set, return code %d\n", - rc); - msm_snddev_withdraw_freq(audio->enc_id, - SNDDEV_CAP_TX, AUDDEV_CLNT_ENC); - MM_DBG("msm_snddev_withdraw_freq\n"); - break; - } - /*update aurec session info in audpreproc layer*/ - audio->session_info.session_id = audio->enc_id; - audio->session_info.sampling_freq = audio->samp_rate; - audpreproc_update_audrec_info(&audio->session_info); - rc = audqcelp_in_enable(audio); - if (!rc) { - rc = - wait_event_interruptible_timeout(audio->wait_enable, - audio->running != 0, 1*HZ); - MM_DBG("state %d rc = %d\n", audio->running, rc); - - if (audio->running == 0) - rc = -ENODEV; - else - rc = 0; - } - audio->stopped = 0; - break; - } - case AUDIO_STOP: { - /*reset the sampling frequency information at audpreproc layer*/ - audio->session_info.sampling_freq = 0; - audpreproc_update_audrec_info(&audio->session_info); - rc = audqcelp_in_disable(audio); - rc = msm_snddev_withdraw_freq(audio->enc_id, - SNDDEV_CAP_TX, AUDDEV_CLNT_ENC); - MM_DBG("msm_snddev_withdraw_freq\n"); - audio->stopped = 1; - break; - } - case AUDIO_FLUSH: { - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audqcelp_ioport_reset(audio); - if (audio->running) { - audqcelp_flush_command(audio); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - } - case AUDIO_SET_STREAM_CONFIG: { - struct msm_audio_stream_config cfg; - if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - /* Allow only single frame */ - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - if (cfg.buffer_size != (FRAME_SIZE - 8)) { - rc = -EINVAL; - break; - } - } else { - if (cfg.buffer_size != (QCELP_FRAME_SIZE + 14)) { - rc = -EINVAL; - break; - } - } - audio->buffer_size = cfg.buffer_size; - break; - } - case AUDIO_GET_STREAM_CONFIG: { - struct msm_audio_stream_config cfg; - memset(&cfg, 0, sizeof(cfg)); - cfg.buffer_size = audio->buffer_size; - cfg.buffer_count = FRAME_NUM; - if (copy_to_user((void *) arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - break; - } - case AUDIO_GET_QCELP_ENC_CONFIG: { - if (copy_to_user((void *) arg, &audio->cfg, sizeof(audio->cfg))) - rc = -EFAULT; - break; - } - case AUDIO_SET_QCELP_ENC_CONFIG: { - struct msm_audio_qcelp_enc_config cfg; - if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - MM_DBG("0X%8x, 0x%8x, 0x%8x\n", cfg.min_bit_rate, \ - cfg.max_bit_rate, cfg.cdma_rate); - if (cfg.min_bit_rate > CDMA_RATE_FULL || \ - cfg.min_bit_rate < CDMA_RATE_EIGHTH) { - MM_ERR("invalid min bitrate\n"); - rc = -EFAULT; - break; - } - if (cfg.max_bit_rate > CDMA_RATE_FULL || \ - cfg.max_bit_rate < CDMA_RATE_EIGHTH) { - MM_ERR("invalid max bitrate\n"); - rc = -EFAULT; - break; - } - /* Recording Does not support Erase and Blank */ - if (cfg.cdma_rate > CDMA_RATE_FULL || - cfg.cdma_rate < CDMA_RATE_EIGHTH) { - MM_ERR("invalid qcelp cdma rate\n"); - rc = -EFAULT; - break; - } - memcpy(&audio->cfg, &cfg, sizeof(cfg)); - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config cfg; - memset(&cfg, 0, sizeof(cfg)); - cfg.buffer_size = OUT_BUFFER_SIZE; - cfg.buffer_count = OUT_FRAME_NUM; - cfg.sample_rate = audio->samp_rate; - cfg.channel_count = audio->channel_mode; - if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) - rc = -EFAULT; - break; - } - case AUDIO_SET_INCALL: { - struct msm_voicerec_mode cfg; - unsigned long flags; - if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) { - if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { - rc = -EFAULT; - break; - } - if (cfg.rec_mode != VOC_REC_BOTH && - cfg.rec_mode != VOC_REC_UPLINK && - cfg.rec_mode != VOC_REC_DOWNLINK) { - MM_ERR("invalid rec_mode\n"); - rc = -EINVAL; - break; - } else { - spin_lock_irqsave(&audio->dev_lock, flags); - if (cfg.rec_mode == VOC_REC_UPLINK) - audio->source = \ - VOICE_UL_SOURCE_MIX_MASK; - else if (cfg.rec_mode == VOC_REC_DOWNLINK) - audio->source = \ - VOICE_DL_SOURCE_MIX_MASK; - else - audio->source = \ - VOICE_DL_SOURCE_MIX_MASK | - VOICE_UL_SOURCE_MIX_MASK ; - audio->in_call = 1; - spin_unlock_irqrestore(&audio->dev_lock, flags); - } - } - break; - } - case AUDIO_GET_SESSION_ID: { - if (copy_to_user((void *) arg, &audio->enc_id, - sizeof(unsigned short))) { - rc = -EFAULT; - } - break; - } - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -static ssize_t audqcelp_in_read(struct file *file, - char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_in *audio = file->private_data; - unsigned long flags; - const char __user *start = buf; - void *data; - uint32_t index; - uint32_t size; - int rc = 0; - struct qcelp_encoded_meta_out meta_field; - struct audio_frame_nt *nt_frame; - MM_DBG(" count = %d\n", count); - mutex_lock(&audio->read_lock); - while (count > 0) { - rc = wait_event_interruptible( - audio->wait, (audio->in_count > 0) || audio->stopped || - audio->rflush || - ((audio->mode == MSM_AUD_ENC_MODE_TUNNEL) && - audio->in_call && audio->running && - (audio->voice_state == VOICE_STATE_OFFCALL))); - if (rc < 0) - break; - - if (audio->rflush) { - rc = -EBUSY; - break; - } - if (audio->stopped && !audio->in_count) { - MM_DBG("Driver in stop state, No more buffer to read"); - rc = 0;/* End of File */ - break; - } else if ((audio->mode == MSM_AUD_ENC_MODE_TUNNEL) && - audio->in_call && audio->running && - (audio->voice_state \ - == VOICE_STATE_OFFCALL)) { - MM_DBG("Not Permitted Voice Terminated\n"); - rc = -EPERM; /* Voice Call stopped */ - break; - } - - index = audio->in_tail; - data = (uint8_t *) audio->in[index].data; - size = audio->in[index].size; - - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) { - nt_frame = (struct audio_frame_nt *)(data - - sizeof(struct audio_frame_nt)); - memcpy((char *)&meta_field.time_stamp_dword_lsw, - (char *)&nt_frame->time_stamp_dword_lsw, - (sizeof(struct qcelp_encoded_meta_out) - \ - sizeof(uint16_t))); - meta_field.metadata_len = - sizeof(struct qcelp_encoded_meta_out); - if (copy_to_user((char *)start, - (char *)&meta_field, - sizeof(struct qcelp_encoded_meta_out))) { - rc = -EFAULT; - break; - } - if (nt_frame->nflag_lsw & 0x0001) { - MM_ERR("recieved EOS in read call\n"); - audio->eos_ack = 1; - } - buf += sizeof(struct qcelp_encoded_meta_out); - count -= sizeof(struct qcelp_encoded_meta_out); - } - if (count >= size) { - if (copy_to_user(buf, data, size)) { - rc = -EFAULT; - break; - } - spin_lock_irqsave(&audio->dsp_lock, flags); - if (index != audio->in_tail) { - /* overrun -- data is - * invalid and we need to retry */ - spin_unlock_irqrestore(&audio->dsp_lock, flags); - continue; - } - audio->in[index].size = 0; - audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); - audio->in_count--; - spin_unlock_irqrestore(&audio->dsp_lock, flags); - count -= size; - buf += size; - if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL)) { - if (!audio->eos_ack) { - MM_DBG("sending read ptr command\ - %d %d\n", - audio->dsp_cnt, - audio->in_tail); - audqcelp_dsp_read_buffer(audio, - audio->dsp_cnt++); - } - } - } else { - MM_ERR("short read\n"); - break; - } - break; - } - mutex_unlock(&audio->read_lock); - - if (buf > start) - return buf - start; - - return rc; -} - -static void audpreproc_pcm_send_data(struct audio_in *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - MM_DBG("\n"); - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - audpreproc_pcm_buffer_ptr_refresh(audio, - audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } - done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - - -static int audqcelp_in_fsync(struct file *file, loff_t ppos1, loff_t ppos2, int datasync) - -{ - struct audio_in *audio = file->private_data; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - if (!audio->running || (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - audio->wflush); - MM_DBG("waked on by some event audio->wflush = %d\n", audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; - -} - - int audpreproc_qcelp_process_eos(struct audio_in *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - struct buffer *frame; - int rc = 0; - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - MM_DBG("copying meta_out frame->used = %d\n", frame->used); - audpreproc_pcm_send_data(audio, 0); -done: - return rc; -} - -static ssize_t audqcelp_in_write(struct file *file, - const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_in *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - char *cpy_ptr; - int rc = 0, eos_condition = AUDPREPROC_QCELP_EOS_NONE; - unsigned short mfield_size = 0; - int write_count = 0; - - MM_DBG("cnt=%d\n", count); - if (count & 1) - return -EINVAL; - - if (audio->mode != MSM_AUD_ENC_MODE_NONTUNNEL) - return -EINVAL; - - mutex_lock(&audio->write_lock); - frame = audio->out + audio->out_head; - /* if supplied count is more than driver buffer size - * then only copy driver buffer size - */ - if (count > frame->size) - count = frame->size; - - write_count = count; - cpy_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - goto error; - - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto error; - } - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - goto error; - } else if (mfield_size > count) { - rc = -EINVAL; - goto error; - } - MM_DBG("mf offset_val %x\n", mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - goto error; - } - /* Check if EOS flag is set and buffer has - * contains just meta field - */ - if (cpy_ptr[AUDPREPROC_QCELP_EOS_FLG_OFFSET] & - AUDPREPROC_QCELP_EOS_FLG_MASK) { - eos_condition = AUDPREPROC_QCELP_EOS_SET; - MM_DBG("EOS SET\n"); - if (mfield_size == count) { - buf += mfield_size; - eos_condition = 0; - goto exit; - } else - cpy_ptr[AUDPREPROC_QCELP_EOS_FLG_OFFSET] &= - ~AUDPREPROC_QCELP_EOS_FLG_MASK; - } - cpy_ptr += mfield_size; - count -= mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - MM_DBG("copying the stream count = %d\n", count); - if (copy_from_user(cpy_ptr, buf, count)) { - rc = -EFAULT; - goto error; - } -exit: - frame->used = count; - audio->out_head ^= 1; - if (!audio->flush_ack) - audpreproc_pcm_send_data(audio, 0); - else { - audpreproc_pcm_send_data(audio, 1); - audio->flush_ack = 0; - } - if (eos_condition == AUDPREPROC_QCELP_EOS_SET) - rc = audpreproc_qcelp_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - return write_count; -error: - mutex_unlock(&audio->write_lock); - return rc; -} - -static int audqcelp_in_release(struct inode *inode, struct file *file) -{ - struct audio_in *audio = file->private_data; - - mutex_lock(&audio->lock); - audio->in_call = 0; - /* with draw frequency for session - incase not stopped the driver */ - msm_snddev_withdraw_freq(audio->enc_id, SNDDEV_CAP_TX, - AUDDEV_CLNT_ENC); - auddev_unregister_evt_listner(AUDDEV_CLNT_ENC, audio->enc_id); - /*reset the sampling frequency information at audpreproc layer*/ - audio->session_info.sampling_freq = 0; - audpreproc_update_audrec_info(&audio->session_info); - audqcelp_in_disable(audio); - audqcelp_in_flush(audio); - msm_adsp_put(audio->audrec); - audpreproc_aenc_free(audio->enc_id); - audio->audrec = NULL; - audio->opened = 0; - if (audio->data) { - iounmap(audio->map_v_read); - free_contiguous_memory_by_paddr(audio->phys); - audio->data = NULL; - } - if (audio->out_data) { - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->out_phys); - audio->out_data = NULL; - } - mutex_unlock(&audio->lock); - return 0; -} - -struct audio_in the_audio_qcelp_in; -static int audqcelp_in_open(struct inode *inode, struct file *file) -{ - struct audio_in *audio = &the_audio_qcelp_in; - int rc; - int encid; - - mutex_lock(&audio->lock); - if (audio->opened) { - rc = -EBUSY; - goto done; - } - audio->phys = allocate_contiguous_ebi_nomap(DMASZ, SZ_4K); - if (audio->phys) { - audio->map_v_read = ioremap(audio->phys, DMASZ); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("could not map DMA buffers\n"); - rc = -ENOMEM; - free_contiguous_memory_by_paddr(audio->phys); - goto done; - } - audio->data = audio->map_v_read; - } else { - MM_ERR("could not allocate DMA buffers\n"); - rc = -ENOMEM; - goto done; - } - MM_DBG("Memory addr = 0x%8x phy addr = 0x%8x\n",\ - (int) audio->data, (int) audio->phys); - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - audio->mode = MSM_AUD_ENC_MODE_NONTUNNEL; - MM_DBG("Opened for non tunnel mode encoding\n"); - } else if (!(file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - audio->mode = MSM_AUD_ENC_MODE_TUNNEL; - MM_DBG("Opened for tunnel mode encoding\n"); - } else { - MM_ERR("Invalid mode\n"); - rc = -EACCES; - goto done; - } - - /* Settings will be re-config at AUDIO_SET_CONFIG, - * but at least we need to have initial config - */ - if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) - audio->buffer_size = (QCELP_FRAME_SIZE + 14); - else - audio->buffer_size = (FRAME_SIZE - 8); - audio->enc_type = ENC_TYPE_V13K | audio->mode; - audio->samp_rate = 8000; - audio->channel_mode = AUDREC_CMD_MODE_MONO; - audio->cfg.cdma_rate = CDMA_RATE_FULL; - audio->cfg.min_bit_rate = CDMA_RATE_FULL; - audio->cfg.max_bit_rate = CDMA_RATE_FULL; - audio->source = INTERNAL_CODEC_TX_SOURCE_MIX_MASK; - audio->rec_mode = VOC_REC_UPLINK; - - encid = audpreproc_aenc_alloc(audio->enc_type, &audio->module_name, - &audio->queue_ids); - if (encid < 0) { - MM_ERR("No free encoder available\n"); - rc = -ENODEV; - goto done; - } - audio->enc_id = encid; - - rc = msm_adsp_get(audio->module_name, &audio->audrec, - &audrec_qcelp_adsp_ops, audio); - - if (rc) { - audpreproc_aenc_free(audio->enc_id); - goto done; - } - - audio->stopped = 0; - audio->source = 0; - audio->wflush = 0; - audio->rflush = 0; - audio->flush_ack = 0; - - audqcelp_in_flush(audio); - audqcelp_out_flush(audio); - - audio->out_phys = allocate_contiguous_ebi_nomap(BUFFER_SIZE, SZ_4K); - if (!audio->out_phys) { - MM_ERR("could not allocate write buffers\n"); - rc = -ENOMEM; - goto evt_error; - } else { - audio->map_v_write = ioremap(audio->out_phys, BUFFER_SIZE); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write buffers\n"); - rc = -ENOMEM; - free_contiguous_memory_by_paddr(audio->out_phys); - goto evt_error; - } - audio->out_data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n", - audio->out_phys, (int)audio->out_data); - } - - /* Initialize buffer */ - audio->out[0].data = audio->out_data + 0; - audio->out[0].addr = audio->out_phys + 0; - audio->out[0].size = OUT_BUFFER_SIZE; - - audio->out[1].data = audio->out_data + OUT_BUFFER_SIZE; - audio->out[1].addr = audio->out_phys + OUT_BUFFER_SIZE; - audio->out[1].size = OUT_BUFFER_SIZE; - - MM_DBG("audio->out[0].data = %d audio->out[1].data = %d", - (unsigned int)audio->out[0].data, - (unsigned int)audio->out[1].data); - audio->device_events = AUDDEV_EVT_DEV_RDY | AUDDEV_EVT_DEV_RLS | - AUDDEV_EVT_VOICE_STATE_CHG; - - audio->voice_state = msm_get_voice_state(); - rc = auddev_register_evt_listner(audio->device_events, - AUDDEV_CLNT_ENC, audio->enc_id, - qcelp_in_listener, (void *) audio); - if (rc) { - MM_ERR("failed to register device event listener\n"); - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->out_phys); - goto evt_error; - } - audio->mfield = META_OUT_SIZE; - file->private_data = audio; - audio->opened = 1; - audio->out_frame_cnt++; - audio->build_id = socinfo_get_build_id(); - MM_DBG("Modem build id = %s\n", audio->build_id); -done: - mutex_unlock(&audio->lock); - return rc; -evt_error: - msm_adsp_put(audio->audrec); - audpreproc_aenc_free(audio->enc_id); - mutex_unlock(&audio->lock); - return rc; -} - -static const struct file_operations audio_in_fops = { - .owner = THIS_MODULE, - .open = audqcelp_in_open, - .release = audqcelp_in_release, - .read = audqcelp_in_read, - .write = audqcelp_in_write, - .fsync = audqcelp_in_fsync, - .unlocked_ioctl = audqcelp_in_ioctl, -}; - -struct miscdevice audio_qcelp_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_qcelp_in", - .fops = &audio_in_fops, -}; - -static int __init audqcelp_in_init(void) -{ - mutex_init(&the_audio_qcelp_in.lock); - mutex_init(&the_audio_qcelp_in.read_lock); - spin_lock_init(&the_audio_qcelp_in.dsp_lock); - spin_lock_init(&the_audio_qcelp_in.dev_lock); - init_waitqueue_head(&the_audio_qcelp_in.wait); - init_waitqueue_head(&the_audio_qcelp_in.wait_enable); - mutex_init(&the_audio_qcelp_in.write_lock); - init_waitqueue_head(&the_audio_qcelp_in.write_wait); - return misc_register(&audio_qcelp_in_misc); -} - -device_initcall(audqcelp_in_init); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_wma.c b/arch/arm/mach-msm/qdsp5v2/audio_wma.c deleted file mode 100644 index 131df227f2a634c456bc078f6e912826131d42d6..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_wma.c +++ /dev/null @@ -1,1797 +0,0 @@ -/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. - * - * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * - * All source code in this file is licensed under the following license except - * where indicated. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Size must be power of 2 */ -#define BUFSZ_MAX 4110 /* Includes meta in size */ -#define BUFSZ_MIN 1038 /* Includes meta in size */ -#define DMASZ_MAX (BUFSZ_MAX * 2) -#define DMASZ_MIN (BUFSZ_MIN * 2) - -#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF -#define AUDDEC_DEC_WMA 4 - -#define PCM_BUFSZ_MIN 8216 /* Hold one stereo WMA frame and meta out*/ -#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most - but support 2 buffers currently */ -#define ROUTING_MODE_FTRT 1 -#define ROUTING_MODE_RT 2 -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDWMA_METAFIELD_MASK 0xFFFF0000 -#define AUDWMA_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */ -#define AUDWMA_EOS_FLG_MASK 0x01 -#define AUDWMA_EOS_NONE 0x0 /* No EOS detected */ -#define AUDWMA_EOS_SET 0x1 /* EOS set in meta field */ - -#define AUDWMA_EVENT_NUM 10 /* Default number of pre-allocated event packets */ - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; - unsigned short mfield_sz; /*only useful for data has meta field */ -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audwma_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct audwma_event{ - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audio { - struct buffer out[2]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - unsigned out_dma_sz; - - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - /* Host PCM section */ - struct buffer in[PCM_BUF_MAX_COUNT]; - struct mutex read_lock; - wait_queue_head_t read_wait; /* Wait queue for read */ - char *read_data; /* pointer to reader buffer */ - int32_t read_phys; /* physical address of reader buffer */ - uint8_t read_next; /* index to input buffers to be read next */ - uint8_t fill_next; /* index to buffer that DSP should be filling */ - uint8_t pcm_buf_count; /* number of pcm buffer allocated */ - /* ---- End of Host PCM section */ - - struct msm_adsp_module *audplay; - - /* configuration to use on next enable */ - uint32_t out_sample_rate; - uint32_t out_channel_mode; - - struct msm_audio_wma_config wma_config; - - /* data allocated for various buffers */ - char *data; - int32_t phys; /* physical address of write buffer */ - void *map_v_read; - void *map_v_write; - - int mfield; /* meta field embedded in data */ - int rflush; /* Read flush */ - int wflush; /* Write flush */ - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - int pcm_feedback; - int buf_refresh; - int teos; /* valid only if tunnel mode & no data left for decoder */ - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - int reserved; /* A byte is being reserved */ - char rsv_byte; /* Handle odd length user data */ - - const char *module_name; - unsigned queue_id; - uint16_t dec_id; - uint32_t read_ptr_offset; - int16_t source; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audwma_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - /* AV sync Info */ - int avsync_flag; /* Flag to indicate feedback from DSP */ - wait_queue_head_t avsync_wait;/* Wait queue for AV Sync Message */ - /* flags, 48 bits sample/bytes counter per channel */ - uint16_t avsync[AUDPP_AVSYNC_CH_COUNT * AUDPP_AVSYNC_NUM_WORDS + 1]; - - uint32_t device_events; - - int eq_enable; - int eq_needs_commit; - struct audpp_cmd_cfg_object_params_eqalizer eq; - struct audpp_cmd_cfg_object_params_volume vol_pan; -}; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audpp_cmd_cfg_adec_params(struct audio *audio); -static void audpp_cmd_cfg_routing_mode(struct audio *audio); -static void audplay_send_data(struct audio *audio, unsigned needed); -static void audplay_config_hostpcm(struct audio *audio); -static void audplay_buffer_refresh(struct audio *audio); -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg); -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audwma_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); -#endif -/* must be called with audio->lock held */ -static int audio_enable(struct audio *audio) -{ - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) - return 0; - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_tail = 0; - audio->out_needed = 0; - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - return -ENODEV; - } - - audio->enabled = 1; - return 0; -} - -static void wma_listner(u32 evt_id, union auddev_evt_data *evt_payload, - void *private_data) -{ - struct audio *audio = (struct audio *) private_data; - switch (evt_id) { - case AUDDEV_EVT_DEV_RDY: - MM_DBG(":AUDDEV_EVT_DEV_RDY\n"); - audio->source |= (0x1 << evt_payload->routing_id); - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - break; - case AUDDEV_EVT_DEV_RLS: - MM_DBG(":AUDDEV_EVT_DEV_RLS\n"); - audio->source &= ~(0x1 << evt_payload->routing_id); - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - break; - case AUDDEV_EVT_STREAM_VOL_CHG: - audio->vol_pan.volume = evt_payload->session_vol; - MM_DBG(":AUDDEV_EVT_STREAM_VOL_CHG, stream vol %d\n", - audio->vol_pan.volume); - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - break; - default: - MM_ERR(":ERROR:wrong event\n"); - break; - } -} -/* must be called with audio->lock held */ -static int audio_disable(struct audio *audio) -{ - int rc = 0; - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - wake_up(&audio->write_wait); - wake_up(&audio->read_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - audio->out_needed = 0; - } - return rc; -} - -/* ------------------- dsp --------------------- */ -static void audio_update_pcm_buf_entry(struct audio *audio, - uint32_t *payload) -{ - uint8_t index; - unsigned long flags; - - if (audio->rflush) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < payload[1]; index++) { - if (audio->in[audio->fill_next].addr == - payload[2 + index * 2]) { - MM_DBG("audio_update_pcm_buf_entry: \ - in[%d] ready\n", audio->fill_next); - audio->in[audio->fill_next].used = - payload[3 + index * 2]; - if ((++audio->fill_next) == audio->pcm_buf_count) - audio->fill_next = 0; - } else { - MM_ERR("audio_update_pcm_buf_entry: \ - expected=%x ret=%x\n", - audio->in[audio->fill_next].addr, - payload[1 + index * 2]); - break; - } - } - if (audio->in[audio->fill_next].used == 0) { - audplay_buffer_refresh(audio); - } else { - MM_DBG("read cannot keep up\n"); - audio->buf_refresh = 1; - } - wake_up(&audio->read_wait); - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - - getevent(msg, sizeof(msg)); - - MM_DBG("msg_id=%x\n", id); - - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audplay_send_data(audio, 1); - break; - - case AUDPLAY_MSG_BUFFER_UPDATE: - audio_update_pcm_buf_entry(audio, msg); - break; - - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audplaytask)\n"); - break; - - default: - MM_ERR("unexpected message from decoder \n"); - break; - } -} - -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status:sleep reason = \ - 0x%04x\n", reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init\n"); - if (audio->pcm_feedback) - audpp_cmd_cfg_routing_mode(audio); - else - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg\n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play \n"); - /* send mixer command */ - audpp_route_stream(audio->dec_id, - audio->source); - if (audio->pcm_feedback) { - audplay_config_hostpcm(audio); - audplay_buffer_refresh(audio); - } - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - default: - MM_ERR("unknown decoder status\n"); - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - audpp_dsp_set_eq(audio->dec_id, audio->eq_enable, - &audio->eq, POPP); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audio->running = 0; - } else { - MM_DBG("CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_ROUTING_ACK: - MM_DBG("ROUTING_ACK mode=%d\n", msg[1]); - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - audio->rflush = 0; - wake_up(&audio->write_wait); - if (audio->pcm_feedback) - audplay_buffer_refresh(audio); - break; - - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - - case AUDPP_MSG_AVSYNC_MSG: - MM_DBG("AUDPP_MSG_AVSYNC_MSG\n"); - memcpy(&audio->avsync[0], msg, sizeof(audio->avsync)); - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); - break; - - default: - MM_ERR("UNKNOWN (%d)\n", id); - } - -} - -static struct msm_adsp_ops audplay_adsp_ops_wma = { - .event = audplay_dsp_event, -}; - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id, \ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - struct audpp_cmd_cfg_dec_type cfg_dec_cmd; - - memset(&cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - - cfg_dec_cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE; - if (enable) - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_WMA; - else - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - cfg_dec_cmd.dm_mode = 0x0; - cfg_dec_cmd.stream_id = audio->dec_id; - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} - -static void audpp_cmd_cfg_adec_params(struct audio *audio) -{ - struct audpp_cmd_cfg_adec_params_wma cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_WMA_LEN; - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = audio->out_sample_rate; - - /* - * Test done for sample with the following configuration - * armdatareqthr = 1262 - * channelsdecoded = 1(MONO)/2(STEREO) - * wmabytespersec = Tested with 6003 Bytes per sec - * wmasamplingfreq = 44100 - * wmaencoderopts = 31 - */ - - cmd.armdatareqthr = audio->wma_config.armdatareqthr; - cmd.channelsdecoded = audio->wma_config.channelsdecoded; - cmd.wmabytespersec = audio->wma_config.wmabytespersec; - cmd.wmasamplingfreq = audio->wma_config.wmasamplingfreq; - cmd.wmaencoderopts = audio->wma_config.wmaencoderopts; - - audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static void audpp_cmd_cfg_routing_mode(struct audio *audio) -{ - struct audpp_cmd_routing_mode cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; - cmd.object_number = audio->dec_id; - if (audio->pcm_feedback) - cmd.routing_mode = ROUTING_MODE_FTRT; - else - cmd.routing_mode = ROUTING_MODE_RT; - - audpp_send_queue1(&cmd, sizeof(cmd)); -} - -static void audplay_buffer_refresh(struct audio *audio) -{ - struct audplay_cmd_buffer_refresh refresh_cmd; - - refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; - refresh_cmd.num_buffers = 1; - refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; - refresh_cmd.buf0_length = audio->in[audio->fill_next].size; - refresh_cmd.buf_read_count = 0; - - MM_DBG("buf0_addr=%x buf0_len=%d\n", - refresh_cmd.buf0_address, - refresh_cmd.buf0_length); - - (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); -} - -static void audplay_config_hostpcm(struct audio *audio) -{ - struct audplay_cmd_hpcm_buf_cfg cfg_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; - cfg_cmd.max_buffers = audio->pcm_buf_count; - cfg_cmd.byte_swap = 0; - cfg_cmd.hostpcm_config = (0x8000) | (0x4000); - cfg_cmd.feedback_frequency = 1; - cfg_cmd.partition_number = 0; - - (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); -} - - -static int audplay_dsp_send_data_avail(struct audio *audio, - unsigned idx, unsigned len) -{ - struct audplay_cmd_bitstream_data_avail_nt2 cmd; - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2; - if (!audio->pcm_feedback) - cmd.decoder_id = 0; - else { - if (audio->mfield) - cmd.decoder_id = AUDWMA_METAFIELD_MASK | - (audio->out[idx].mfield_sz >> 1); - else - cmd.decoder_id = audio->dec_id; - } - cmd.buf_ptr = audio->out[idx].addr; - cmd.buf_size = len/2; - cmd.partition_number = 0; - return audplay_send_queue0(audio, &cmd, sizeof(cmd)); -} - -static void audplay_send_data(struct audio *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (audio->wflush) { - audio->out_needed = 1; - goto done; - } - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - MM_DBG("\n"); /* Macro prints the file name and function */ - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - MM_DBG("frame %d busy\n", audio->out_tail); - audplay_dsp_send_data_avail(audio, audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } -done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ - -static void audio_flush(struct audio *audio) -{ - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->reserved = 0; - atomic_set(&audio->out_bytes, 0); -} - -static void audio_flush_pcm_buf(struct audio *audio) -{ - uint8_t index; - - for (index = 0; index < PCM_BUF_MAX_COUNT; index++) - audio->in[index].used = 0; - audio->buf_refresh = 0; - audio->read_next = 0; - audio->fill_next = 0; -} - -static void audio_ioport_reset(struct audio *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audio_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->read_wait); - mutex_lock(&audio->read_lock); - audio_flush_pcm_buf(audio); - mutex_unlock(&audio->read_lock); - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); -} - -static int audwma_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audwma_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audwma_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audwma_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audwma_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - -static long audwma_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audwma_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout( - audio->event_wait, audwma_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audwma_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - rc = 0; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audwma_event, list); - list_del(&drv_evt->list); - } - - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audio_enable_eq(struct audio *audio, int enable) -{ - if (audio->eq_enable == enable && !audio->eq_needs_commit) - return 0; - - audio->eq_enable = enable; - - if (audio->running) { - audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq, POPP); - audio->eq_needs_commit = 0; - } - return 0; -} - -static int audio_get_avsync_data(struct audio *audio, - struct msm_audio_stats *stats) -{ - int rc = -EINVAL; - unsigned long flags; - - local_irq_save(flags); - if (audio->dec_id == audio->avsync[0] && audio->avsync_flag) { - /* av_sync sample count */ - stats->sample_count = (audio->avsync[2] << 16) | - (audio->avsync[3]); - - /* av_sync byte_count */ - stats->byte_count = (audio->avsync[5] << 16) | - (audio->avsync[6]); - - audio->avsync_flag = 0; - rc = 0; - } - local_irq_restore(flags); - return rc; - -} - -static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - unsigned long flags = 0; - uint16_t enable_mask; - int enable; - int prev_state; - - MM_DBG("cmd = %d\n", cmd); - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - - audio->avsync_flag = 0; - memset(&stats, 0, sizeof(stats)); - if (audpp_query_avsync(audio->dec_id) < 0) - return rc; - - rc = wait_event_interruptible_timeout(audio->avsync_wait, - (audio->avsync_flag == 1), - msecs_to_jiffies(AUDPP_AVSYNC_EVENT_TIMEOUT)); - - if (rc < 0) - return rc; - else if ((rc > 0) || ((rc == 0) && (audio->avsync_flag == 1))) { - if (audio_get_avsync_data(audio, &stats) < 0) - return rc; - - if (copy_to_user((void *)arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } else - return -EAGAIN; - } - - switch (cmd) { - case AUDIO_ENABLE_AUDPP: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - spin_lock_irqsave(&audio->dsp_lock, flags); - enable = (enable_mask & EQ_ENABLE) ? 1 : 0; - audio_enable_eq(audio, enable); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - case AUDIO_SET_VOLUME: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.volume = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_PAN: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.pan = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_EQ: - prev_state = audio->eq_enable; - audio->eq_enable = 0; - if (copy_from_user(&audio->eq.num_bands, (void *) arg, - sizeof(audio->eq) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) { - rc = -EFAULT; - break; - } - audio->eq_enable = prev_state; - audio->eq_needs_commit = 1; - rc = 0; - break; - } - - if (-EINVAL != rc) - return rc; - - if (cmd == AUDIO_GET_EVENT) { - MM_DBG("AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audwma_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audio_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) - rc = -ENODEV; - else - rc = 0; - } - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audio_disable(audio); - audio->stopped = 1; - audio_ioport_reset(audio); - audio->stopped = 0; - break; - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audio_ioport_reset(audio); - if (audio->running) { - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - case AUDIO_SET_CONFIG: { - struct msm_audio_config config; - if (copy_from_user(&config, (void *) arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.channel_count == 1) { - config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V; - } else if (config.channel_count == 2) { - config.channel_count = AUDPP_CMD_PCM_INTF_STEREO_V; - } else { - rc = -EINVAL; - break; - } - audio->mfield = config.meta_field; - audio->out_sample_rate = config.sample_rate; - audio->out_channel_mode = config.channel_count; - rc = 0; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config config; - config.buffer_size = (audio->out_dma_sz >> 1); - config.buffer_count = 2; - config.sample_rate = audio->out_sample_rate; - if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) - config.channel_count = 1; - else - config.channel_count = 2; - config.meta_field = 0; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *) arg, &config, sizeof(config))) - rc = -EFAULT; - else - rc = 0; - - break; - } - case AUDIO_GET_WMA_CONFIG:{ - if (copy_to_user((void *)arg, &audio->wma_config, - sizeof(audio->wma_config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_WMA_CONFIG:{ - struct msm_audio_wma_config usr_config; - - if (copy_from_user - (&usr_config, (void *)arg, - sizeof(usr_config))) { - rc = -EFAULT; - break; - } - - audio->wma_config = usr_config; - rc = 0; - break; - } - case AUDIO_GET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - config.pcm_feedback = audio->pcm_feedback; - config.buffer_count = PCM_BUF_MAX_COUNT; - config.buffer_size = PCM_BUFSZ_MIN; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.pcm_feedback != audio->pcm_feedback) { - MM_ERR("Not sufficient permission to" - "change the playback mode\n"); - rc = -EACCES; - break; - } - if ((config.buffer_count > PCM_BUF_MAX_COUNT) || - (config.buffer_count == 1)) - config.buffer_count = PCM_BUF_MAX_COUNT; - - if (config.buffer_size < PCM_BUFSZ_MIN) - config.buffer_size = PCM_BUFSZ_MIN; - - /* Check if pcm feedback is required */ - if ((config.pcm_feedback) && (!audio->read_data)) { - MM_DBG("allocate PCM buffer %d\n", - config.buffer_count * - config.buffer_size); - audio->read_phys = - allocate_contiguous_ebi_nomap( - config.buffer_size * - config.buffer_count, - SZ_4K); - if (!audio->read_phys) { - rc = -ENOMEM; - break; - } - audio->map_v_read = ioremap( - audio->read_phys, - config.buffer_size * - config.buffer_count); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("read buf alloc fail\n"); - rc = -ENOMEM; - free_contiguous_memory_by_paddr( - audio->read_phys); - } else { - uint8_t index; - uint32_t offset = 0; - audio->read_data = - audio->map_v_read; - audio->buf_refresh = 0; - audio->pcm_buf_count = - config.buffer_count; - audio->read_next = 0; - audio->fill_next = 0; - - for (index = 0; - index < config.buffer_count; - index++) { - audio->in[index].data = - audio->read_data + offset; - audio->in[index].addr = - audio->read_phys + offset; - audio->in[index].size = - config.buffer_size; - audio->in[index].used = 0; - offset += config.buffer_size; - } - MM_DBG("read buf: phy addr \ - 0x%08x kernel addr 0x%08x\n", - audio->read_phys, - (int)audio->read_data); - rc = 0; - } - } else { - rc = 0; - } - break; - } - case AUDIO_PAUSE: - MM_DBG("AUDIO_PAUSE %ld\n", arg); - rc = audpp_pause(audio->dec_id, (int) arg); - break; - case AUDIO_GET_SESSION_ID: - if (copy_to_user((void *) arg, &audio->dec_id, - sizeof(unsigned short))) - rc = -EFAULT; - else - rc = 0; - break; - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -static int audio_fsync(struct file *file, loff_t ppos1, loff_t ppos2, int datasync) -{ - struct audio *audio = file->private_data; - struct buffer *frame; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (!audio->running || audio->pcm_feedback) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (audio->reserved) { - MM_DBG("send reserved byte\n"); - frame = audio->out + audio->out_tail; - ((char *) frame->data)[0] = audio->rsv_byte; - ((char *) frame->data)[1] = 0; - frame->used = 2; - audplay_send_data(audio, 0); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - } - - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush); - - if (audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; -} - -static ssize_t audio_read(struct file *file, char __user *buf, size_t count, - loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - int rc = 0; - - if (!audio->pcm_feedback) - return 0; /* PCM feedback is not enabled. Nothing to read */ - - mutex_lock(&audio->read_lock); - MM_DBG("%d \n", count); - while (count > 0) { - rc = wait_event_interruptible(audio->read_wait, - (audio->in[audio->read_next].used > 0) || - (audio->stopped) || (audio->rflush)); - - if (rc < 0) - break; - - if (audio->stopped || audio->rflush) { - rc = -EBUSY; - break; - } - - if (count < audio->in[audio->read_next].used) { - /* Read must happen in frame boundary. Since driver - does not know frame size, read count must be greater - or equal to size of PCM samples */ - MM_DBG("audio_read: no partial frame done reading\n"); - break; - } else { - MM_DBG("audio_read: read from in[%d]\n", - audio->read_next); - if (copy_to_user - (buf, audio->in[audio->read_next].data, - audio->in[audio->read_next].used)) { - MM_ERR("invalid addr %x \n", (unsigned int)buf); - rc = -EFAULT; - break; - } - count -= audio->in[audio->read_next].used; - buf += audio->in[audio->read_next].used; - audio->in[audio->read_next].used = 0; - if ((++audio->read_next) == audio->pcm_buf_count) - audio->read_next = 0; - break; /* Force to exit while loop - * to prevent output thread - * sleep too long if data is - * not ready at this moment. - */ - } - } - - /* don't feed output buffer to HW decoder during flushing - * buffer refresh command will be sent once flush completes - * send buf refresh command here can confuse HW decoder - */ - if (audio->buf_refresh && !audio->rflush) { - audio->buf_refresh = 0; - MM_DBG("kick start pcm feedback again\n"); - audplay_buffer_refresh(audio); - } - - mutex_unlock(&audio->read_lock); - - if (buf > start) - rc = buf - start; - - MM_DBG("read %d bytes\n", rc); - return rc; -} - -static int audwma_process_eos(struct audio *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - int rc = 0; - struct buffer *frame; - char *buf_ptr; - - if (audio->reserved) { - MM_DBG("flush reserve byte\n"); - frame = audio->out + audio->out_head; - buf_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - buf_ptr[0] = audio->rsv_byte; - buf_ptr[1] = 0; - audio->out_head ^= 1; - frame->mfield_sz = 0; - frame->used = 2; - audio->reserved = 0; - audplay_send_data(audio, 0); - } - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - audplay_send_data(audio, 0); -done: - return rc; -} - -static ssize_t audio_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - char *cpy_ptr; - int rc = 0, eos_condition = AUDWMA_EOS_NONE; - unsigned dsize; - unsigned short mfield_size = 0; - - MM_DBG("cnt=%d\n", count); - - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - cpy_ptr = frame->data; - dsize = 0; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - break; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - break; - } - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - break; - } else if (mfield_size > count) { - rc = -EINVAL; - break; - } - MM_DBG("audio_write: mf offset_val %x\n", - mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - break; - } - /* Check if EOS flag is set and buffer has - * contains just meta field - */ - if (cpy_ptr[AUDWMA_EOS_FLG_OFFSET] & - AUDWMA_EOS_FLG_MASK) { - MM_DBG("audio_write: EOS SET\n"); - eos_condition = AUDWMA_EOS_SET; - if (mfield_size == count) { - buf += mfield_size; - break; - } else - cpy_ptr[AUDWMA_EOS_FLG_OFFSET] - &= ~AUDWMA_EOS_FLG_MASK; - } - cpy_ptr += mfield_size; - count -= mfield_size; - dsize += mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("audio_write: continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - - if (audio->reserved) { - MM_DBG("append reserved byte %x\n", audio->rsv_byte); - *cpy_ptr = audio->rsv_byte; - xfer = (count > ((frame->size - mfield_size) - 1)) ? - (frame->size - mfield_size) - 1 : count; - cpy_ptr++; - dsize += 1; - audio->reserved = 0; - } else - xfer = (count > (frame->size - mfield_size)) ? - (frame->size - mfield_size) : count; - - if (copy_from_user(cpy_ptr, buf, xfer)) { - rc = -EFAULT; - break; - } - - dsize += xfer; - if (dsize & 1) { - audio->rsv_byte = ((char *) frame->data)[dsize - 1]; - MM_DBG("odd length buf reserve last byte %x\n", - audio->rsv_byte); - audio->reserved = 1; - dsize--; - } - count -= xfer; - buf += xfer; - - if (dsize > 0) { - audio->out_head ^= 1; - frame->used = dsize; - audplay_send_data(audio, 0); - } - } - if (eos_condition == AUDWMA_EOS_SET) - rc = audwma_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - if (!rc) { - if (buf > start) - return buf - start; - } - return rc; -} - -static int audio_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_INFO("audio instance 0x%08x freeing\n", (int)audio); - mutex_lock(&audio->lock); - auddev_unregister_evt_listner(AUDDEV_CLNT_DEC, audio->dec_id); - audio_disable(audio); - audio_flush(audio); - audio_flush_pcm_buf(audio); - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->event_abort = 1; - wake_up(&audio->event_wait); - audwma_reset_event_queue(audio); - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - if (audio->read_data) { - iounmap(audio->map_v_read); - free_contiguous_memory_by_paddr(audio->read_phys); - } - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - kfree(audio); - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audwma_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audwma_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audwma_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audwma_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -static void audwma_suspend(struct early_suspend *h) -{ - struct audwma_suspend_ctl *ctl = - container_of(h, struct audwma_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audwma_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audwma_resume(struct early_suspend *h) -{ - struct audwma_suspend_ctl *ctl = - container_of(h, struct audwma_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audwma_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audwma_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audwma_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 4096; - static char buffer[4096]; - int n = 0, i; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_feedback %d\n", audio->pcm_feedback); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_buf_sz %d\n", audio->out[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_count %d \n", audio->pcm_buf_count); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_sz %d \n", audio->in[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %x \n", audio->vol_pan.volume); - n += scnprintf(buffer + n, debug_bufmax - n, - "sample rate %d \n", audio->out_sample_rate); - n += scnprintf(buffer + n, debug_bufmax - n, - "channel mode %d \n", audio->out_channel_mode); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "rflush %d\n", audio->rflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d \n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d \n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d \n", audio->out_needed); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_head %d \n", audio->out_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_tail %d \n", audio->out_tail); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[0].used %d \n", audio->out[0].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[1].used %d \n", audio->out[1].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "buffer_refresh %d \n", audio->buf_refresh); - n += scnprintf(buffer + n, debug_bufmax - n, - "read_next %d \n", audio->read_next); - n += scnprintf(buffer + n, debug_bufmax - n, - "fill_next %d \n", audio->fill_next); - for (i = 0; i < audio->pcm_buf_count; i++) - n += scnprintf(buffer + n, debug_bufmax - n, - "in[%d].size %d \n", i, audio->in[i].used); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audwma_debug_fops = { - .read = audwma_debug_read, - .open = audwma_debug_open, -}; -#endif - -static int audio_open(struct inode *inode, struct file *file) -{ - struct audio *audio = NULL; - int rc, dec_attrb, decid, i; - unsigned pmem_sz = DMASZ_MAX; - struct audwma_event *e_node = NULL; -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_wma_" + 5]; -#endif - - /* Allocate Mem for audio instance */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("no memory to allocate audio instance \n"); - rc = -ENOMEM; - goto done; - } - MM_INFO("audio instance 0x%08x created\n", (int)audio); - - /* Allocate the decoder */ - dec_attrb = AUDDEC_DEC_WMA; - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_NONTUNNEL; - audio->pcm_feedback = NON_TUNNEL_MODE_PLAYBACK; - } else if ((file->f_mode & FMODE_WRITE) && - !(file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_TUNNEL; - audio->pcm_feedback = TUNNEL_MODE_PLAYBACK; - } else { - kfree(audio); - rc = -EACCES; - goto done; - } - - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - - if (decid < 0) { - MM_ERR("No free decoder available, freeing instance 0x%08x\n", - (int)audio); - rc = -ENODEV; - kfree(audio); - goto done; - } - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - while (pmem_sz >= DMASZ_MIN) { - MM_DBG("pmemsz = %d\n", pmem_sz); - audio->phys = allocate_contiguous_ebi_nomap(pmem_sz, SZ_4K); - if (audio->phys) { - audio->map_v_write = ioremap(audio->phys, pmem_sz); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not allocate write buffers, \ - freeing instance 0x%08x\n", - (int)audio); - rc = -ENOMEM; - free_contiguous_memory_by_paddr(audio->phys); - audpp_adec_free(audio->dec_id); - kfree(audio); - goto done; - } - audio->data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr \ - 0x%08x\n", audio->phys, (int)audio->data); - break; - } else if (pmem_sz == DMASZ_MIN) { - MM_ERR("could not allocate write buffers, freeing \ - instance 0x%08x\n", (int)audio); - rc = -ENOMEM; - audpp_adec_free(audio->dec_id); - kfree(audio); - goto done; - } else - pmem_sz >>= 1; - } - audio->out_dma_sz = pmem_sz; - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audplay_adsp_ops_wma, audio); - if (rc) { - MM_ERR("failed to get %s module, freeing instance 0x%08x\n", - audio->module_name, (int)audio); - goto err; - } - - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->read_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - init_waitqueue_head(&audio->write_wait); - init_waitqueue_head(&audio->read_wait); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - spin_lock_init(&audio->event_queue_lock); - init_waitqueue_head(&audio->avsync_wait); - - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = audio->out_dma_sz >> 1; - - audio->out[1].data = audio->data + audio->out[0].size; - audio->out[1].addr = audio->phys + audio->out[0].size; - audio->out[1].size = audio->out[0].size; - - audio->wma_config.armdatareqthr = 1262; - audio->wma_config.channelsdecoded = 2; - audio->wma_config.wmabytespersec = 6003; - audio->wma_config.wmasamplingfreq = 44100; - audio->wma_config.wmaencoderopts = 31; - - audio->out_sample_rate = 44100; - audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V; - - audio->vol_pan.volume = 0x2000; - - audio_flush(audio); - - file->private_data = audio; - audio->opened = 1; - - audio->device_events = AUDDEV_EVT_DEV_RDY - |AUDDEV_EVT_DEV_RLS| - AUDDEV_EVT_STREAM_VOL_CHG; - - rc = auddev_register_evt_listner(audio->device_events, - AUDDEV_CLNT_DEC, - audio->dec_id, - wma_listner, - (void *)audio); - if (rc) { - MM_ERR("%s: failed to register listner\n", __func__); - goto event_err; - } - -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_wma_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, - &audwma_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audwma_resume; - audio->suspend_ctl.node.suspend = audwma_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (i = 0; i < AUDWMA_EVENT_NUM; i++) { - e_node = kmalloc(sizeof(struct audwma_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } -done: - return rc; -event_err: - msm_adsp_put(audio->audplay); -err: - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - audpp_adec_free(audio->dec_id); - kfree(audio); - return rc; -} - -static const struct file_operations audio_wma_fops = { - .owner = THIS_MODULE, - .open = audio_open, - .release = audio_release, - .read = audio_read, - .write = audio_write, - .unlocked_ioctl = audio_ioctl, - .fsync = audio_fsync, -}; - -struct miscdevice audio_wma_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_wma", - .fops = &audio_wma_fops, -}; - -static int __init audio_init(void) -{ - return misc_register(&audio_wma_misc); -} - -device_initcall(audio_init); diff --git a/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c b/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c deleted file mode 100644 index 84cfed6af9823d762c243c44fda6f3a9803ec73d..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c +++ /dev/null @@ -1,1815 +0,0 @@ -/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. - * - * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c - * - * Copyright (C) 2008 Google, Inc. - * Copyright (C) 2008 HTC Corporation - * - * All source code in this file is licensed under the following license except - * where indicated. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* Size must be power of 2 */ -#define BUFSZ_MAX 4110 /* Includes meta in size */ -#define BUFSZ_MIN 2062 /* Includes meta in size */ -#define DMASZ_MAX (BUFSZ_MAX * 2) -#define DMASZ_MIN (BUFSZ_MIN * 2) - -#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF -#define AUDDEC_DEC_WMAPRO 13 - -#define PCM_BUFSZ_MIN 8216 /* Hold one stereo WMAPRO frame and meta out*/ -#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most - but support 2 buffers currently */ -#define ROUTING_MODE_FTRT 1 -#define ROUTING_MODE_RT 2 -/* Decoder status received from AUDPPTASK */ -#define AUDPP_DEC_STATUS_SLEEP 0 -#define AUDPP_DEC_STATUS_INIT 1 -#define AUDPP_DEC_STATUS_CFG 2 -#define AUDPP_DEC_STATUS_PLAY 3 - -#define AUDWMAPRO_METAFIELD_MASK 0xFFFF0000 -#define AUDWMAPRO_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */ -#define AUDWMAPRO_EOS_FLG_MASK 0x01 -#define AUDWMAPRO_EOS_NONE 0x0 /* No EOS detected */ -#define AUDWMAPRO_EOS_SET 0x1 /* EOS set in meta field */ - -#define AUDWMAPRO_EVENT_NUM 10 /* Default no. of pre-allocated event packets */ - -struct buffer { - void *data; - unsigned size; - unsigned used; /* Input usage actual DSP produced PCM size */ - unsigned addr; - unsigned short mfield_sz; /*only useful for data has meta field */ -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -struct audwmapro_suspend_ctl { - struct early_suspend node; - struct audio *audio; -}; -#endif - -struct audwmapro_event{ - struct list_head list; - int event_type; - union msm_audio_event_payload payload; -}; - -struct audio { - struct buffer out[2]; - - spinlock_t dsp_lock; - - uint8_t out_head; - uint8_t out_tail; - uint8_t out_needed; /* number of buffers the dsp is waiting for */ - unsigned out_dma_sz; - - atomic_t out_bytes; - - struct mutex lock; - struct mutex write_lock; - wait_queue_head_t write_wait; - - /* Host PCM section */ - struct buffer in[PCM_BUF_MAX_COUNT]; - struct mutex read_lock; - wait_queue_head_t read_wait; /* Wait queue for read */ - char *read_data; /* pointer to reader buffer */ - int32_t read_phys; /* physical address of reader buffer */ - uint8_t read_next; /* index to input buffers to be read next */ - uint8_t fill_next; /* index to buffer that DSP should be filling */ - uint8_t pcm_buf_count; /* number of pcm buffer allocated */ - /* ---- End of Host PCM section */ - - struct msm_adsp_module *audplay; - - /* configuration to use on next enable */ - uint32_t out_sample_rate; - uint32_t out_channel_mode; - - struct msm_audio_wmapro_config wmapro_config; - - /* data allocated for various buffers */ - char *data; - int32_t phys; /* physical address of write buffer */ - void *map_v_read; - void *map_v_write; - - int mfield; /* meta field embedded in data */ - int rflush; /* Read flush */ - int wflush; /* Write flush */ - int opened; - int enabled; - int running; - int stopped; /* set when stopped, cleared on flush */ - int pcm_feedback; - int buf_refresh; - int teos; /* valid only if tunnel mode & no data left for decoder */ - enum msm_aud_decoder_state dec_state; /* Represents decoder state */ - int reserved; /* A byte is being reserved */ - char rsv_byte; /* Handle odd length user data */ - - const char *module_name; - unsigned queue_id; - uint16_t dec_id; - uint32_t read_ptr_offset; - int16_t source; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct audwmapro_suspend_ctl suspend_ctl; -#endif - -#ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -#endif - - wait_queue_head_t wait; - struct list_head free_event_queue; - struct list_head event_queue; - wait_queue_head_t event_wait; - spinlock_t event_queue_lock; - struct mutex get_event_lock; - int event_abort; - /* AV sync Info */ - int avsync_flag; /* Flag to indicate feedback from DSP */ - wait_queue_head_t avsync_wait;/* Wait queue for AV Sync Message */ - /* flags, 48 bits sample/bytes counter per channel */ - uint16_t avsync[AUDPP_AVSYNC_CH_COUNT * AUDPP_AVSYNC_NUM_WORDS + 1]; - - uint32_t device_events; - - int eq_enable; - int eq_needs_commit; - struct audpp_cmd_cfg_object_params_eqalizer eq; - struct audpp_cmd_cfg_object_params_volume vol_pan; -}; - -static int auddec_dsp_config(struct audio *audio, int enable); -static void audpp_cmd_cfg_adec_params(struct audio *audio); -static void audpp_cmd_cfg_routing_mode(struct audio *audio); -static void audplay_send_data(struct audio *audio, unsigned needed); -static void audplay_config_hostpcm(struct audio *audio); -static void audplay_buffer_refresh(struct audio *audio); -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg); -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audwmapro_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload); -#endif - -/* must be called with audio->lock held */ -static int audio_enable(struct audio *audio) -{ - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) - return 0; - - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - audio->out_tail = 0; - audio->out_needed = 0; - - if (msm_adsp_enable(audio->audplay)) { - MM_ERR("msm_adsp_enable(audplay) failed\n"); - return -ENODEV; - } - - if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) { - MM_ERR("audpp_enable() failed\n"); - msm_adsp_disable(audio->audplay); - return -ENODEV; - } - - audio->enabled = 1; - return 0; -} - -static void wmapro_listner(u32 evt_id, union auddev_evt_data *evt_payload, - void *private_data) -{ - struct audio *audio = (struct audio *) private_data; - switch (evt_id) { - case AUDDEV_EVT_DEV_RDY: - MM_DBG(":AUDDEV_EVT_DEV_RDY\n"); - audio->source |= (0x1 << evt_payload->routing_id); - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - break; - case AUDDEV_EVT_DEV_RLS: - MM_DBG(":AUDDEV_EVT_DEV_RLS\n"); - audio->source &= ~(0x1 << evt_payload->routing_id); - if (audio->running == 1 && audio->enabled == 1) - audpp_route_stream(audio->dec_id, audio->source); - break; - case AUDDEV_EVT_STREAM_VOL_CHG: - audio->vol_pan.volume = evt_payload->session_vol; - MM_DBG(":AUDDEV_EVT_STREAM_VOL_CHG, stream vol %d\n", - audio->vol_pan.volume); - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - break; - default: - MM_ERR(":ERROR:wrong event\n"); - break; - } -} - -/* must be called with audio->lock held */ -static int audio_disable(struct audio *audio) -{ - int rc = 0; - MM_DBG("\n"); /* Macro prints the file name and function */ - if (audio->enabled) { - audio->enabled = 0; - audio->dec_state = MSM_AUD_DECODER_STATE_NONE; - auddec_dsp_config(audio, 0); - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - if (rc == 0) - rc = -ETIMEDOUT; - else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE) - rc = -EFAULT; - else - rc = 0; - wake_up(&audio->write_wait); - wake_up(&audio->read_wait); - msm_adsp_disable(audio->audplay); - audpp_disable(audio->dec_id, audio); - audio->out_needed = 0; - } - return rc; -} - -/* ------------------- dsp --------------------- */ -static void audio_update_pcm_buf_entry(struct audio *audio, - uint32_t *payload) -{ - uint8_t index; - unsigned long flags; - - if (audio->rflush) - return; - - spin_lock_irqsave(&audio->dsp_lock, flags); - for (index = 0; index < payload[1]; index++) { - if (audio->in[audio->fill_next].addr == - payload[2 + index * 2]) { - MM_DBG("audio_update_pcm_buf_entry: \ - in[%d] ready\n", audio->fill_next); - audio->in[audio->fill_next].used = - payload[3 + index * 2]; - if ((++audio->fill_next) == audio->pcm_buf_count) - audio->fill_next = 0; - } else { - MM_ERR("audio_update_pcm_buf_entry: \ - expected=%x ret=%x\n", - audio->in[audio->fill_next].addr, - payload[1 + index * 2]); - break; - } - } - if (audio->in[audio->fill_next].used == 0) { - audplay_buffer_refresh(audio); - } else { - MM_DBG("read cannot keep up\n"); - audio->buf_refresh = 1; - } - wake_up(&audio->read_wait); - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -static void audplay_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audio *audio = data; - uint32_t msg[28]; - - getevent(msg, sizeof(msg)); - - MM_DBG("msg_id=%x\n", id); - - switch (id) { - case AUDPLAY_MSG_DEC_NEEDS_DATA: - audplay_send_data(audio, 1); - break; - - case AUDPLAY_MSG_BUFFER_UPDATE: - audio_update_pcm_buf_entry(audio, msg); - break; - - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable(audplaytask)\n"); - break; - - default: - MM_ERR("unexpected message from decoder \n"); - break; - } -} - -static void audio_dsp_event(void *private, unsigned id, uint16_t *msg) -{ - struct audio *audio = private; - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned status = msg[1]; - - switch (status) { - case AUDPP_DEC_STATUS_SLEEP: { - uint16_t reason = msg[2]; - MM_DBG("decoder status:sleep reason = \ - 0x%04x\n", reason); - if ((reason == AUDPP_MSG_REASON_MEM) - || (reason == - AUDPP_MSG_REASON_NODECODER)) { - audio->dec_state = - MSM_AUD_DECODER_STATE_FAILURE; - wake_up(&audio->wait); - } else if (reason == AUDPP_MSG_REASON_NONE) { - /* decoder is in disable state */ - audio->dec_state = - MSM_AUD_DECODER_STATE_CLOSE; - wake_up(&audio->wait); - } - break; - } - case AUDPP_DEC_STATUS_INIT: - MM_DBG("decoder status: init\n"); - if (audio->pcm_feedback) - audpp_cmd_cfg_routing_mode(audio); - else - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_DEC_STATUS_CFG: - MM_DBG("decoder status: cfg\n"); - break; - case AUDPP_DEC_STATUS_PLAY: - MM_DBG("decoder status: play \n"); - audpp_route_stream(audio->dec_id, - audio->source); - if (audio->pcm_feedback) { - audplay_config_hostpcm(audio); - audplay_buffer_refresh(audio); - } - audio->dec_state = - MSM_AUD_DECODER_STATE_SUCCESS; - wake_up(&audio->wait); - break; - default: - MM_ERR("unknown decoder status\n"); - } - break; - } - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_DBG("CFG_MSG ENABLE\n"); - auddec_dsp_config(audio, 1); - audio->out_needed = 0; - audio->running = 1; - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - audpp_dsp_set_eq(audio->dec_id, audio->eq_enable, - &audio->eq, POPP); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_DBG("CFG_MSG DISABLE\n"); - audio->running = 0; - } else { - MM_DBG("CFG_MSG %d?\n", msg[0]); - } - break; - case AUDPP_MSG_ROUTING_ACK: - MM_DBG("ROUTING_ACK mode=%d\n", msg[1]); - audpp_cmd_cfg_adec_params(audio); - break; - - case AUDPP_MSG_FLUSH_ACK: - MM_DBG("FLUSH_ACK\n"); - audio->wflush = 0; - audio->rflush = 0; - wake_up(&audio->write_wait); - if (audio->pcm_feedback) - audplay_buffer_refresh(audio); - break; - - case AUDPP_MSG_PCMDMAMISSED: - MM_DBG("PCMDMAMISSED\n"); - audio->teos = 1; - wake_up(&audio->write_wait); - break; - - case AUDPP_MSG_AVSYNC_MSG: - MM_DBG("AUDPP_MSG_AVSYNC_MSG\n"); - memcpy(&audio->avsync[0], msg, sizeof(audio->avsync)); - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); - break; - - default: - MM_ERR("UNKNOWN (%d)\n", id); - } - -} - -static struct msm_adsp_ops audplay_adsp_ops_wmapro = { - .event = audplay_dsp_event, -}; - -#define audplay_send_queue0(audio, cmd, len) \ - msm_adsp_write(audio->audplay, audio->queue_id, \ - cmd, len) - -static int auddec_dsp_config(struct audio *audio, int enable) -{ - struct audpp_cmd_cfg_dec_type cfg_dec_cmd; - - memset(&cfg_dec_cmd, 0, sizeof(cfg_dec_cmd)); - - cfg_dec_cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE; - if (enable) - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_WMAPRO; - else - cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | - AUDPP_CMD_DIS_DEC_V; - cfg_dec_cmd.dm_mode = 0x0; - cfg_dec_cmd.stream_id = audio->dec_id; - return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd)); -} - -static void audpp_cmd_cfg_adec_params(struct audio *audio) -{ - struct audpp_cmd_cfg_adec_params_wmapro cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_WMAPRO_LEN; - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = audio->out_sample_rate; - - /* - * Test done for sample with the following configuration - * armdatareqthr = 1262 - * channelsdecoded = 1(MONO)/2(STEREO) - * wmaprobytespersec = Tested with 6003 Bytes per sec - * wmaprosamplingfreq = 44100 - * wmaproencoderopts = 31 - */ - - cmd.armdatareqthr = audio->wmapro_config.armdatareqthr; - cmd.numchannels = audio->wmapro_config.numchannels; - cmd.validbitspersample = audio->wmapro_config.validbitspersample; - cmd.formattag = audio->wmapro_config.formattag; - cmd.samplingrate = audio->wmapro_config.samplingrate; - cmd.avgbytespersecond = audio->wmapro_config.avgbytespersecond; - cmd.asfpacketlength = audio->wmapro_config.asfpacketlength; - cmd.channelmask = audio->wmapro_config.channelmask; - cmd.encodeopt = audio->wmapro_config.encodeopt; - cmd.advancedencodeopt = audio->wmapro_config.advancedencodeopt; - cmd.advancedencodeopt2 = audio->wmapro_config.advancedencodeopt2; - - audpp_send_queue2(&cmd, sizeof(cmd)); -} - -static void audpp_cmd_cfg_routing_mode(struct audio *audio) -{ - struct audpp_cmd_routing_mode cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; - cmd.object_number = audio->dec_id; - if (audio->pcm_feedback) - cmd.routing_mode = ROUTING_MODE_FTRT; - else - cmd.routing_mode = ROUTING_MODE_RT; - - audpp_send_queue1(&cmd, sizeof(cmd)); -} - -static void audplay_buffer_refresh(struct audio *audio) -{ - struct audplay_cmd_buffer_refresh refresh_cmd; - - refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; - refresh_cmd.num_buffers = 1; - refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; - refresh_cmd.buf0_length = audio->in[audio->fill_next].size; - refresh_cmd.buf_read_count = 0; - - MM_DBG("buf0_addr=%x buf0_len=%d\n", - refresh_cmd.buf0_address, - refresh_cmd.buf0_length); - - (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); -} - -static void audplay_config_hostpcm(struct audio *audio) -{ - struct audplay_cmd_hpcm_buf_cfg cfg_cmd; - - MM_DBG("\n"); /* Macro prints the file name and function */ - cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; - cfg_cmd.max_buffers = audio->pcm_buf_count; - cfg_cmd.byte_swap = 0; - cfg_cmd.hostpcm_config = (0x8000) | (0x4000); - cfg_cmd.feedback_frequency = 1; - cfg_cmd.partition_number = 0; - - (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); -} - - -static int audplay_dsp_send_data_avail(struct audio *audio, - unsigned idx, unsigned len) -{ - struct audplay_cmd_bitstream_data_avail_nt2 cmd; - - cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2; - if (audio->mfield) - cmd.decoder_id = AUDWMAPRO_METAFIELD_MASK | - (audio->out[idx].mfield_sz >> 1); - else - cmd.decoder_id = audio->dec_id; - cmd.buf_ptr = audio->out[idx].addr; - cmd.buf_size = len/2; - cmd.partition_number = 0; - return audplay_send_queue0(audio, &cmd, sizeof(cmd)); -} - -static void audplay_send_data(struct audio *audio, unsigned needed) -{ - struct buffer *frame; - unsigned long flags; - - spin_lock_irqsave(&audio->dsp_lock, flags); - if (!audio->running) - goto done; - - if (audio->wflush) { - audio->out_needed = 1; - goto done; - } - - if (needed && !audio->wflush) { - /* We were called from the callback because the DSP - * requested more data. Note that the DSP does want - * more data, and if a buffer was in-flight, mark it - * as available (since the DSP must now be done with - * it). - */ - audio->out_needed = 1; - frame = audio->out + audio->out_tail; - if (frame->used == 0xffffffff) { - MM_DBG("frame %d free\n", audio->out_tail); - frame->used = 0; - audio->out_tail ^= 1; - wake_up(&audio->write_wait); - } - } - - if (audio->out_needed) { - /* If the DSP currently wants data and we have a - * buffer available, we will send it and reset - * the needed flag. We'll mark the buffer as in-flight - * so that it won't be recycled until the next buffer - * is requested - */ - - MM_DBG("\n"); /* Macro prints the file name and function */ - frame = audio->out + audio->out_tail; - if (frame->used) { - BUG_ON(frame->used == 0xffffffff); - MM_DBG("frame %d busy\n", audio->out_tail); - audplay_dsp_send_data_avail(audio, audio->out_tail, - frame->used); - frame->used = 0xffffffff; - audio->out_needed = 0; - } - } -done: - spin_unlock_irqrestore(&audio->dsp_lock, flags); -} - -/* ------------------- device --------------------- */ - -static void audio_flush(struct audio *audio) -{ - audio->out[0].used = 0; - audio->out[1].used = 0; - audio->out_head = 0; - audio->out_tail = 0; - audio->reserved = 0; - atomic_set(&audio->out_bytes, 0); -} - -static void audio_flush_pcm_buf(struct audio *audio) -{ - uint8_t index; - - for (index = 0; index < PCM_BUF_MAX_COUNT; index++) - audio->in[index].used = 0; - audio->buf_refresh = 0; - audio->read_next = 0; - audio->fill_next = 0; -} - -static void audio_ioport_reset(struct audio *audio) -{ - /* Make sure read/write thread are free from - * sleep and knowing that system is not able - * to process io request at the moment - */ - wake_up(&audio->write_wait); - mutex_lock(&audio->write_lock); - audio_flush(audio); - mutex_unlock(&audio->write_lock); - wake_up(&audio->read_wait); - mutex_lock(&audio->read_lock); - audio_flush_pcm_buf(audio); - mutex_unlock(&audio->read_lock); - audio->avsync_flag = 1; - wake_up(&audio->avsync_wait); -} - -static int audwmapro_events_pending(struct audio *audio) -{ - unsigned long flags; - int empty; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - empty = !list_empty(&audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - return empty || audio->event_abort; -} - -static void audwmapro_reset_event_queue(struct audio *audio) -{ - unsigned long flags; - struct audwmapro_event *drv_evt; - struct list_head *ptr, *next; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - list_for_each_safe(ptr, next, &audio->event_queue) { - drv_evt = list_first_entry(&audio->event_queue, - struct audwmapro_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - list_for_each_safe(ptr, next, &audio->free_event_queue) { - drv_evt = list_first_entry(&audio->free_event_queue, - struct audwmapro_event, list); - list_del(&drv_evt->list); - kfree(drv_evt); - } - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - return; -} - -static long audwmapro_process_event_req(struct audio *audio, void __user *arg) -{ - long rc; - struct msm_audio_event usr_evt; - struct audwmapro_event *drv_evt = NULL; - int timeout; - unsigned long flags; - - if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) - return -EFAULT; - - timeout = (int) usr_evt.timeout_ms; - - if (timeout > 0) { - rc = wait_event_interruptible_timeout(audio->event_wait, - audwmapro_events_pending(audio), - msecs_to_jiffies(timeout)); - if (rc == 0) - return -ETIMEDOUT; - } else { - rc = wait_event_interruptible( - audio->event_wait, audwmapro_events_pending(audio)); - } - - if (rc < 0) - return rc; - - if (audio->event_abort) { - audio->event_abort = 0; - return -ENODEV; - } - - rc = 0; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - if (!list_empty(&audio->event_queue)) { - drv_evt = list_first_entry(&audio->event_queue, - struct audwmapro_event, list); - list_del(&drv_evt->list); - } - - if (drv_evt) { - usr_evt.event_type = drv_evt->event_type; - usr_evt.event_payload = drv_evt->payload; - list_add_tail(&drv_evt->list, &audio->free_event_queue); - } else - rc = -1; - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - - if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt))) - rc = -EFAULT; - - return rc; -} - -static int audio_enable_eq(struct audio *audio, int enable) -{ - if (audio->eq_enable == enable && !audio->eq_needs_commit) - return 0; - - audio->eq_enable = enable; - - if (audio->running) { - audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq, POPP); - audio->eq_needs_commit = 0; - } - return 0; -} - -static int audio_get_avsync_data(struct audio *audio, - struct msm_audio_stats *stats) -{ - int rc = -EINVAL; - unsigned long flags; - - local_irq_save(flags); - if (audio->dec_id == audio->avsync[0] && audio->avsync_flag) { - /* av_sync sample count */ - stats->sample_count = (audio->avsync[2] << 16) | - (audio->avsync[3]); - - /* av_sync byte_count */ - stats->byte_count = (audio->avsync[5] << 16) | - (audio->avsync[6]); - - audio->avsync_flag = 0; - rc = 0; - } - local_irq_restore(flags); - return rc; - -} - -static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct audio *audio = file->private_data; - int rc = -EINVAL; - unsigned long flags = 0; - uint16_t enable_mask; - int enable; - int prev_state; - - MM_DBG("cmd = %d\n", cmd); - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - - audio->avsync_flag = 0; - memset(&stats, 0, sizeof(stats)); - if (audpp_query_avsync(audio->dec_id) < 0) - return rc; - - rc = wait_event_interruptible_timeout(audio->avsync_wait, - (audio->avsync_flag == 1), - msecs_to_jiffies(AUDPP_AVSYNC_EVENT_TIMEOUT)); - - if (rc < 0) - return rc; - else if ((rc > 0) || ((rc == 0) && (audio->avsync_flag == 1))) { - if (audio_get_avsync_data(audio, &stats) < 0) - return rc; - - if (copy_to_user((void *)arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } else - return -EAGAIN; - } - - switch (cmd) { - case AUDIO_ENABLE_AUDPP: - if (copy_from_user(&enable_mask, (void *) arg, - sizeof(enable_mask))) { - rc = -EFAULT; - break; - } - - spin_lock_irqsave(&audio->dsp_lock, flags); - enable = (enable_mask & EQ_ENABLE) ? 1 : 0; - audio_enable_eq(audio, enable); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - case AUDIO_SET_VOLUME: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.volume = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_PAN: - spin_lock_irqsave(&audio->dsp_lock, flags); - audio->vol_pan.pan = arg; - if (audio->running) - audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan, - POPP); - spin_unlock_irqrestore(&audio->dsp_lock, flags); - rc = 0; - break; - - case AUDIO_SET_EQ: - prev_state = audio->eq_enable; - audio->eq_enable = 0; - if (copy_from_user(&audio->eq.num_bands, (void *) arg, - sizeof(audio->eq) - - (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) { - rc = -EFAULT; - break; - } - audio->eq_enable = prev_state; - audio->eq_needs_commit = 1; - rc = 0; - break; - } - - if (-EINVAL != rc) - return rc; - - if (cmd == AUDIO_GET_EVENT) { - MM_DBG("AUDIO_GET_EVENT\n"); - if (mutex_trylock(&audio->get_event_lock)) { - rc = audwmapro_process_event_req(audio, - (void __user *) arg); - mutex_unlock(&audio->get_event_lock); - } else - rc = -EBUSY; - return rc; - } - - if (cmd == AUDIO_ABORT_GET_EVENT) { - audio->event_abort = 1; - wake_up(&audio->event_wait); - return 0; - } - - mutex_lock(&audio->lock); - switch (cmd) { - case AUDIO_START: - MM_DBG("AUDIO_START\n"); - rc = audio_enable(audio); - if (!rc) { - rc = wait_event_interruptible_timeout(audio->wait, - audio->dec_state != MSM_AUD_DECODER_STATE_NONE, - msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS)); - MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc); - - if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS) - rc = -ENODEV; - else - rc = 0; - } - break; - case AUDIO_STOP: - MM_DBG("AUDIO_STOP\n"); - rc = audio_disable(audio); - audio->stopped = 1; - audio_ioport_reset(audio); - audio->stopped = 0; - break; - case AUDIO_FLUSH: - MM_DBG("AUDIO_FLUSH\n"); - audio->rflush = 1; - audio->wflush = 1; - audio_ioport_reset(audio); - if (audio->running) { - audpp_flush(audio->dec_id); - rc = wait_event_interruptible(audio->write_wait, - !audio->wflush); - if (rc < 0) { - MM_ERR("AUDIO_FLUSH interrupted\n"); - rc = -EINTR; - } - } else { - audio->rflush = 0; - audio->wflush = 0; - } - break; - case AUDIO_SET_CONFIG: { - struct msm_audio_config config; - if (copy_from_user(&config, (void *) arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.channel_count == 1) { - config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V; - } else if (config.channel_count == 2) { - config.channel_count = AUDPP_CMD_PCM_INTF_STEREO_V; - } else { - rc = -EINVAL; - break; - } - audio->mfield = config.meta_field; - audio->out_sample_rate = config.sample_rate; - audio->out_channel_mode = config.channel_count; - rc = 0; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config config; - config.buffer_size = (audio->out_dma_sz >> 1); - config.buffer_count = 2; - config.sample_rate = audio->out_sample_rate; - if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) - config.channel_count = 1; - else - config.channel_count = 2; - config.meta_field = 0; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *) arg, &config, sizeof(config))) - rc = -EFAULT; - else - rc = 0; - - break; - } - case AUDIO_GET_WMAPRO_CONFIG:{ - if (copy_to_user((void *)arg, &audio->wmapro_config, - sizeof(audio->wmapro_config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_WMAPRO_CONFIG:{ - struct msm_audio_wmapro_config usr_config; - - if (copy_from_user - (&usr_config, (void *)arg, - sizeof(usr_config))) { - rc = -EFAULT; - break; - } - - audio->wmapro_config = usr_config; - - /* Need to swap the first and last words of advancedencodeopt2 - * as DSP cannot read 32-bit variable at a time. Need to be - * split into two 16-bit and swap them as required by DSP */ - - audio->wmapro_config.advancedencodeopt2 = - ((audio->wmapro_config.advancedencodeopt2 & 0xFFFF0000) - >> 16) | ((audio->wmapro_config.advancedencodeopt2 - << 16) & 0xFFFF0000); - rc = 0; - break; - } - case AUDIO_GET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - config.pcm_feedback = audio->pcm_feedback; - config.buffer_count = PCM_BUF_MAX_COUNT; - config.buffer_size = PCM_BUFSZ_MIN; - if (copy_to_user((void *)arg, &config, - sizeof(config))) - rc = -EFAULT; - else - rc = 0; - break; - } - case AUDIO_SET_PCM_CONFIG:{ - struct msm_audio_pcm_config config; - if (copy_from_user - (&config, (void *)arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.pcm_feedback != audio->pcm_feedback) { - MM_ERR("Not sufficient permission to" - "change the playback mode\n"); - rc = -EACCES; - break; - } - if ((config.buffer_count > PCM_BUF_MAX_COUNT) || - (config.buffer_count == 1)) - config.buffer_count = PCM_BUF_MAX_COUNT; - - if (config.buffer_size < PCM_BUFSZ_MIN) - config.buffer_size = PCM_BUFSZ_MIN; - - /* Check if pcm feedback is required */ - if ((config.pcm_feedback) && (!audio->read_data)) { - MM_DBG("allocate PCM buffer %d\n", - config.buffer_count * - config.buffer_size); - audio->read_phys = - allocate_contiguous_ebi_nomap( - config.buffer_size * - config.buffer_count, - SZ_4K); - if (!audio->read_phys) { - rc = -ENOMEM; - break; - } - audio->map_v_read = ioremap( - audio->read_phys, - config.buffer_size * - config.buffer_count); - if (IS_ERR(audio->map_v_read)) { - MM_ERR("read buf map fail\n"); - rc = -ENOMEM; - free_contiguous_memory_by_paddr( - audio->read_phys); - } else { - uint8_t index; - uint32_t offset = 0; - audio->read_data = - audio->map_v_read; - audio->pcm_feedback = 1; - audio->buf_refresh = 0; - audio->pcm_buf_count = - config.buffer_count; - audio->read_next = 0; - audio->fill_next = 0; - - for (index = 0; - index < config.buffer_count; - index++) { - audio->in[index].data = - audio->read_data + offset; - audio->in[index].addr = - audio->read_phys + offset; - audio->in[index].size = - config.buffer_size; - audio->in[index].used = 0; - offset += config.buffer_size; - } - MM_DBG("read buf: phy addr \ - 0x%08x kernel addr 0x%08x\n", - audio->read_phys, - (int)audio->read_data); - rc = 0; - } - } else { - rc = 0; - } - break; - } - case AUDIO_PAUSE: - MM_DBG("AUDIO_PAUSE %ld\n", arg); - rc = audpp_pause(audio->dec_id, (int) arg); - break; - case AUDIO_GET_SESSION_ID: - if (copy_to_user((void *) arg, &audio->dec_id, - sizeof(unsigned short))) - rc = -EFAULT; - else - rc = 0; - break; - default: - rc = -EINVAL; - } - mutex_unlock(&audio->lock); - return rc; -} - -/* Only useful in tunnel-mode */ -static int audio_fsync(struct file *file, loff_t ppos1, loff_t ppos2, int datasync) -{ - struct audio *audio = file->private_data; - struct buffer *frame; - int rc = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - if (!audio->running || audio->pcm_feedback) { - rc = -EINVAL; - goto done_nolock; - } - - mutex_lock(&audio->write_lock); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (audio->reserved) { - MM_DBG("send reserved byte\n"); - frame = audio->out + audio->out_tail; - ((char *) frame->data)[0] = audio->rsv_byte; - ((char *) frame->data)[1] = 0; - frame->used = 2; - audplay_send_data(audio, 0); - - rc = wait_event_interruptible(audio->write_wait, - (!audio->out[0].used && - !audio->out[1].used && - audio->out_needed) || audio->wflush); - - if (rc < 0) - goto done; - else if (audio->wflush) { - rc = -EBUSY; - goto done; - } - } - - /* pcm dmamiss message is sent continously - * when decoder is starved so no race - * condition concern - */ - audio->teos = 0; - - rc = wait_event_interruptible(audio->write_wait, - audio->teos || audio->wflush); - - if (audio->wflush) - rc = -EBUSY; - -done: - mutex_unlock(&audio->write_lock); -done_nolock: - return rc; -} - -static ssize_t audio_read(struct file *file, char __user *buf, size_t count, - loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - int rc = 0; - - if (!audio->pcm_feedback) - return 0; /* PCM feedback is not enabled. Nothing to read */ - - mutex_lock(&audio->read_lock); - MM_DBG("%d \n", count); - while (count > 0) { - rc = wait_event_interruptible(audio->read_wait, - (audio->in[audio->read_next].used > 0) || - (audio->stopped) || (audio->rflush)); - - if (rc < 0) - break; - - if (audio->stopped || audio->rflush) { - rc = -EBUSY; - break; - } - - if (count < audio->in[audio->read_next].used) { - /* Read must happen in frame boundary. Since driver - does not know frame size, read count must be greater - or equal to size of PCM samples */ - MM_DBG("audio_read: no partial frame done reading\n"); - break; - } else { - MM_DBG("audio_read: read from in[%d]\n", - audio->read_next); - if (copy_to_user - (buf, audio->in[audio->read_next].data, - audio->in[audio->read_next].used)) { - MM_ERR("invalid addr %x \n", (unsigned int)buf); - rc = -EFAULT; - break; - } - count -= audio->in[audio->read_next].used; - buf += audio->in[audio->read_next].used; - audio->in[audio->read_next].used = 0; - if ((++audio->read_next) == audio->pcm_buf_count) - audio->read_next = 0; - break; /* Force to exit while loop - * to prevent output thread - * sleep too long if data is - * not ready at this moment. - */ - } - } - - /* don't feed output buffer to HW decoder during flushing - * buffer refresh command will be sent once flush completes - * send buf refresh command here can confuse HW decoder - */ - if (audio->buf_refresh && !audio->rflush) { - audio->buf_refresh = 0; - MM_DBG("kick start pcm feedback again\n"); - audplay_buffer_refresh(audio); - } - - mutex_unlock(&audio->read_lock); - - if (buf > start) - rc = buf - start; - - MM_DBG("read %d bytes\n", rc); - return rc; -} - -static int audwmapro_process_eos(struct audio *audio, - const char __user *buf_start, unsigned short mfield_size) -{ - int rc = 0; - struct buffer *frame; - char *buf_ptr; - - if (audio->reserved) { - MM_DBG("flush reserve byte\n"); - frame = audio->out + audio->out_head; - buf_ptr = frame->data; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - buf_ptr[0] = audio->rsv_byte; - buf_ptr[1] = 0; - audio->out_head ^= 1; - frame->mfield_sz = 0; - frame->used = 2; - audio->reserved = 0; - audplay_send_data(audio, 0); - } - - frame = audio->out + audio->out_head; - - rc = wait_event_interruptible(audio->write_wait, - (audio->out_needed && - audio->out[0].used == 0 && - audio->out[1].used == 0) - || (audio->stopped) - || (audio->wflush)); - - if (rc < 0) - goto done; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - goto done; - } - - if (copy_from_user(frame->data, buf_start, mfield_size)) { - rc = -EFAULT; - goto done; - } - - frame->mfield_sz = mfield_size; - audio->out_head ^= 1; - frame->used = mfield_size; - audplay_send_data(audio, 0); -done: - return rc; -} - -static ssize_t audio_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct audio *audio = file->private_data; - const char __user *start = buf; - struct buffer *frame; - size_t xfer; - char *cpy_ptr; - int rc = 0, eos_condition = AUDWMAPRO_EOS_NONE; - unsigned dsize; - unsigned short mfield_size = 0; - - MM_DBG("cnt=%d\n", count); - - mutex_lock(&audio->write_lock); - while (count > 0) { - frame = audio->out + audio->out_head; - cpy_ptr = frame->data; - dsize = 0; - rc = wait_event_interruptible(audio->write_wait, - (frame->used == 0) - || (audio->stopped) - || (audio->wflush)); - if (rc < 0) - break; - if (audio->stopped || audio->wflush) { - rc = -EBUSY; - break; - } - if (audio->mfield) { - if (buf == start) { - /* Processing beginning of user buffer */ - if (__get_user(mfield_size, - (unsigned short __user *) buf)) { - rc = -EFAULT; - break; - } else if (mfield_size > count) { - rc = -EINVAL; - break; - } - MM_DBG("audio_write: mf offset_val %x\n", - mfield_size); - if (copy_from_user(cpy_ptr, buf, mfield_size)) { - rc = -EFAULT; - break; - } - /* Check if EOS flag is set and buffer has - * contains just meta field - */ - if (cpy_ptr[AUDWMAPRO_EOS_FLG_OFFSET] & - AUDWMAPRO_EOS_FLG_MASK) { - MM_DBG("audio_write: EOS SET\n"); - eos_condition = AUDWMAPRO_EOS_SET; - if (mfield_size == count) { - buf += mfield_size; - break; - } else - cpy_ptr[AUDWMAPRO_EOS_FLG_OFFSET] - &= ~AUDWMAPRO_EOS_FLG_MASK; - } - cpy_ptr += mfield_size; - count -= mfield_size; - dsize += mfield_size; - buf += mfield_size; - } else { - mfield_size = 0; - MM_DBG("audio_write: continuous buffer\n"); - } - frame->mfield_sz = mfield_size; - } - - if (audio->reserved) { - MM_DBG("append reserved byte %x\n", audio->rsv_byte); - *cpy_ptr = audio->rsv_byte; - xfer = (count > ((frame->size - mfield_size) - 1)) ? - (frame->size - mfield_size) - 1 : count; - cpy_ptr++; - dsize += 1; - audio->reserved = 0; - } else - xfer = (count > (frame->size - mfield_size)) ? - (frame->size - mfield_size) : count; - - if (copy_from_user(cpy_ptr, buf, xfer)) { - rc = -EFAULT; - break; - } - - dsize += xfer; - if (dsize & 1) { - audio->rsv_byte = ((char *) frame->data)[dsize - 1]; - MM_DBG("odd length buf reserve last byte %x\n", - audio->rsv_byte); - audio->reserved = 1; - dsize--; - } - count -= xfer; - buf += xfer; - - if (dsize > 0) { - audio->out_head ^= 1; - frame->used = dsize; - audplay_send_data(audio, 0); - } - } - if (eos_condition == AUDWMAPRO_EOS_SET) - rc = audwmapro_process_eos(audio, start, mfield_size); - mutex_unlock(&audio->write_lock); - if (!rc) { - if (buf > start) - return buf - start; - } - return rc; -} - -static int audio_release(struct inode *inode, struct file *file) -{ - struct audio *audio = file->private_data; - - MM_INFO("audio instance 0x%08x freeing\n", (int)audio); - mutex_lock(&audio->lock); - auddev_unregister_evt_listner(AUDDEV_CLNT_DEC, audio->dec_id); - audio_disable(audio); - audio_flush(audio); - audio_flush_pcm_buf(audio); - msm_adsp_put(audio->audplay); - audpp_adec_free(audio->dec_id); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&audio->suspend_ctl.node); -#endif - audio->event_abort = 1; - wake_up(&audio->event_wait); - audwmapro_reset_event_queue(audio); - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - if (audio->read_data) { - iounmap(audio->map_v_read); - free_contiguous_memory_by_paddr(audio->read_phys); - } - mutex_unlock(&audio->lock); -#ifdef CONFIG_DEBUG_FS - if (audio->dentry) - debugfs_remove(audio->dentry); -#endif - kfree(audio); - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void audwmapro_post_event(struct audio *audio, int type, - union msm_audio_event_payload payload) -{ - struct audwmapro_event *e_node = NULL; - unsigned long flags; - - spin_lock_irqsave(&audio->event_queue_lock, flags); - - if (!list_empty(&audio->free_event_queue)) { - e_node = list_first_entry(&audio->free_event_queue, - struct audwmapro_event, list); - list_del(&e_node->list); - } else { - e_node = kmalloc(sizeof(struct audwmapro_event), GFP_ATOMIC); - if (!e_node) { - MM_ERR("No mem to post event %d\n", type); - return; - } - } - - e_node->event_type = type; - e_node->payload = payload; - - list_add_tail(&e_node->list, &audio->event_queue); - spin_unlock_irqrestore(&audio->event_queue_lock, flags); - wake_up(&audio->event_wait); -} - -static void audwmapro_suspend(struct early_suspend *h) -{ - struct audwmapro_suspend_ctl *ctl = - container_of(h, struct audwmapro_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audwmapro_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload); -} - -static void audwmapro_resume(struct early_suspend *h) -{ - struct audwmapro_suspend_ctl *ctl = - container_of(h, struct audwmapro_suspend_ctl, node); - union msm_audio_event_payload payload; - - MM_DBG("\n"); /* Macro prints the file name and function */ - audwmapro_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload); -} -#endif - -#ifdef CONFIG_DEBUG_FS -static ssize_t audwmapro_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t audwmapro_debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - const int debug_bufmax = 4096; - static char buffer[4096]; - int n = 0, i; - struct audio *audio = file->private_data; - - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_feedback %d\n", audio->pcm_feedback); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_buf_sz %d\n", audio->out[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_count %d \n", audio->pcm_buf_count); - n += scnprintf(buffer + n, debug_bufmax - n, - "pcm_buf_sz %d \n", audio->in[0].size); - n += scnprintf(buffer + n, debug_bufmax - n, - "volume %x \n", audio->vol_pan.volume); - n += scnprintf(buffer + n, debug_bufmax - n, - "sample rate %d \n", audio->out_sample_rate); - n += scnprintf(buffer + n, debug_bufmax - n, - "channel mode %d \n", audio->out_channel_mode); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "rflush %d\n", audio->rflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "running %d \n", audio->running); - n += scnprintf(buffer + n, debug_bufmax - n, - "dec state %d \n", audio->dec_state); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_needed %d \n", audio->out_needed); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_head %d \n", audio->out_head); - n += scnprintf(buffer + n, debug_bufmax - n, - "out_tail %d \n", audio->out_tail); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[0].used %d \n", audio->out[0].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "out[1].used %d \n", audio->out[1].used); - n += scnprintf(buffer + n, debug_bufmax - n, - "buffer_refresh %d \n", audio->buf_refresh); - n += scnprintf(buffer + n, debug_bufmax - n, - "read_next %d \n", audio->read_next); - n += scnprintf(buffer + n, debug_bufmax - n, - "fill_next %d \n", audio->fill_next); - for (i = 0; i < audio->pcm_buf_count; i++) - n += scnprintf(buffer + n, debug_bufmax - n, - "in[%d].size %d \n", i, audio->in[i].used); - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static const struct file_operations audwmapro_debug_fops = { - .read = audwmapro_debug_read, - .open = audwmapro_debug_open, -}; -#endif - -static int audio_open(struct inode *inode, struct file *file) -{ - struct audio *audio = NULL; - int rc, dec_attrb, decid, i; - unsigned pmem_sz = DMASZ_MAX; - struct audwmapro_event *e_node = NULL; -#ifdef CONFIG_DEBUG_FS - /* 4 bytes represents decoder number, 1 byte for terminate string */ - char name[sizeof "msm_wmapro_" + 5]; -#endif - - /* Allocate Mem for audio instance */ - audio = kzalloc(sizeof(struct audio), GFP_KERNEL); - if (!audio) { - MM_ERR("no memory to allocate audio instance \n"); - rc = -ENOMEM; - goto done; - } - MM_INFO("audio instance 0x%08x created\n", (int)audio); - - /* Allocate the decoder */ - dec_attrb = AUDDEC_DEC_WMAPRO; - if ((file->f_mode & FMODE_WRITE) && - (file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_NONTUNNEL; - audio->pcm_feedback = NON_TUNNEL_MODE_PLAYBACK; - } else if ((file->f_mode & FMODE_WRITE) && - !(file->f_mode & FMODE_READ)) { - dec_attrb |= MSM_AUD_MODE_TUNNEL; - audio->pcm_feedback = TUNNEL_MODE_PLAYBACK; - } else { - kfree(audio); - rc = -EACCES; - goto done; - } - - decid = audpp_adec_alloc(dec_attrb, &audio->module_name, - &audio->queue_id); - - if (decid < 0) { - MM_ERR("No free decoder available, freeing instance 0x%08x\n", - (int)audio); - rc = -ENODEV; - kfree(audio); - goto done; - } - audio->dec_id = decid & MSM_AUD_DECODER_MASK; - - while (pmem_sz >= DMASZ_MIN) { - MM_DBG("pmemsz = %d\n", pmem_sz); - audio->phys = allocate_contiguous_ebi_nomap(pmem_sz, SZ_4K); - if (audio->phys) { - audio->map_v_write = ioremap(audio->phys, pmem_sz); - if (IS_ERR(audio->map_v_write)) { - MM_ERR("could not map write buffers, \ - freeing instance 0x%08x\n", - (int)audio); - rc = -ENOMEM; - free_contiguous_memory_by_paddr(audio->phys); - audpp_adec_free(audio->dec_id); - kfree(audio); - goto done; - } - audio->data = audio->map_v_write; - MM_DBG("write buf: phy addr 0x%08x kernel addr \ - 0x%08x\n", audio->phys, (int)audio->data); - break; - } else if (pmem_sz == DMASZ_MIN) { - MM_ERR("could not allocate write buffers, freeing \ - instance 0x%08x\n", (int)audio); - rc = -ENOMEM; - audpp_adec_free(audio->dec_id); - kfree(audio); - goto done; - } else - pmem_sz >>= 1; - } - audio->out_dma_sz = pmem_sz; - - rc = msm_adsp_get(audio->module_name, &audio->audplay, - &audplay_adsp_ops_wmapro, audio); - if (rc) { - MM_ERR("failed to get %s module, freeing instance 0x%08x\n", - audio->module_name, (int)audio); - goto err; - } - - mutex_init(&audio->lock); - mutex_init(&audio->write_lock); - mutex_init(&audio->read_lock); - mutex_init(&audio->get_event_lock); - spin_lock_init(&audio->dsp_lock); - init_waitqueue_head(&audio->write_wait); - init_waitqueue_head(&audio->read_wait); - INIT_LIST_HEAD(&audio->free_event_queue); - INIT_LIST_HEAD(&audio->event_queue); - init_waitqueue_head(&audio->wait); - init_waitqueue_head(&audio->event_wait); - spin_lock_init(&audio->event_queue_lock); - init_waitqueue_head(&audio->avsync_wait); - - audio->out[0].data = audio->data + 0; - audio->out[0].addr = audio->phys + 0; - audio->out[0].size = audio->out_dma_sz >> 1; - - audio->out[1].data = audio->data + audio->out[0].size; - audio->out[1].addr = audio->phys + audio->out[0].size; - audio->out[1].size = audio->out[0].size; - - /*audio->wmapro_config.armdatareqthr = 1268; - audio->wmapro_config.numchannels = 2; - audio->wmapro_config.avgbytespersecond = 6003; - audio->wmapro_config.samplingrate = 44100; - audio->wmapro_config.encodeopt = 224; - audio->wmapro_config.validbitspersample = 16; - audio->wmapro_config.formattag = 354; - audio->wmapro_config.asfpacketlength = 2230; - audio->wmapro_config.channelmask = 3; - audio->wmapro_config.advancedencodeopt = 32834; - audio->wmapro_config.advancedencodeopt2 = 0;*/ - - audio->out_sample_rate = 44100; - audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V; - - audio->vol_pan.volume = 0x2000; - - audio_flush(audio); - - file->private_data = audio; - audio->opened = 1; - audio->device_events = AUDDEV_EVT_DEV_RDY - |AUDDEV_EVT_DEV_RLS| - AUDDEV_EVT_STREAM_VOL_CHG; - - rc = auddev_register_evt_listner(audio->device_events, - AUDDEV_CLNT_DEC, - audio->dec_id, - wmapro_listner, - (void *)audio); - if (rc) { - MM_ERR("%s: failed to register listner\n", __func__); - goto event_err; - } - -#ifdef CONFIG_DEBUG_FS - snprintf(name, sizeof name, "msm_wmapro_%04x", audio->dec_id); - audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, - NULL, (void *) audio, - &audwmapro_debug_fops); - - if (IS_ERR(audio->dentry)) - MM_DBG("debugfs_create_file failed\n"); -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - audio->suspend_ctl.node.resume = audwmapro_resume; - audio->suspend_ctl.node.suspend = audwmapro_suspend; - audio->suspend_ctl.audio = audio; - register_early_suspend(&audio->suspend_ctl.node); -#endif - for (i = 0; i < AUDWMAPRO_EVENT_NUM; i++) { - e_node = kmalloc(sizeof(struct audwmapro_event), GFP_KERNEL); - if (e_node) - list_add_tail(&e_node->list, &audio->free_event_queue); - else { - MM_ERR("event pkt alloc failed\n"); - break; - } - } -done: - return rc; -event_err: - msm_adsp_put(audio->audplay); -err: - iounmap(audio->map_v_write); - free_contiguous_memory_by_paddr(audio->phys); - audpp_adec_free(audio->dec_id); - kfree(audio); - return rc; -} - -static const struct file_operations audio_wmapro_fops = { - .owner = THIS_MODULE, - .open = audio_open, - .release = audio_release, - .read = audio_read, - .write = audio_write, - .unlocked_ioctl = audio_ioctl, - .fsync = audio_fsync, -}; - -struct miscdevice audio_wmapro_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_wmapro", - .fops = &audio_wmapro_fops, -}; - -static int __init audio_init(void) -{ - return misc_register(&audio_wmapro_misc); -} - -device_initcall(audio_init); diff --git a/arch/arm/mach-msm/qdsp5v2/audpp.c b/arch/arm/mach-msm/qdsp5v2/audpp.c deleted file mode 100644 index 7a40156d961f69d643c16e2e18a5485aa5afe9dd..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audpp.c +++ /dev/null @@ -1,1140 +0,0 @@ -/* arch/arm/mach-msm/qdsp5/audpp.c - * - * common code to deal with the AUDPP dsp task (audio postproc) - * - * Copyright (C) 2008 Google, Inc. - * Copyright (c) 2009-2011, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../qdsp5/evlog.h" -#include - -enum { - EV_NULL, - EV_ENABLE, - EV_DISABLE, - EV_EVENT, - EV_DATA, -}; - -static const char *dsp_log_strings[] = { - "NULL", - "ENABLE", - "DISABLE", - "EVENT", - "DATA", -}; - -DECLARE_LOG(dsp_log, 64, dsp_log_strings); - -static int __init _dsp_log_init(void) -{ - return ev_log_init(&dsp_log); -} - -module_init(_dsp_log_init); -#define LOG(id, arg) ev_log_write(&dsp_log, id, arg) - -static DEFINE_MUTEX(audpp_lock); -static DEFINE_MUTEX(audpp_dec_lock); -static struct wake_lock audpp_wake_lock; - -#define CH_COUNT 5 -#define AUDPP_CLNT_MAX_COUNT 6 - -#define AUDPP_CMD_CFG_OBJ_UPDATE 0x8000 -#define AUDPP_CMD_EQ_FLAG_DIS 0x0000 -#define AUDPP_CMD_EQ_FLAG_ENA -1 -#define AUDPP_CMD_IIR_FLAG_DIS 0x0000 -#define AUDPP_CMD_IIR_FLAG_ENA -1 -#define AUDPP_CMD_STF_FLAG_ENA -1 -#define AUDPP_CMD_STF_FLAG_DIS 0x0000 - -#define MAX_EVENT_CALLBACK_CLIENTS 1 - -#define AUDPP_CONCURRENCY_DEFAULT 0 /* Set default to LPA mode */ -#define AUDPP_MAX_DECODER_CNT 5 -#define AUDPP_CODEC_MASK 0x000000FF -#define AUDPP_MODE_MASK 0x00000F00 -#define AUDPP_OP_MASK 0xF0000000 - -struct audpp_decoder_info { - unsigned int codec; - pid_t pid; -}; - -struct audpp_state { - struct msm_adsp_module *mod; - audpp_event_func func[AUDPP_CLNT_MAX_COUNT]; - void *private[AUDPP_CLNT_MAX_COUNT]; - struct mutex *lock; - unsigned open_count; - unsigned enabled; - - /* Related to decoder allocation */ - struct mutex *lock_dec; - struct msm_adspdec_database *dec_database; - struct audpp_decoder_info dec_info_table[AUDPP_MAX_DECODER_CNT]; - unsigned dec_inuse; - unsigned long concurrency; - - struct audpp_event_callback *cb_tbl[MAX_EVENT_CALLBACK_CLIENTS]; - - /* Related to decoder instances */ - uint8_t op_mode; /* Specifies Turbo/Non Turbo mode */ - uint8_t decoder_count; /* No. of decoders active running */ - uint8_t codec_max_instances; /* Max codecs allowed currently */ - uint8_t codec_cnt[MSM_MAX_DEC_CNT]; /* Nr of each codec - type enabled */ - - wait_queue_head_t event_wait; -}; - -struct audpp_state the_audpp_state = { - .lock = &audpp_lock, - .lock_dec = &audpp_dec_lock, -}; - -static inline void prevent_suspend(void) -{ - wake_lock(&audpp_wake_lock); -} -static inline void allow_suspend(void) -{ - wake_unlock(&audpp_wake_lock); -} - -int audpp_send_queue1(void *cmd, unsigned len) -{ - return msm_adsp_write(the_audpp_state.mod, - QDSP_uPAudPPCmd1Queue, cmd, len); -} -EXPORT_SYMBOL(audpp_send_queue1); - -int audpp_send_queue2(void *cmd, unsigned len) -{ - return msm_adsp_write(the_audpp_state.mod, - QDSP_uPAudPPCmd2Queue, cmd, len); -} -EXPORT_SYMBOL(audpp_send_queue2); - -int audpp_send_queue3(void *cmd, unsigned len) -{ - return msm_adsp_write(the_audpp_state.mod, - QDSP_uPAudPPCmd3Queue, cmd, len); -} -EXPORT_SYMBOL(audpp_send_queue3); - -static int audpp_dsp_config(int enable) -{ - struct audpp_cmd_cfg cmd; - - cmd.cmd_id = AUDPP_CMD_CFG; - cmd.cfg = enable ? AUDPP_CMD_CFG_ENABLE : AUDPP_CMD_CFG_SLEEP; - - return audpp_send_queue1(&cmd, sizeof(cmd)); -} - -void audpp_route_stream(unsigned short dec_id, unsigned short mixer_mask) -{ - struct audpp_cmd_cfg_dev_mixer_params mixer_params_cmd; - - memset(&mixer_params_cmd, 0, sizeof(mixer_params_cmd)); - - mixer_params_cmd.cmd_id = AUDPP_CMD_CFG_DEV_MIXER; - mixer_params_cmd.stream_id = dec_id; - mixer_params_cmd.mixer_cmd = mixer_mask; - audpp_send_queue1(&mixer_params_cmd, sizeof(mixer_params_cmd)); - -} -EXPORT_SYMBOL(audpp_route_stream); - -int is_audpp_enable(void) -{ - struct audpp_state *audpp = &the_audpp_state; - - return audpp->enabled; -} -EXPORT_SYMBOL(is_audpp_enable); - -int audpp_register_event_callback(struct audpp_event_callback *ecb) -{ - struct audpp_state *audpp = &the_audpp_state; - int i; - - for (i = 0; i < MAX_EVENT_CALLBACK_CLIENTS; ++i) { - if (NULL == audpp->cb_tbl[i]) { - audpp->cb_tbl[i] = ecb; - return 0; - } - } - return -1; -} -EXPORT_SYMBOL(audpp_register_event_callback); - - -int audpp_unregister_event_callback(struct audpp_event_callback *ecb) -{ - struct audpp_state *audpp = &the_audpp_state; - int i; - - for (i = 0; i < MAX_EVENT_CALLBACK_CLIENTS; ++i) { - if (ecb == audpp->cb_tbl[i]) { - audpp->cb_tbl[i] = NULL; - return 0; - } - } - return -1; -} -EXPORT_SYMBOL(audpp_unregister_event_callback); - -static void audpp_broadcast(struct audpp_state *audpp, unsigned id, - uint16_t *msg) -{ - unsigned n; - for (n = 0; n < AUDPP_CLNT_MAX_COUNT; n++) { - if (audpp->func[n]) - audpp->func[n] (audpp->private[n], id, msg); - } - - for (n = 0; n < MAX_EVENT_CALLBACK_CLIENTS; ++n) - if (audpp->cb_tbl[n] && audpp->cb_tbl[n]->fn) - audpp->cb_tbl[n]->fn(audpp->cb_tbl[n]->private, id, - msg); -} - -static void audpp_notify_clnt(struct audpp_state *audpp, unsigned clnt_id, - unsigned id, uint16_t *msg) -{ - if (clnt_id < AUDPP_CLNT_MAX_COUNT && audpp->func[clnt_id]) - audpp->func[clnt_id] (audpp->private[clnt_id], id, msg); -} - -static void audpp_handle_pcmdmamiss(struct audpp_state *audpp, - uint16_t bit_mask) -{ - uint8_t b_index; - - for (b_index = 0; b_index < AUDPP_CLNT_MAX_COUNT; b_index++) { - if (bit_mask & (0x1 << b_index)) - if (audpp->func[b_index]) - audpp->func[b_index] (audpp->private[b_index], - AUDPP_MSG_PCMDMAMISSED, - &bit_mask); - } -} - -static void audpp_dsp_event(void *data, unsigned id, size_t len, - void (*getevent) (void *ptr, size_t len)) -{ - struct audpp_state *audpp = data; - uint16_t msg[8]; - - getevent(msg, sizeof(msg)); - - LOG(EV_EVENT, (id << 16) | msg[0]); - LOG(EV_DATA, (msg[1] << 16) | msg[2]); - - switch (id) { - case AUDPP_MSG_STATUS_MSG:{ - unsigned cid = msg[0]; - MM_DBG("status %d %d %d\n", cid, msg[1], msg[2]); - - if ((cid < 5) && audpp->func[cid]) - audpp->func[cid] (audpp->private[cid], id, msg); - break; - } - case AUDPP_MSG_HOST_PCM_INTF_MSG: - if (audpp->func[5]) - audpp->func[5] (audpp->private[5], id, msg); - break; - case AUDPP_MSG_PCMDMAMISSED: - audpp_handle_pcmdmamiss(audpp, msg[0]); - break; - case AUDPP_MSG_CFG_MSG: - if (msg[0] == AUDPP_MSG_ENA_ENA) { - MM_INFO("ENABLE\n"); - audpp->enabled = 1; - audpp_broadcast(audpp, id, msg); - } else if (msg[0] == AUDPP_MSG_ENA_DIS) { - MM_INFO("DISABLE\n"); - audpp->enabled = 0; - wake_up(&audpp->event_wait); - audpp_broadcast(audpp, id, msg); - } else { - MM_ERR("invalid config msg %d\n", msg[0]); - } - break; - case AUDPP_MSG_ROUTING_ACK: - audpp_notify_clnt(audpp, msg[0], id, msg); - break; - case AUDPP_MSG_FLUSH_ACK: - audpp_notify_clnt(audpp, msg[0], id, msg); - break; - case ADSP_MESSAGE_ID: - MM_DBG("Received ADSP event: module enable/disable \ - (audpptask)"); - break; - case AUDPP_MSG_AVSYNC_MSG: - audpp_notify_clnt(audpp, msg[0], id, msg); - break; -#ifdef CONFIG_DEBUG_FS - case AUDPP_MSG_FEAT_QUERY_DM_DONE: - MM_INFO(" RTC ACK --> %x %x %x %x %x %x %x %x\n", msg[0],\ - msg[1], msg[2], msg[3], msg[4], \ - msg[5], msg[6], msg[7]); - acdb_rtc_set_err(msg[3]); - break; -#endif - default: - MM_INFO("unhandled msg id %x\n", id); - } -} - -static struct msm_adsp_ops adsp_ops = { - .event = audpp_dsp_event, -}; - -static void audpp_fake_event(struct audpp_state *audpp, int id, - unsigned event, unsigned arg) -{ - uint16_t msg[1]; - uint16_t n = 0; - msg[0] = arg; - audpp->func[id] (audpp->private[id], event, msg); - if (audpp->enabled == 1) { - for (n = 0; n < MAX_EVENT_CALLBACK_CLIENTS; ++n) - if (audpp->cb_tbl[n] && audpp->cb_tbl[n]->fn) - audpp->cb_tbl[n]->fn(audpp->cb_tbl[n]->private, - AUDPP_MSG_CFG_MSG, msg); - } -} - -int audpp_enable(int id, audpp_event_func func, void *private) -{ - struct audpp_state *audpp = &the_audpp_state; - int res = 0; - - if (id < -1 || id > 4) - return -EINVAL; - - if (id == -1) - id = 5; - - mutex_lock(audpp->lock); - if (audpp->func[id]) { - res = -EBUSY; - goto out; - } - - audpp->func[id] = func; - audpp->private[id] = private; - - LOG(EV_ENABLE, 1); - if (audpp->open_count++ == 0) { - MM_DBG("enable\n"); - res = msm_adsp_get("AUDPPTASK", &audpp->mod, &adsp_ops, audpp); - if (res < 0) { - MM_ERR("audpp: cannot open AUDPPTASK\n"); - audpp->open_count = 0; - audpp->func[id] = NULL; - audpp->private[id] = NULL; - goto out; - } - LOG(EV_ENABLE, 2); - prevent_suspend(); - msm_adsp_enable(audpp->mod); - audpp_dsp_config(1); - } else { - unsigned long flags; - local_irq_save(flags); - if (audpp->enabled) - audpp_fake_event(audpp, id, - AUDPP_MSG_CFG_MSG, AUDPP_MSG_ENA_ENA); - local_irq_restore(flags); - } - - res = 0; -out: - mutex_unlock(audpp->lock); - return res; -} -EXPORT_SYMBOL(audpp_enable); - -void audpp_disable(int id, void *private) -{ - struct audpp_state *audpp = &the_audpp_state; - unsigned long flags; - int rc; - - if (id < -1 || id > 4) - return; - - if (id == -1) - id = 5; - - mutex_lock(audpp->lock); - LOG(EV_DISABLE, 1); - if (!audpp->func[id]) - goto out; - if (audpp->private[id] != private) - goto out; - - local_irq_save(flags); - audpp_fake_event(audpp, id, AUDPP_MSG_CFG_MSG, AUDPP_MSG_ENA_DIS); - audpp->func[id] = NULL; - audpp->private[id] = NULL; - local_irq_restore(flags); - - if (--audpp->open_count == 0) { - MM_DBG("disable\n"); - LOG(EV_DISABLE, 2); - audpp_dsp_config(0); - rc = wait_event_interruptible(audpp->event_wait, - (audpp->enabled == 0)); - if (audpp->enabled == 0) - MM_INFO("Received CFG_MSG_DISABLE from ADSP\n"); - else - MM_ERR("Didn't receive CFG_MSG DISABLE \ - message from ADSP\n"); - msm_adsp_disable(audpp->mod); - msm_adsp_put(audpp->mod); - audpp->mod = NULL; - allow_suspend(); - } -out: - mutex_unlock(audpp->lock); -} -EXPORT_SYMBOL(audpp_disable); - -#define BAD_ID(id) ((id < 0) || (id >= CH_COUNT)) - -int audpp_restore_avsync(int id, uint16_t *avsync) -{ - struct audpp_cmd_avsync cmd; - - if (BAD_ID(id)) - return -1; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_AVSYNC; - cmd.stream_id = id; - cmd.interrupt_interval = 0; /* Setting it to Zero as there won't be - periodic update */ - cmd.sample_counter_dlsw = avsync[3]; - cmd.sample_counter_dmsw = avsync[2]; - cmd.sample_counter_msw = avsync[1]; - cmd.byte_counter_dlsw = avsync[6]; - cmd.byte_counter_dmsw = avsync[5]; - cmd.byte_counter_msw = avsync[4]; - - return audpp_send_queue1(&cmd, sizeof(cmd)); -} -EXPORT_SYMBOL(audpp_restore_avsync); - -int audpp_query_avsync(int id) -{ - struct audpp_cmd_query_avsync cmd; - - if (BAD_ID(id)) - return -EINVAL; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_id = AUDPP_CMD_QUERY_AVSYNC; - cmd.stream_id = id; - return audpp_send_queue1(&cmd, sizeof(cmd)); - -} -EXPORT_SYMBOL(audpp_query_avsync); - -int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan, - enum obj_type objtype) -{ - /* cmd, obj_cfg[7], cmd_type, volume, pan */ - uint16_t cmd[7]; - - if (objtype) { - if (id > 5) { - MM_ERR("Wrong POPP decoder id: %d\n", id); - return -EINVAL; - } - } else { - if (id > 3) { - MM_ERR("Wrong COPP decoder id: %d\n", id); - return -EINVAL; - } - } - - memset(cmd, 0, sizeof(cmd)); - cmd[0] = AUDPP_CMD_CFG_OBJECT_PARAMS; - if (objtype) - cmd[1] = AUDPP_CMD_POPP_STREAM; - else - cmd[1] = AUDPP_CMD_COPP_STREAM; - cmd[2] = id; - cmd[3] = AUDPP_CMD_CFG_OBJ_UPDATE; - cmd[4] = AUDPP_CMD_VOLUME_PAN; - cmd[5] = volume; - cmd[6] = pan; - - return audpp_send_queue3(cmd, sizeof(cmd)); -} -EXPORT_SYMBOL(audpp_set_volume_and_pan); - -/* Implementation of COPP features */ -int audpp_dsp_set_mbadrc(unsigned id, unsigned enable, - struct audpp_cmd_cfg_object_params_mbadrc *mbadrc, - enum obj_type objtype) -{ - if (objtype) { - if (id > 5) { - MM_ERR("Wrong POPP decoder id: %d\n", id); - return -EINVAL; - } - } else { - if (id > 3) { - MM_ERR("Wrong COPP decoder id: %d\n", id); - return -EINVAL; - } - } - - mbadrc->common.cmd_id = AUDPP_CMD_CFG_OBJECT_PARAMS; - if (objtype) - mbadrc->common.stream = AUDPP_CMD_POPP_STREAM; - else - mbadrc->common.stream = AUDPP_CMD_COPP_STREAM; - - mbadrc->common.stream_id = id; - mbadrc->common.obj_cfg = AUDPP_CMD_CFG_OBJ_UPDATE; - mbadrc->common.command_type = AUDPP_CMD_MBADRC; - - if (enable) - mbadrc->enable = AUDPP_CMD_ADRC_FLAG_ENA; - else - mbadrc->enable = AUDPP_CMD_ADRC_FLAG_DIS; - - return audpp_send_queue3(mbadrc, - sizeof(struct audpp_cmd_cfg_object_params_mbadrc)); -} -EXPORT_SYMBOL(audpp_dsp_set_mbadrc); - -int audpp_dsp_set_qconcert_plus(unsigned id, unsigned enable, - struct audpp_cmd_cfg_object_params_qconcert *qconcert_plus, - enum obj_type objtype) -{ - if (objtype) { - if (id > 5) { - MM_ERR("Wrong POPP decoder id: %d\n", id); - return -EINVAL; - } - } else { - if (id > 3) { - MM_ERR("Wrong COPP decoder id: %d\n", id); - return -EINVAL; - } - } - - qconcert_plus->common.cmd_id = AUDPP_CMD_CFG_OBJECT_PARAMS; - if (objtype) - qconcert_plus->common.stream = AUDPP_CMD_POPP_STREAM; - else - qconcert_plus->common.stream = AUDPP_CMD_COPP_STREAM; - - qconcert_plus->common.stream_id = id; - qconcert_plus->common.obj_cfg = AUDPP_CMD_CFG_OBJ_UPDATE; - qconcert_plus->common.command_type = AUDPP_CMD_QCONCERT; - - if (enable) - qconcert_plus->enable_flag = AUDPP_CMD_ADRC_FLAG_ENA; - else - qconcert_plus->enable_flag = AUDPP_CMD_ADRC_FLAG_DIS; - - return audpp_send_queue3(qconcert_plus, - sizeof(struct audpp_cmd_cfg_object_params_qconcert)); -} -EXPORT_SYMBOL(audpp_dsp_set_qconcert_plus); - -int audpp_dsp_set_rx_iir(unsigned id, unsigned enable, - struct audpp_cmd_cfg_object_params_pcm *iir, - enum obj_type objtype) -{ - - if (objtype) { - if (id > 5) { - MM_ERR("Wrong POPP decoder id: %d\n", id); - return -EINVAL; - } - } else { - if (id > 3) { - MM_ERR("Wrong COPP decoder id: %d\n", id); - return -EINVAL; - } - } - - iir->common.cmd_id = AUDPP_CMD_CFG_OBJECT_PARAMS; - if (objtype) - iir->common.stream = AUDPP_CMD_POPP_STREAM; - else - iir->common.stream = AUDPP_CMD_COPP_STREAM; - - iir->common.stream_id = id; - iir->common.obj_cfg = AUDPP_CMD_CFG_OBJ_UPDATE; - iir->common.command_type = AUDPP_CMD_IIR_TUNING_FILTER; - - if (enable) - iir->active_flag = AUDPP_CMD_IIR_FLAG_ENA; - else - iir->active_flag = AUDPP_CMD_IIR_FLAG_DIS; - - return audpp_send_queue3(iir, - sizeof(struct audpp_cmd_cfg_object_params_pcm)); -} -EXPORT_SYMBOL(audpp_dsp_set_rx_iir); - -int audpp_dsp_set_gain_rx(unsigned id, - struct audpp_cmd_cfg_cal_gain *calib_gain_rx, - enum obj_type objtype) -{ - if (objtype) { - return -EINVAL; - } else { - if (id > 3) { - MM_ERR("Wrong COPP decoder id: %d\n", id); - return -EINVAL; - } - } - calib_gain_rx->common.cmd_id = AUDPP_CMD_CFG_OBJECT_PARAMS; - calib_gain_rx->common.stream = AUDPP_CMD_COPP_STREAM; - - calib_gain_rx->common.stream_id = id; - calib_gain_rx->common.obj_cfg = AUDPP_CMD_CFG_OBJ_UPDATE; - calib_gain_rx->common.command_type = AUDPP_CMD_CALIB_GAIN_RX; - - return audpp_send_queue3(calib_gain_rx, - sizeof(struct audpp_cmd_cfg_cal_gain)); -} -EXPORT_SYMBOL(audpp_dsp_set_gain_rx); - -int audpp_dsp_set_pbe(unsigned id, unsigned enable, - struct audpp_cmd_cfg_pbe *pbe_block, - enum obj_type objtype) -{ - if (objtype) { - if (id > 5) { - MM_ERR("Wrong POPP decoder id: %d\n", id); - return -EINVAL; - } - } else { - if (id > 3) { - MM_ERR("Wrong COPP decoder id: %d\n", id); - return -EINVAL; - } - } - - pbe_block->common.cmd_id = AUDPP_CMD_CFG_OBJECT_PARAMS; - if (objtype) - pbe_block->common.stream = AUDPP_CMD_POPP_STREAM; - else - pbe_block->common.stream = AUDPP_CMD_COPP_STREAM; - - pbe_block->common.stream_id = id; - pbe_block->common.obj_cfg = AUDPP_CMD_CFG_OBJ_UPDATE; - pbe_block->common.command_type = AUDPP_CMD_PBE; - - if (enable) - pbe_block->pbe_enable = AUDPP_CMD_PBE_FLAG_ENA; - else - pbe_block->pbe_enable = AUDPP_CMD_PBE_FLAG_DIS; - - return audpp_send_queue3(pbe_block, - sizeof(struct audpp_cmd_cfg_pbe)); -} -EXPORT_SYMBOL(audpp_dsp_set_pbe); - -int audpp_dsp_set_spa(unsigned id, - struct audpp_cmd_cfg_object_params_spectram *spa, - enum obj_type objtype){ - struct audpp_cmd_cfg_object_params_spectram cmd; - - if (objtype) { - if (id > 5) { - MM_ERR("Wrong POPP decoder id: %d\n", id); - return -EINVAL; - } - } else { - if (id > 3) { - MM_ERR("Wrong COPP decoder id: %d\n", id); - return -EINVAL; - } - } - - memset(&cmd, 0, sizeof(cmd)); - if (objtype) - cmd.common.stream = AUDPP_CMD_POPP_STREAM; - else - cmd.common.stream = AUDPP_CMD_COPP_STREAM; - - cmd.common.stream_id = id; - cmd.common.obj_cfg = AUDPP_CMD_CFG_OBJ_UPDATE; - cmd.common.command_type = AUDPP_CMD_SPECTROGRAM; - cmd.sample_interval = spa->sample_interval; - cmd.num_coeff = spa->num_coeff; - return audpp_send_queue3(&cmd, sizeof(cmd)); - -} -EXPORT_SYMBOL(audpp_dsp_set_spa); - -int audpp_dsp_set_stf(unsigned id, unsigned enable, - struct audpp_cmd_cfg_object_params_sidechain *stf, - enum obj_type objtype){ - if (objtype) { - if (id > 5) { - MM_ERR("Wrong POPP decoder id: %d\n", id); - return -EINVAL; - } - } else { - if (id > 3) { - MM_ERR("Wrong COPP decoder id: %d\n", id); - return -EINVAL; - } - } - - stf->common.cmd_id = AUDPP_CMD_CFG_OBJECT_PARAMS; - if (objtype) - stf->common.stream = AUDPP_CMD_POPP_STREAM; - else - stf->common.stream = AUDPP_CMD_COPP_STREAM; - - stf->common.stream_id = id; - stf->common.obj_cfg = AUDPP_CMD_CFG_OBJ_UPDATE; - stf->common.command_type = AUDPP_CMD_SIDECHAIN_TUNING_FILTER; - - if (enable) - stf->active_flag = AUDPP_CMD_STF_FLAG_ENA; - else - stf->active_flag = AUDPP_CMD_STF_FLAG_DIS; - return audpp_send_queue3(stf, - sizeof(struct audpp_cmd_cfg_object_params_sidechain)); -} -EXPORT_SYMBOL(audpp_dsp_set_stf); - -/* Implementation Of COPP + POPP */ -int audpp_dsp_set_eq(unsigned id, unsigned enable, - struct audpp_cmd_cfg_object_params_eqalizer *eq, - enum obj_type objtype) -{ - struct audpp_cmd_cfg_object_params_eqalizer cmd; - - if (objtype) { - if (id > 5) { - MM_ERR("Wrong POPP decoder id: %d\n", id); - return -EINVAL; - } - } else { - if (id > 3) { - MM_ERR("Wrong COPP decoder id: %d\n", id); - return -EINVAL; - } - } - - memset(&cmd, 0, sizeof(cmd)); - if (objtype) - cmd.common.stream = AUDPP_CMD_POPP_STREAM; - else - cmd.common.stream = AUDPP_CMD_COPP_STREAM; - - cmd.common.stream_id = id; - cmd.common.obj_cfg = AUDPP_CMD_CFG_OBJ_UPDATE; - cmd.common.command_type = AUDPP_CMD_EQUALIZER; - if (enable) { - cmd.eq_flag = AUDPP_CMD_EQ_FLAG_ENA; - cmd.num_bands = eq->num_bands; - memcpy(&cmd.eq_coeff, &eq->eq_coeff, sizeof(eq->eq_coeff)); - } else - cmd.eq_flag = AUDPP_CMD_EQ_FLAG_DIS; - - return audpp_send_queue3(&cmd, sizeof(cmd)); -} -EXPORT_SYMBOL(audpp_dsp_set_eq); - -int audpp_dsp_set_vol_pan(unsigned id, - struct audpp_cmd_cfg_object_params_volume *vol_pan, - enum obj_type objtype) -{ - struct audpp_cmd_cfg_object_params_volume cmd; - - if (objtype) { - if (id > 5) { - MM_ERR("Wrong POPP decoder id: %d\n", id); - return -EINVAL; - } - } else { - if (id > AUDPP_MAX_COPP_DEVICES) { - MM_ERR("Wrong COPP decoder id: %d\n", id); - return -EINVAL; - } - } - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_OBJECT_PARAMS; - if (objtype) - cmd.common.stream = AUDPP_CMD_POPP_STREAM; - else - cmd.common.stream = AUDPP_CMD_COPP_STREAM; - - cmd.common.stream_id = id; - cmd.common.obj_cfg = AUDPP_CMD_CFG_OBJ_UPDATE; - cmd.common.command_type = AUDPP_CMD_VOLUME_PAN; - - cmd.volume = vol_pan->volume; - cmd.pan = vol_pan->pan; - - return audpp_send_queue3(&cmd, sizeof(cmd)); -} -EXPORT_SYMBOL(audpp_dsp_set_vol_pan); - -int audpp_pause(unsigned id, int pause) -{ - /* pause 1 = pause 0 = resume */ - u16 pause_cmd[AUDPP_CMD_DEC_CTRL_LEN / sizeof(unsigned short)]; - - if (id >= CH_COUNT) - return -EINVAL; - - memset(pause_cmd, 0, sizeof(pause_cmd)); - - pause_cmd[0] = AUDPP_CMD_DEC_CTRL; - pause_cmd[1] = id; - if (pause == 1) - pause_cmd[2] = AUDPP_CMD_UPDATE_V | AUDPP_CMD_PAUSE_V; - else if (pause == 0) - pause_cmd[2] = AUDPP_CMD_UPDATE_V | AUDPP_CMD_RESUME_V; - else - return -EINVAL; - - return audpp_send_queue1(pause_cmd, sizeof(pause_cmd)); -} -EXPORT_SYMBOL(audpp_pause); - -int audpp_flush(unsigned id) -{ - u16 flush_cmd[AUDPP_CMD_DEC_CTRL_LEN / sizeof(unsigned short)]; - - if (id >= CH_COUNT) - return -EINVAL; - - memset(flush_cmd, 0, sizeof(flush_cmd)); - - flush_cmd[0] = AUDPP_CMD_DEC_CTRL; - flush_cmd[1] = id; - flush_cmd[2] = AUDPP_CMD_UPDATE_V | AUDPP_CMD_FLUSH_V; - - return audpp_send_queue1(flush_cmd, sizeof(flush_cmd)); -} -EXPORT_SYMBOL(audpp_flush); - -/* dec_attrb = 7:0, 0 - No Decoder, else supported decoder * - * like mp3, aac, wma etc ... * - * = 15:8, bit[8] = 1 - Tunnel, bit[9] = 1 - NonTunnel * - * = 31:16, reserved */ -int audpp_adec_alloc(unsigned dec_attrb, const char **module_name, - unsigned *queueid) -{ - struct audpp_state *audpp = &the_audpp_state; - int decid = -1, idx, lidx, mode, codec; - int codecs_supported, min_codecs_supported; - unsigned int *concurrency_entry; - u8 max_instance, codec_type; - - struct dec_instance_table *dec_instance_list; - dec_instance_list = (struct dec_instance_table *) - (audpp->dec_database->dec_instance_list); - - mutex_lock(audpp->lock_dec); - /* Represents in bit mask */ - mode = ((dec_attrb & AUDPP_MODE_MASK) << 16); - codec = (1 << (dec_attrb & AUDPP_CODEC_MASK)); - codec_type = (dec_attrb & AUDPP_CODEC_MASK); - - /* Find whether same/different codec instances are running */ - audpp->decoder_count++; - audpp->codec_cnt[codec_type]++; - max_instance = 0; - - /*if different instance of codec*/ - if (audpp->codec_cnt[codec_type] < audpp->decoder_count) { - max_instance = audpp->codec_max_instances; - /* Get the maximum no. of instances that can be supported */ - for (idx = 0; idx < MSM_MAX_DEC_CNT; idx++) { - if (audpp->codec_cnt[idx]) { - if ((dec_instance_list + - audpp->op_mode * MSM_MAX_DEC_CNT + - idx)-> - max_instances_diff_dec < - max_instance) { - max_instance = - (dec_instance_list + - audpp->op_mode * - MSM_MAX_DEC_CNT - + idx)-> - max_instances_diff_dec; - } - } - } - /* if different codec type, should not cross maximum other - supported */ - if (audpp->decoder_count > (max_instance + 1)) { - MM_ERR("Can not support, already reached max\n"); - audpp->decoder_count--; - audpp->codec_cnt[codec_type]--; - goto done; - } - audpp->codec_max_instances = max_instance; - MM_DBG("different codec running\n"); - } else { - max_instance = (dec_instance_list + audpp->op_mode * - MSM_MAX_DEC_CNT + - codec_type)-> - max_instances_same_dec; - /* if same codec type, should not cross maximum supported */ - if (audpp->decoder_count > max_instance) { - MM_ERR("Can not support, already reached max\n"); - audpp->decoder_count--; - audpp->codec_cnt[codec_type]--; - goto done; - } - audpp->codec_max_instances = max_instance; - MM_DBG("same codec running\n"); - } - - /* Point to Last entry of the row */ - concurrency_entry = ((audpp->dec_database->dec_concurrency_table + - ((audpp->concurrency + 1) * - (audpp->dec_database->num_dec))) - 1); - - lidx = audpp->dec_database->num_dec; - min_codecs_supported = sizeof(unsigned int) * 8; - - MM_DBG("mode = 0x%08x codec = 0x%08x\n", mode, codec); - - for (idx = lidx; idx > 0; idx--, concurrency_entry--) { - if (!(audpp->dec_inuse & (1 << (idx - 1)))) { - if (((mode & *concurrency_entry) == mode) && - (codec & *concurrency_entry)) { - /* Check supports minimum number codecs */ - codecs_supported = - audpp->dec_database->dec_info_list[idx - - 1]. - nr_codec_support; - if (codecs_supported < min_codecs_supported) { - lidx = idx - 1; - min_codecs_supported = codecs_supported; - } - } - } - } - - if (lidx < audpp->dec_database->num_dec) { - audpp->dec_inuse |= (1 << lidx); - *module_name = - audpp->dec_database->dec_info_list[lidx].module_name; - *queueid = - audpp->dec_database->dec_info_list[lidx].module_queueid; - decid = audpp->dec_database->dec_info_list[lidx].module_decid; - audpp->dec_info_table[lidx].codec = - (dec_attrb & AUDPP_CODEC_MASK); - audpp->dec_info_table[lidx].pid = current->pid; - /* point to row to get supported operation */ - concurrency_entry = - ((audpp->dec_database->dec_concurrency_table + - ((audpp->concurrency) * (audpp->dec_database->num_dec))) + - lidx); - decid |= ((*concurrency_entry & AUDPP_OP_MASK) >> 12); - MM_INFO("decid =0x%08x module_name=%s, queueid=%d \n", decid, - *module_name, *queueid); - } -done: - mutex_unlock(audpp->lock_dec); - return decid; - -} -EXPORT_SYMBOL(audpp_adec_alloc); - -void audpp_adec_free(int decid) -{ - struct audpp_state *audpp = &the_audpp_state; - int idx; - mutex_lock(audpp->lock_dec); - for (idx = audpp->dec_database->num_dec; idx > 0; idx--) { - if (audpp->dec_database->dec_info_list[idx - 1].module_decid == - decid) { - audpp->decoder_count--; - audpp->\ - codec_cnt[audpp->dec_info_table[idx - 1].codec]--; - audpp->dec_inuse &= ~(1 << (idx - 1)); - audpp->dec_info_table[idx - 1].codec = -1; - audpp->dec_info_table[idx - 1].pid = 0; - MM_INFO("free decid =%d \n", decid); - break; - } - } - mutex_unlock(audpp->lock_dec); - return; - -} -EXPORT_SYMBOL(audpp_adec_free); - -static ssize_t concurrency_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct audpp_state *audpp = &the_audpp_state; - int rc; - mutex_lock(audpp->lock_dec); - rc = sprintf(buf, "%ld\n", audpp->concurrency); - mutex_unlock(audpp->lock_dec); - return rc; -} - -static ssize_t concurrency_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct audpp_state *audpp = &the_audpp_state; - unsigned long concurrency; - int rc = -1; - mutex_lock(audpp->lock_dec); - if (audpp->dec_inuse) { - MM_ERR("Can not change profile, while playback in progress\n"); - goto done; - } - rc = strict_strtoul(buf, 10, &concurrency); - if (!rc && - (concurrency < audpp->dec_database->num_concurrency_support)) { - audpp->concurrency = concurrency; - MM_DBG("Concurrency case %ld\n", audpp->concurrency); - rc = count; - } else { - MM_ERR("Not a valid Concurrency case\n"); - rc = -EINVAL; - } -done: - mutex_unlock(audpp->lock_dec); - return rc; -} - -static ssize_t decoder_info_show(struct device *dev, - struct device_attribute *attr, char *buf); -static struct device_attribute dev_attr_decoder[AUDPP_MAX_DECODER_CNT] = { - __ATTR(decoder0, S_IRUGO, decoder_info_show, NULL), - __ATTR(decoder1, S_IRUGO, decoder_info_show, NULL), - __ATTR(decoder2, S_IRUGO, decoder_info_show, NULL), - __ATTR(decoder3, S_IRUGO, decoder_info_show, NULL), - __ATTR(decoder4, S_IRUGO, decoder_info_show, NULL), -}; - -static ssize_t decoder_info_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int cpy_sz = 0; - struct audpp_state *audpp = &the_audpp_state; - const ptrdiff_t off = attr - dev_attr_decoder; /* decoder number */ - mutex_lock(audpp->lock_dec); - cpy_sz += scnprintf(buf + cpy_sz, PAGE_SIZE - cpy_sz, "%d:", - audpp->dec_info_table[off].codec); - cpy_sz += scnprintf(buf + cpy_sz, PAGE_SIZE - cpy_sz, "%d\n", - audpp->dec_info_table[off].pid); - mutex_unlock(audpp->lock_dec); - return cpy_sz; -} - -static DEVICE_ATTR(concurrency, S_IWUSR | S_IRUGO, concurrency_show, - concurrency_store); -static int audpp_probe(struct platform_device *pdev) -{ - int rc, idx; - struct audpp_state *audpp = &the_audpp_state; - audpp->concurrency = AUDPP_CONCURRENCY_DEFAULT; - audpp->dec_database = - (struct msm_adspdec_database *)pdev->dev.platform_data; - - MM_INFO("Number of decoder supported %d\n", - audpp->dec_database->num_dec); - MM_INFO("Number of concurrency supported %d\n", - audpp->dec_database->num_concurrency_support); - init_waitqueue_head(&audpp->event_wait); - for (idx = 0; idx < audpp->dec_database->num_dec; idx++) { - audpp->dec_info_table[idx].codec = -1; - audpp->dec_info_table[idx].pid = 0; - MM_INFO("module_name:%s\n", - audpp->dec_database->dec_info_list[idx].module_name); - MM_INFO("queueid:%d\n", - audpp->dec_database->dec_info_list[idx].module_queueid); - MM_INFO("decid:%d\n", - audpp->dec_database->dec_info_list[idx].module_decid); - MM_INFO("nr_codec_support:%d\n", - audpp->dec_database->dec_info_list[idx]. - nr_codec_support); - } - - wake_lock_init(&audpp_wake_lock, WAKE_LOCK_SUSPEND, "audpp"); - for (idx = 0; idx < audpp->dec_database->num_dec; idx++) { - rc = device_create_file(&pdev->dev, &dev_attr_decoder[idx]); - if (rc) - goto err; - } - rc = device_create_file(&pdev->dev, &dev_attr_concurrency); - audpp->op_mode = 0; /* Consider as non turbo mode */ - if (rc) - goto err; - else - goto done; -err: - while (idx--) - device_remove_file(&pdev->dev, &dev_attr_decoder[idx]); -done: - return rc; -} - -static struct platform_driver audpp_plat_driver = { - .probe = audpp_probe, - .driver = { - .name = "msm_adspdec", - .owner = THIS_MODULE, - }, -}; - -static int __init audpp_init(void) -{ - return platform_driver_register(&audpp_plat_driver); -} - -device_initcall(audpp_init); diff --git a/arch/arm/mach-msm/qdsp5v2/audpreproc.c b/arch/arm/mach-msm/qdsp5v2/audpreproc.c deleted file mode 100644 index 28eead08e81992974008b23cf57fc0ed635df187..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/audpreproc.c +++ /dev/null @@ -1,527 +0,0 @@ -/* - * Common code to deal with the AUDPREPROC dsp task (audio preprocessing) - * - * Copyright (c) 2009-2011, The Linux Foundation. All rights reserved. - * - * Based on the audpp layer in arch/arm/mach-msm/qdsp5/audpp.c - * - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -static DEFINE_MUTEX(audpreproc_lock); -static struct wake_lock audpre_wake_lock; -static struct pm_qos_request audpre_pm_qos_req; - -struct msm_adspenc_info { - const char *module_name; - unsigned module_queueids; - int module_encid; /* streamid */ - int enc_formats; /* supported formats */ - int nr_codec_support; /* number of codec suported */ -}; - -#define ENC_MODULE_INFO(name, queueids, encid, formats, nr_codec) \ - {.module_name = name, .module_queueids = queueids, \ - .module_encid = encid, .enc_formats = formats, \ - .nr_codec_support = nr_codec } - -#define MAX_EVENT_CALLBACK_CLIENTS 1 - -#define ENC0_FORMAT ((1<func[cfg_done_msg.stream_id]) - audpreproc->func[cfg_done_msg.stream_id]( - audpreproc->private[cfg_done_msg.stream_id], id, - &cfg_done_msg); - break; - } - case AUDPREPROC_ERROR_MSG: { - struct audpreproc_err_msg err_msg; - - getevent(&err_msg, AUDPREPROC_ERROR_MSG_LEN); - MM_DBG("AUDPREPROC_ERROR_MSG: stream id %d err idx %d\n", - err_msg.stream_id, err_msg.aud_preproc_err_idx); - if ((err_msg.stream_id < MAX_ENC_COUNT) && - audpreproc->func[err_msg.stream_id]) - audpreproc->func[err_msg.stream_id]( - audpreproc->private[err_msg.stream_id], id, - &err_msg); - break; - } - case AUDPREPROC_CMD_ENC_CFG_DONE_MSG: { - struct audpreproc_cmd_enc_cfg_done_msg enc_cfg_msg; - - getevent(&enc_cfg_msg, AUDPREPROC_CMD_ENC_CFG_DONE_MSG_LEN); - MM_DBG("AUDPREPROC_CMD_ENC_CFG_DONE_MSG: stream id %d enc type \ - %d\n", enc_cfg_msg.stream_id, enc_cfg_msg.rec_enc_type); - if ((enc_cfg_msg.stream_id < MAX_ENC_COUNT) && - audpreproc->func[enc_cfg_msg.stream_id]) - audpreproc->func[enc_cfg_msg.stream_id]( - audpreproc->private[enc_cfg_msg.stream_id], id, - &enc_cfg_msg); - for (n = 0; n < MAX_EVENT_CALLBACK_CLIENTS; ++n) { - if (audpreproc->cb_tbl[n] && - audpreproc->cb_tbl[n]->fn) { - audpreproc->cb_tbl[n]->fn( \ - audpreproc->cb_tbl[n]->private, \ - id, (void *) &enc_cfg_msg); - } - } - break; - } - case AUDPREPROC_CMD_ENC_PARAM_CFG_DONE_MSG: { - struct audpreproc_cmd_enc_param_cfg_done_msg enc_param_msg; - - getevent(&enc_param_msg, - AUDPREPROC_CMD_ENC_PARAM_CFG_DONE_MSG_LEN); - MM_DBG("AUDPREPROC_CMD_ENC_PARAM_CFG_DONE_MSG: stream id %d\n", - enc_param_msg.stream_id); - if ((enc_param_msg.stream_id < MAX_ENC_COUNT) && - audpreproc->func[enc_param_msg.stream_id]) - audpreproc->func[enc_param_msg.stream_id]( - audpreproc->private[enc_param_msg.stream_id], id, - &enc_param_msg); - break; - } - case AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG_DONE_MSG: { - struct audpreproc_afe_cmd_audio_record_cfg_done - record_cfg_done; - getevent(&record_cfg_done, - AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG_DONE_MSG_LEN); - MM_DBG("AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG_DONE_MSG: \ - stream id %d\n", record_cfg_done.stream_id); - if ((record_cfg_done.stream_id < MAX_ENC_COUNT) && - audpreproc->func[record_cfg_done.stream_id]) - audpreproc->func[record_cfg_done.stream_id]( - audpreproc->private[record_cfg_done.stream_id], id, - &record_cfg_done); - break; - } - case AUDPREPROC_CMD_ROUTING_MODE_DONE_MSG: { - struct audpreproc_cmd_routing_mode_done routing_mode_done; - - getevent(&routing_mode_done, - AUDPREPROC_CMD_ROUTING_MODE_DONE_MSG_LEN); - MM_DBG("AUDPREPROC_CMD_ROUTING_MODE_DONE_MSG: \ - stream id %d\n", routing_mode_done.stream_id); - if ((routing_mode_done.stream_id < MAX_ENC_COUNT) && - audpreproc->func[routing_mode_done.stream_id]) - audpreproc->func[routing_mode_done.stream_id]( - audpreproc->private[routing_mode_done.stream_id], id, - &routing_mode_done); - break; - } -#ifdef CONFIG_DEBUG_FS - case AUDPREPROC_MSG_FEAT_QUERY_DM_DONE: - { - uint16_t msg[3]; - getevent(msg, sizeof(msg)); - MM_INFO("RTC ACK --> %x %x %x\n", msg[0], msg[1], msg[2]); - acdb_rtc_set_err(msg[2]); - } - break; -#endif - case ADSP_MESSAGE_ID: { - MM_DBG("Received ADSP event:module audpreproctask\n"); - break; - } - default: - MM_ERR("Unknown Event %d\n", id); - } - return; -} - -static struct msm_adsp_ops adsp_ops = { - .event = audpreproc_dsp_event, -}; - -/* EXPORTED API's */ -int audpreproc_enable(int enc_id, audpreproc_event_func func, void *private) -{ - struct audpreproc_state *audpreproc = &the_audpreproc_state; - int res = 0; - - if (enc_id < 0 || enc_id > (MAX_ENC_COUNT - 1)) - return -EINVAL; - - mutex_lock(audpreproc->lock); - if (audpreproc->func[enc_id]) { - res = -EBUSY; - goto out; - } - - audpreproc->func[enc_id] = func; - audpreproc->private[enc_id] = private; - - /* First client to enable preproc task */ - if (audpreproc->open_count++ == 0) { - MM_DBG("Get AUDPREPROCTASK\n"); - res = msm_adsp_get("AUDPREPROCTASK", &audpreproc->mod, - &adsp_ops, audpreproc); - if (res < 0) { - MM_ERR("Can not get AUDPREPROCTASK\n"); - audpreproc->open_count = 0; - audpreproc->func[enc_id] = NULL; - audpreproc->private[enc_id] = NULL; - goto out; - } - prevent_suspend(); - if (msm_adsp_enable(audpreproc->mod)) { - MM_ERR("Can not enable AUDPREPROCTASK\n"); - audpreproc->open_count = 0; - audpreproc->func[enc_id] = NULL; - audpreproc->private[enc_id] = NULL; - msm_adsp_put(audpreproc->mod); - audpreproc->mod = NULL; - res = -ENODEV; - allow_suspend(); - goto out; - } - } - res = 0; -out: - mutex_unlock(audpreproc->lock); - return res; -} -EXPORT_SYMBOL(audpreproc_enable); - -int audpreproc_update_audrec_info( - struct audrec_session_info *audrec_session_info) -{ - if (!audrec_session_info) { - MM_ERR("error in audrec session info address\n"); - return -EINVAL; - } - if (audrec_session_info->session_id < MAX_ENC_COUNT) { - memcpy(&session_info[audrec_session_info->session_id], - audrec_session_info, - sizeof(struct audrec_session_info)); - return 0; - } - return -EINVAL; -} -EXPORT_SYMBOL(audpreproc_update_audrec_info); - -void audpreproc_disable(int enc_id, void *private) -{ - struct audpreproc_state *audpreproc = &the_audpreproc_state; - - if (enc_id < 0 || enc_id > (MAX_ENC_COUNT - 1)) - return; - - mutex_lock(audpreproc->lock); - if (!audpreproc->func[enc_id]) - goto out; - if (audpreproc->private[enc_id] != private) - goto out; - - audpreproc->func[enc_id] = NULL; - audpreproc->private[enc_id] = NULL; - - /* Last client then disable preproc task */ - if (--audpreproc->open_count == 0) { - msm_adsp_disable(audpreproc->mod); - MM_DBG("Put AUDPREPROCTASK\n"); - msm_adsp_put(audpreproc->mod); - audpreproc->mod = NULL; - allow_suspend(); - } -out: - mutex_unlock(audpreproc->lock); - return; -} -EXPORT_SYMBOL(audpreproc_disable); - - -int audpreproc_register_event_callback(struct audpreproc_event_callback *ecb) -{ - struct audpreproc_state *audpreproc = &the_audpreproc_state; - int i; - - for (i = 0; i < MAX_EVENT_CALLBACK_CLIENTS; ++i) { - if (NULL == audpreproc->cb_tbl[i]) { - audpreproc->cb_tbl[i] = ecb; - return 0; - } - } - return -1; -} -EXPORT_SYMBOL(audpreproc_register_event_callback); - -int audpreproc_unregister_event_callback(struct audpreproc_event_callback *ecb) -{ - struct audpreproc_state *audpreproc = &the_audpreproc_state; - int i; - - for (i = 0; i < MAX_EVENT_CALLBACK_CLIENTS; ++i) { - if (ecb == audpreproc->cb_tbl[i]) { - audpreproc->cb_tbl[i] = NULL; - return 0; - } - } - return -1; -} -EXPORT_SYMBOL(audpreproc_unregister_event_callback); - - -/* enc_type = supported encode format * - * like pcm, aac, sbc, evrc, qcelp, amrnb etc ... * - */ -int audpreproc_aenc_alloc(unsigned enc_type, const char **module_name, - unsigned *queue_ids) -{ - struct audpreproc_state *audpreproc = &the_audpreproc_state; - int encid = -1, idx, lidx, mode, codec; - int codecs_supported, min_codecs_supported; - static int wakelock_init; - - mutex_lock(audpreproc->lock); - /* Represents in bit mask */ - mode = ((enc_type & AUDPREPROC_MODE_MASK) << 16); - codec = (1 << (enc_type & AUDPREPROC_CODEC_MASK)); - - lidx = msm_enc_database.num_enc; - min_codecs_supported = sizeof(unsigned int) * 8; - MM_DBG("mode = 0x%08x codec = 0x%08x\n", mode, codec); - - for (idx = lidx-1; idx >= 0; idx--) { - /* encoder free and supports the format */ - if (!(audpreproc->enc_inuse & (1 << (idx))) && - ((mode & msm_enc_database.enc_info_list[idx].enc_formats) - == mode) && ((codec & - msm_enc_database.enc_info_list[idx].enc_formats) - == codec)){ - /* Check supports minimum number codecs */ - codecs_supported = - msm_enc_database.enc_info_list[idx].nr_codec_support; - if (codecs_supported < min_codecs_supported) { - lidx = idx; - min_codecs_supported = codecs_supported; - } - } - } - - if (lidx < msm_enc_database.num_enc) { - audpreproc->enc_inuse |= (1 << lidx); - *module_name = - msm_enc_database.enc_info_list[lidx].module_name; - *queue_ids = - msm_enc_database.enc_info_list[lidx].module_queueids; - encid = msm_enc_database.enc_info_list[lidx].module_encid; - } - - if (!wakelock_init) { - wake_lock_init(&audpre_wake_lock, WAKE_LOCK_SUSPEND, "audpre"); - pm_qos_add_request(&audpre_pm_qos_req, PM_QOS_CPU_DMA_LATENCY, - PM_QOS_DEFAULT_VALUE); - wakelock_init = 1; - } - - mutex_unlock(audpreproc->lock); - return encid; -} -EXPORT_SYMBOL(audpreproc_aenc_alloc); - -void audpreproc_aenc_free(int enc_id) -{ - struct audpreproc_state *audpreproc = &the_audpreproc_state; - int idx; - - mutex_lock(audpreproc->lock); - for (idx = 0; idx < msm_enc_database.num_enc; idx++) { - if (msm_enc_database.enc_info_list[idx].module_encid == - enc_id) { - audpreproc->enc_inuse &= ~(1 << idx); - break; - } - } - mutex_unlock(audpreproc->lock); - return; - -} -EXPORT_SYMBOL(audpreproc_aenc_free); - -int audpreproc_send_preproccmdqueue(void *cmd, unsigned len) -{ - return msm_adsp_write(the_audpreproc_state.mod, - QDSP_uPAudPreProcCmdQueue, cmd, len); -} -EXPORT_SYMBOL(audpreproc_send_preproccmdqueue); - -int audpreproc_send_audreccmdqueue(void *cmd, unsigned len) -{ - return msm_adsp_write(the_audpreproc_state.mod, - QDSP_uPAudPreProcAudRecCmdQueue, cmd, len); -} -EXPORT_SYMBOL(audpreproc_send_audreccmdqueue); - -int audpreproc_send_audrec2cmdqueue(void *cmd, unsigned len) -{ - return msm_adsp_write(the_audpreproc_state.mod, - QDSP_uPAudRec2CmdQueue, cmd, len); -} -EXPORT_SYMBOL(audpreproc_send_audrec2cmdqueue); - -int audpreproc_dsp_set_agc(struct audpreproc_cmd_cfg_agc_params *agc, - unsigned len) -{ - return msm_adsp_write(the_audpreproc_state.mod, - QDSP_uPAudPreProcCmdQueue, agc, len); -} -EXPORT_SYMBOL(audpreproc_dsp_set_agc); - -int audpreproc_dsp_set_agc2(struct audpreproc_cmd_cfg_agc_params_2 *agc2, - unsigned len) -{ - return msm_adsp_write(the_audpreproc_state.mod, - QDSP_uPAudPreProcCmdQueue, agc2, len); -} -EXPORT_SYMBOL(audpreproc_dsp_set_agc2); - -int audpreproc_dsp_set_ns(struct audpreproc_cmd_cfg_ns_params *ns, - unsigned len) -{ - return msm_adsp_write(the_audpreproc_state.mod, - QDSP_uPAudPreProcCmdQueue, ns, len); -} -EXPORT_SYMBOL(audpreproc_dsp_set_ns); - -int audpreproc_dsp_set_iir( -struct audpreproc_cmd_cfg_iir_tuning_filter_params *iir, unsigned len) -{ - return msm_adsp_write(the_audpreproc_state.mod, - QDSP_uPAudPreProcCmdQueue, iir, len); -} -EXPORT_SYMBOL(audpreproc_dsp_set_iir); - -int audpreproc_dsp_set_gain_tx( - struct audpreproc_cmd_cfg_cal_gain *calib_gain_tx, unsigned len) -{ - return msm_adsp_write(the_audpreproc_state.mod, - QDSP_uPAudPreProcCmdQueue, calib_gain_tx, len); -} -EXPORT_SYMBOL(audpreproc_dsp_set_gain_tx); - -void get_audrec_session_info(int id, struct audrec_session_info *info) -{ - if (id >= MAX_ENC_COUNT) { - MM_ERR("invalid session id = %d\n", id); - return; - } - memcpy(info, &session_info[id], sizeof(struct audrec_session_info)); -} -EXPORT_SYMBOL(get_audrec_session_info); - -int audpreproc_dsp_set_lvnv( - struct audpreproc_cmd_cfg_lvnv_param *preproc_lvnv, unsigned len) -{ - return msm_adsp_write(the_audpreproc_state.mod, - QDSP_uPAudPreProcCmdQueue, preproc_lvnv, len); -} -EXPORT_SYMBOL(audpreproc_dsp_set_lvnv); - diff --git a/arch/arm/mach-msm/qdsp5v2/aux_pcm.c b/arch/arm/mach-msm/qdsp5v2/aux_pcm.c deleted file mode 100644 index 06318bc7f78aff4cb8ca2e5cab53ebbb074844bc..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/aux_pcm.c +++ /dev/null @@ -1,280 +0,0 @@ -/* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/*---------------------------------------------------------------------------- - * Preprocessor Definitions and Constants - * -------------------------------------------------------------------------*/ - -/* define offset of registers here, may put them into platform data */ -#define AUX_CODEC_CTL_OFFSET 0x00 -#define PCM_PATH_CTL_OFFSET 0x04 -#define AUX_CODEC_CTL_OUT_OFFSET 0x08 - -/* define some bit values in PCM_PATH_CTL register */ -#define PCM_PATH_CTL__ADSP_CTL_EN_BMSK 0x8 - -/* mask and shift */ -#define AUX_CODEC_CTL_ADSP_CODEC_CTL_EN_BMSK 0x800 -#define AUX_CODEC_CTL_PCM_SYNC_LONG_BMSK 0x400 -#define AUX_CODEC_CTL_PCM_SYNC_SHORT_BMSK 0x200 -#define AUX_CODEC_CTL_I2S_SAMPLE_CLK_SRC_BMSK 0x80 -#define AUX_CODEC_CTL_I2S_SAMPLE_CLK_MODE_BMSK 0x40 -#define AUX_CODEC_CTL_I2S_RX_MODE_BMSK 0x20 -#define AUX_CODEC_CTL_I2S_CLK_MODE_BMSK 0x10 -#define AUX_CODEC_CTL_AUX_PCM_MODE_BMSK 0x0b -#define AUX_CODEC_CTL_AUX_CODEC_MODE_BMSK 0x02 - -/* AUX PCM MODE */ -#define MASTER_PRIM_PCM_SHORT 0 -#define MASTER_AUX_PCM_LONG 1 -#define SLAVE_PRIM_PCM_SHORT 2 - -struct aux_pcm_state { - void __iomem *aux_pcm_base; /* configure aux pcm through Scorpion */ - int dout; - int din; - int syncout; - int clkin_a; -}; - -static struct aux_pcm_state the_aux_pcm_state; - -static void __iomem *get_base_addr(struct aux_pcm_state *aux_pcm) -{ - return aux_pcm->aux_pcm_base; -} - -/* Set who control aux pcm : adsp or MSM */ -void aux_codec_adsp_codec_ctl_en(bool msm_adsp_en) -{ - void __iomem *baddr = get_base_addr(&the_aux_pcm_state); - uint32_t val; - - if (!IS_ERR(baddr)) { - val = readl(baddr + AUX_CODEC_CTL_OFFSET); - if (msm_adsp_en) { /* adsp */ - writel( - ((val & ~AUX_CODEC_CTL_ADSP_CODEC_CTL_EN_BMSK) | - AUX_CODEC_CTL__ADSP_CODEC_CTL_EN__ADSP_V), - baddr + AUX_CODEC_CTL_OFFSET); - } else { /* MSM */ - writel( - ((val & ~AUX_CODEC_CTL_ADSP_CODEC_CTL_EN_BMSK) | - AUX_CODEC_CTL__ADSP_CODEC_CTL_EN__MSM_V), - baddr + AUX_CODEC_CTL_OFFSET); - } - } - mb(); -} - -/* Set who control aux pcm path: adsp or MSM */ -void aux_codec_pcm_path_ctl_en(bool msm_adsp_en) -{ - void __iomem *baddr = get_base_addr(&the_aux_pcm_state); - uint32_t val; - - if (!IS_ERR(baddr)) { - val = readl(baddr + PCM_PATH_CTL_OFFSET); - if (msm_adsp_en) { /* adsp */ - writel( - ((val & ~PCM_PATH_CTL__ADSP_CTL_EN_BMSK) | - PCM_PATH_CTL__ADSP_CTL_EN__ADSP_V), - baddr + PCM_PATH_CTL_OFFSET); - } else { /* MSM */ - writel( - ((val & ~PCM_PATH_CTL__ADSP_CTL_EN_BMSK) | - PCM_PATH_CTL__ADSP_CTL_EN__MSM_V), - baddr + PCM_PATH_CTL_OFFSET); - } - } - mb(); - return; -} -EXPORT_SYMBOL(aux_codec_pcm_path_ctl_en); - -int aux_pcm_gpios_request(void) -{ - int rc = 0; - - MM_DBG("aux_pcm_gpios_request\n"); - rc = gpio_request(the_aux_pcm_state.dout, "AUX PCM DOUT"); - if (rc) { - MM_ERR("GPIO request for AUX PCM DOUT failed\n"); - return rc; - } - - rc = gpio_request(the_aux_pcm_state.din, "AUX PCM DIN"); - if (rc) { - MM_ERR("GPIO request for AUX PCM DIN failed\n"); - gpio_free(the_aux_pcm_state.dout); - return rc; - } - - rc = gpio_request(the_aux_pcm_state.syncout, "AUX PCM SYNC OUT"); - if (rc) { - MM_ERR("GPIO request for AUX PCM SYNC OUT failed\n"); - gpio_free(the_aux_pcm_state.dout); - gpio_free(the_aux_pcm_state.din); - return rc; - } - - rc = gpio_request(the_aux_pcm_state.clkin_a, "AUX PCM CLKIN A"); - if (rc) { - MM_ERR("GPIO request for AUX PCM CLKIN A failed\n"); - gpio_free(the_aux_pcm_state.dout); - gpio_free(the_aux_pcm_state.din); - gpio_free(the_aux_pcm_state.syncout); - return rc; - } - - return rc; -} -EXPORT_SYMBOL(aux_pcm_gpios_request); - - -void aux_pcm_gpios_free(void) -{ - MM_DBG(" aux_pcm_gpios_free \n"); - - /* - * Feed silence frames before close to prevent buzzing sound in BT at - * call end. This fix is applicable only to Marimba BT. - */ - gpio_tlmm_config(GPIO_CFG(the_aux_pcm_state.dout, 0, GPIO_CFG_OUTPUT, - GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE); - gpio_set_value(the_aux_pcm_state.dout, 0); - msleep(20); - gpio_tlmm_config(GPIO_CFG(the_aux_pcm_state.dout, 1, GPIO_CFG_OUTPUT, - GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE); - - gpio_free(the_aux_pcm_state.dout); - gpio_free(the_aux_pcm_state.din); - gpio_free(the_aux_pcm_state.syncout); - gpio_free(the_aux_pcm_state.clkin_a); -} -EXPORT_SYMBOL(aux_pcm_gpios_free); - - -static int get_aux_pcm_gpios(struct platform_device *pdev) -{ - int rc = 0; - struct resource *res; - - /* Claim all of the GPIOs. */ - res = platform_get_resource_byname(pdev, IORESOURCE_IO, - "aux_pcm_dout"); - if (!res) { - MM_ERR("%s: failed to get gpio AUX PCM DOUT\n", __func__); - return -ENODEV; - } - - the_aux_pcm_state.dout = res->start; - - res = platform_get_resource_byname(pdev, IORESOURCE_IO, - "aux_pcm_din"); - if (!res) { - MM_ERR("%s: failed to get gpio AUX PCM DIN\n", __func__); - return -ENODEV; - } - - the_aux_pcm_state.din = res->start; - - res = platform_get_resource_byname(pdev, IORESOURCE_IO, - "aux_pcm_syncout"); - if (!res) { - MM_ERR("%s: failed to get gpio AUX PCM SYNC OUT\n", __func__); - return -ENODEV; - } - - the_aux_pcm_state.syncout = res->start; - - res = platform_get_resource_byname(pdev, IORESOURCE_IO, - "aux_pcm_clkin_a"); - if (!res) { - MM_ERR("%s: failed to get gpio AUX PCM CLKIN A\n", __func__); - return -ENODEV; - } - - the_aux_pcm_state.clkin_a = res->start; - - return rc; -} -static int aux_pcm_probe(struct platform_device *pdev) -{ - int rc = 0; - struct resource *mem_src; - - MM_DBG("aux_pcm_probe \n"); - mem_src = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "aux_codec_reg_addr"); - if (!mem_src) { - rc = -ENODEV; - goto done; - } - - the_aux_pcm_state.aux_pcm_base = ioremap(mem_src->start, - (mem_src->end - mem_src->start) + 1); - if (!the_aux_pcm_state.aux_pcm_base) { - rc = -ENOMEM; - goto done; - } - rc = get_aux_pcm_gpios(pdev); - if (rc) { - MM_ERR("GPIO configuration failed\n"); - rc = -ENODEV; - } - -done: return rc; - -} - -static int aux_pcm_remove(struct platform_device *pdev) -{ - iounmap(the_aux_pcm_state.aux_pcm_base); - return 0; -} - -static struct platform_driver aux_pcm_driver = { - .probe = aux_pcm_probe, - .remove = aux_pcm_remove, - .driver = { - .name = "msm_aux_pcm", - .owner = THIS_MODULE, - }, -}; - -static int __init aux_pcm_init(void) -{ - - return platform_driver_register(&aux_pcm_driver); -} - -static void __exit aux_pcm_exit(void) -{ - platform_driver_unregister(&aux_pcm_driver); -} - -module_init(aux_pcm_init); -module_exit(aux_pcm_exit); - -MODULE_DESCRIPTION("MSM AUX PCM driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5v2/lpa.c b/arch/arm/mach-msm/qdsp5v2/lpa.c deleted file mode 100644 index 5ffda8ad700d3c1f456972b61418ea3c781c44c1..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/lpa.c +++ /dev/null @@ -1,608 +0,0 @@ -/* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define LPA_REG_WRITEL(drv, val, reg) writel(val, drv->baseaddr + reg) -#define LPA_REG_READL(drv, reg) readl(drv->baseaddr + reg) - -/* bit 2:0 is reserved because watermarks have to be 64-bit aligned */ -#define LLB_WATERMARK_VAL_MASK 0x00000003 - -#define LPA_STATUS_SBUF_EN 0x01 - -struct lpa_drv { - void __iomem *baseaddr; - u32 obuf_hlb_size; - u32 dsp_proc_id; - u32 app_proc_id; - struct lpa_mem_config nosb_config; - struct lpa_mem_config sb_config; - u32 status; - u32 watermark_bytes; - u32 watermark_aheadtime; - u32 sample_boundary; -}; - -struct lpa_state { - struct lpa_drv lpa_drv; /* One instance for now */ - u32 assigned; - struct mutex lpa_lock; -}; - -struct lpa_state the_lpa_state; - -static void lpa_enable_codec(struct lpa_drv *lpa, bool enable) -{ - u32 val; - - val = LPA_REG_READL(lpa, LPA_OBUF_CODEC); - val = enable ? (val | LPA_OBUF_CODEC_CODEC_INTF_EN_BMSK) : - (val & ~LPA_OBUF_CODEC_CODEC_INTF_EN_BMSK); - val |= LPA_OBUF_CODEC_LOAD_BMSK; - LPA_REG_WRITEL(lpa, val, LPA_OBUF_CODEC); - mb(); -} - -static void lpa_reset(struct lpa_drv *lpa) -{ - u32 status; - struct clk *adsp_clk; - /* Need to make sure not disable clock while other device is enabled */ - adsp_clk = clk_get(NULL, "adsp_clk"); - if (!adsp_clk) { - MM_ERR("failed to get adsp clk\n"); - goto error; - } - clk_prepare_enable(adsp_clk); - lpa_enable_codec(lpa, 0); - LPA_REG_WRITEL(lpa, (LPA_OBUF_RESETS_MISR_RESET | - LPA_OBUF_RESETS_OVERALL_RESET), LPA_OBUF_RESETS); - do { - status = LPA_REG_READL(lpa, LPA_OBUF_STATUS); - } while (!(status & LPA_OBUF_STATUS_RESET_DONE)); - - LPA_REG_WRITEL(lpa, LPA_OBUF_ACK_RESET_DONE_BMSK, LPA_OBUF_ACK); - mb(); - clk_disable_unprepare(adsp_clk); - clk_put(adsp_clk); -error: - return; -} - -static void lpa_config_hlb_addr(struct lpa_drv *lpa) -{ - u32 val, min_addr = 0, max_addr = min_addr + lpa->obuf_hlb_size; - - val = (min_addr & LPA_OBUF_HLB_MIN_ADDR_SEG_BMSK) | - LPA_OBUF_HLB_MIN_ADDR_LOAD_BMSK; - LPA_REG_WRITEL(lpa, val, LPA_OBUF_HLB_MIN_ADDR); - val = max_addr & LPA_OBUF_HLB_MAX_ADDR_SEG_BMSK; - LPA_REG_WRITEL(lpa, val, LPA_OBUF_HLB_MAX_ADDR); -} - -static void lpa_powerup_mem_bank(struct lpa_drv *lpa, - struct lpa_mem_bank_select *bank) -{ - u32 status, val; - - status = LPA_REG_READL(lpa, LPA_OBUF_MEMORY_CONTROL); - val = ((*((u32 *) bank)) << LPA_OBUF_MEM_CTL_PWRUP_SHFT) & - LPA_OBUF_MEM_CTL_PWRUP_BMSK; - val |= status; - LPA_REG_WRITEL(lpa, val, LPA_OBUF_MEMORY_CONTROL); -} - -static void lpa_enable_interrupt(struct lpa_drv *lpa, u32 proc_id) -{ - u32 val; - - proc_id &= LPA_OBUF_INTR_EN_BMSK; - val = 0x1 << proc_id; - LPA_REG_WRITEL(lpa, val, LPA_OBUF_INTR_ENABLE); -} - -static void lpa_config_llb_addr(struct lpa_drv *lpa, u32 min_addr, u32 max_addr) -{ - u32 val; - - val = (min_addr & LPA_OBUF_LLB_MIN_ADDR_SEG_BMSK) | - LPA_OBUF_LLB_MIN_ADDR_LOAD_BMSK; - LPA_REG_WRITEL(lpa, val, LPA_OBUF_LLB_MIN_ADDR); - val = max_addr & LPA_OBUF_LLB_MAX_ADDR_SEG_BMSK; - LPA_REG_WRITEL(lpa, val, LPA_OBUF_LLB_MAX_ADDR); -} - -static void lpa_config_sb_addr(struct lpa_drv *lpa, u32 min_addr, u32 max_addr) -{ - u32 val; - - val = (min_addr & LPA_OBUF_SB_MIN_ADDR_SEG_BMSK) | - LPA_OBUF_SB_MIN_ADDR_LOAD_BMSK; - LPA_REG_WRITEL(lpa, val, LPA_OBUF_SB_MIN_ADDR); - val = max_addr & LPA_OBUF_SB_MAX_ADDR_SEG_BMSK; - LPA_REG_WRITEL(lpa, val, LPA_OBUF_SB_MAX_ADDR); -} - -static void lpa_switch_sb(struct lpa_drv *lpa) -{ - if (lpa->status & LPA_STATUS_SBUF_EN) { - lpa_config_llb_addr(lpa, lpa->sb_config.llb_min_addr, - lpa->sb_config.llb_max_addr); - lpa_config_sb_addr(lpa, lpa->sb_config.sb_min_addr, - lpa->sb_config.sb_max_addr); - } else { - lpa_config_llb_addr(lpa, lpa->nosb_config.llb_min_addr, - lpa->nosb_config.llb_max_addr); - lpa_config_sb_addr(lpa, lpa->nosb_config.sb_min_addr, - lpa->nosb_config.sb_max_addr); - } -} - -static u8 lpa_req_wmark_id(struct lpa_drv *lpa) -{ - return (u8) (LPA_REG_READL(lpa, LPA_OBUF_WMARK_ASSIGN) & - LPA_OBUF_WMARK_ASSIGN_BMSK); -} - -static void lpa_enable_llb_wmark(struct lpa_drv *lpa, u32 wmark_ctrl, - u32 wmark_id, u32 cpu_id) -{ - u32 val; - - wmark_id = (wmark_id > 3) ? 0 : wmark_id; - val = LPA_REG_READL(lpa, LPA_OBUF_WMARK_n_LLB_ADDR(wmark_id)); - val &= ~LPA_OBUF_LLB_WMARK_CTRL_BMSK; - val &= ~LPA_OBUF_LLB_WMARK_MAP_BMSK; - val |= (wmark_ctrl << LPA_OBUF_LLB_WMARK_CTRL_SHFT) & - LPA_OBUF_LLB_WMARK_CTRL_BMSK; - val |= (cpu_id << LPA_OBUF_LLB_WMARK_MAP_SHFT) & - LPA_OBUF_LLB_WMARK_MAP_BMSK; - LPA_REG_WRITEL(lpa, val, LPA_OBUF_WMARK_n_LLB_ADDR(wmark_id)); -} - -static void lpa_enable_sb_wmark(struct lpa_drv *lpa, u32 wmark_ctrl, - u32 cpu_id) -{ - u32 val; - - val = LPA_REG_READL(lpa, LPA_OBUF_WMARK_SB); - val &= ~LPA_OBUF_SB_WMARK_CTRL_BMSK; - val &= ~LPA_OBUF_SB_WMARK_MAP_BMSK; - val |= (wmark_ctrl << LPA_OBUF_SB_WMARK_CTRL_SHFT) & - LPA_OBUF_SB_WMARK_CTRL_BMSK; - val |= (cpu_id << LPA_OBUF_SB_WMARK_MAP_SHFT) & - LPA_OBUF_SB_WMARK_MAP_BMSK; - LPA_REG_WRITEL(lpa, val, LPA_OBUF_WMARK_SB); -} -static void lpa_enable_hlb_wmark(struct lpa_drv *lpa, u32 wmark_ctrl, - u32 cpu_id) -{ - u32 val; - - val = LPA_REG_READL(lpa, LPA_OBUF_WMARK_HLB); - val &= ~LPA_OBUF_HLB_WMARK_CTRL_BMSK; - val &= ~LPA_OBUF_HLB_WMARK_MAP_BMSK; - val |= (wmark_ctrl << LPA_OBUF_HLB_WMARK_CTRL_SHFT) & - LPA_OBUF_HLB_WMARK_CTRL_BMSK; - val |= (cpu_id << LPA_OBUF_HLB_WMARK_MAP_SHFT) & - LPA_OBUF_HLB_WMARK_MAP_BMSK; - LPA_REG_WRITEL(lpa, val, LPA_OBUF_WMARK_HLB); -} - -static void lpa_enable_utc(struct lpa_drv *lpa, bool enable, u32 cpu_id) -{ - u32 val; - - val = (cpu_id << LPA_OBUF_UTC_CONFIG_MAP_SHFT) & - LPA_OBUF_UTC_CONFIG_MAP_BMSK; - enable = (enable ? 1 : 0); - val = (enable << LPA_OBUF_UTC_CONFIG_EN_SHFT) & - LPA_OBUF_UTC_CONFIG_EN_BMSK; - LPA_REG_WRITEL(lpa, val, LPA_OBUF_UTC_CONFIG); -} - -static void lpa_enable_mixing(struct lpa_drv *lpa, bool enable) -{ - u32 val; - - val = LPA_REG_READL(lpa, LPA_OBUF_CONTROL); - val = (enable ? val | LPA_OBUF_CONTROL_LLB_EN_BMSK : - val & ~LPA_OBUF_CONTROL_LLB_EN_BMSK); - LPA_REG_WRITEL(lpa, val, LPA_OBUF_CONTROL); -} - -static void lpa_enable_mixer_saturation(struct lpa_drv *lpa, u32 buf_id, - bool enable) -{ - u32 val; - - val = LPA_REG_READL(lpa, LPA_OBUF_CONTROL); - - switch (buf_id) { - case LPA_BUF_ID_LLB: - val = enable ? (val | LPA_OBUF_CONTROL_LLB_SAT_EN_BMSK) : - (val & ~LPA_OBUF_CONTROL_LLB_SAT_EN_BMSK); - break; - - case LPA_BUF_ID_SB: - val = enable ? (val | LPA_OBUF_CONTROL_SB_SAT_EN_BMSK) : - (val & ~LPA_OBUF_CONTROL_SB_SAT_EN_BMSK); - break; - } - - LPA_REG_WRITEL(lpa, val, LPA_OBUF_CONTROL); -} - -static void lpa_enable_obuf(struct lpa_drv *lpa, u32 buf_id, bool enable) -{ - u32 val; - - val = LPA_REG_READL(lpa, LPA_OBUF_CONTROL); - - switch (buf_id) { - case LPA_BUF_ID_HLB: - val = enable ? (val | LPA_OBUF_CONTROL_HLB_EN_BMSK) : - (val & ~LPA_OBUF_CONTROL_HLB_EN_BMSK); - break; - - case LPA_BUF_ID_LLB: - val = enable ? (val | LPA_OBUF_CONTROL_LLB_EN_BMSK) : - (val & ~LPA_OBUF_CONTROL_LLB_EN_BMSK); - break; - - case LPA_BUF_ID_SB: - val = enable ? (val | LPA_OBUF_CONTROL_SB_EN_BMSK) : - (val & ~LPA_OBUF_CONTROL_SB_EN_BMSK); - break; - } - LPA_REG_WRITEL(lpa, val, LPA_OBUF_CONTROL); -} - -struct lpa_drv *lpa_get(void) -{ - struct lpa_mem_bank_select mem_bank; - struct lpa_drv *ret_lpa = &the_lpa_state.lpa_drv; - - mutex_lock(&the_lpa_state.lpa_lock); - if (the_lpa_state.assigned) { - MM_ERR("LPA HW accupied\n"); - ret_lpa = ERR_PTR(-EBUSY); - goto error; - } - /* perform initialization */ - lpa_reset(ret_lpa); - /* Config adec param */ - /* Initialize LLB/SB min/max address */ - lpa_switch_sb(ret_lpa); - /* Config HLB minx/max address */ - lpa_config_hlb_addr(ret_lpa); - - /* Power up all memory bank for now */ - mem_bank.b0 = 1; - mem_bank.b1 = 1; - mem_bank.b2 = 1; - mem_bank.b3 = 1; - mem_bank.b4 = 1; - mem_bank.b5 = 1; - mem_bank.b6 = 1; - mem_bank.b7 = 1; - mem_bank.b8 = 1; - mem_bank.b9 = 1; - mem_bank.b10 = 1; - mem_bank.llb = 1; - lpa_powerup_mem_bank(ret_lpa, &mem_bank); - - while - (lpa_req_wmark_id(ret_lpa) != LPA_OBUF_WMARK_ASSIGN_DONE); - - lpa_enable_llb_wmark(ret_lpa, LPA_WMARK_CTL_DISABLED, 0, - ret_lpa->dsp_proc_id); - lpa_enable_llb_wmark(ret_lpa, LPA_WMARK_CTL_DISABLED, 1, - ret_lpa->dsp_proc_id); - lpa_enable_llb_wmark(ret_lpa, LPA_WMARK_CTL_DISABLED, 2, - ret_lpa->app_proc_id); - lpa_enable_llb_wmark(ret_lpa, LPA_WMARK_CTL_DISABLED, 3, - ret_lpa->app_proc_id); - lpa_enable_hlb_wmark(ret_lpa, LPA_WMARK_CTL_DISABLED, - ret_lpa->dsp_proc_id); - lpa_enable_sb_wmark(ret_lpa, LPA_WMARK_CTL_DISABLED, - ret_lpa->dsp_proc_id); - lpa_enable_utc(ret_lpa, 0, LPA_OBUF_UTC_CONFIG_NO_INTR); - - lpa_enable_mixing(ret_lpa, 1); - lpa_enable_mixer_saturation(ret_lpa, LPA_BUF_ID_LLB, 1); - - lpa_enable_obuf(ret_lpa, LPA_BUF_ID_HLB, 0); - lpa_enable_obuf(ret_lpa, LPA_BUF_ID_LLB, 1); - if (ret_lpa->status & LPA_STATUS_SBUF_EN) { - lpa_enable_mixer_saturation(ret_lpa, LPA_BUF_ID_SB, 1); - lpa_enable_obuf(ret_lpa, LPA_BUF_ID_SB, 1); - } - - lpa_enable_interrupt(ret_lpa, ret_lpa->dsp_proc_id); - mb(); - the_lpa_state.assigned++; -error: - mutex_unlock(&the_lpa_state.lpa_lock); - return ret_lpa; -} -EXPORT_SYMBOL(lpa_get); - -void lpa_put(struct lpa_drv *lpa) -{ - - mutex_lock(&the_lpa_state.lpa_lock); - if (!lpa || &the_lpa_state.lpa_drv != lpa) { - MM_ERR("invalid arg\n"); - goto error; - } - /* Deinitialize */ - the_lpa_state.assigned--; -error: - mutex_unlock(&the_lpa_state.lpa_lock); -} -EXPORT_SYMBOL(lpa_put); - -int lpa_cmd_codec_config(struct lpa_drv *lpa, - struct lpa_codec_config *config_ptr) -{ - u32 sample_rate; - u32 num_channels; - u32 width; - u32 val = 0; - - if (!lpa || !config_ptr) { - MM_ERR("invalid parameters\n"); - return -EINVAL; - } - - switch (config_ptr->num_channels) { - case 8: - num_channels = LPA_NUM_CHAN_7P1; - break; - case 6: - num_channels = LPA_NUM_CHAN_5P1; - break; - case 4: - num_channels = LPA_NUM_CHAN_4_CHANNEL; - break; - case 2: - num_channels = LPA_NUM_CHAN_STEREO; - break; - case 1: - num_channels = LPA_NUM_CHAN_MONO; - break; - default: - MM_ERR("unsupported number of channel\n"); - goto error; - } - val |= (num_channels << LPA_OBUF_CODEC_NUM_CHAN_SHFT) & - LPA_OBUF_CODEC_NUM_CHAN_BMSK; - - switch (config_ptr->sample_rate) { - case 96000: - sample_rate = LPA_SAMPLE_RATE_96KHZ; - break; - case 64000: - sample_rate = LPA_SAMPLE_RATE_64KHZ; - break; - case 48000: - sample_rate = LPA_SAMPLE_RATE_48KHZ; - break; - case 44100: - sample_rate = LPA_SAMPLE_RATE_44P1KHZ; - break; - case 32000: - sample_rate = LPA_SAMPLE_RATE_32KHZ; - break; - case 22050: - sample_rate = LPA_SAMPLE_RATE_22P05KHZ; - break; - case 16000: - sample_rate = LPA_SAMPLE_RATE_16KHZ; - break; - case 11025: - sample_rate = LPA_SAMPLE_RATE_11P025KHZ; - break; - case 8000: - sample_rate = LPA_SAMPLE_RATE_8KHZ; - break; - default: - MM_ERR("unsupported sample rate \n"); - goto error; - } - val |= (sample_rate << LPA_OBUF_CODEC_SAMP_SHFT) & - LPA_OBUF_CODEC_SAMP_BMSK; - switch (config_ptr->sample_width) { - case 32: - width = LPA_BITS_PER_CHAN_32BITS; - break; - case 24: - width = LPA_BITS_PER_CHAN_24BITS; - break; - case 16: - width = LPA_BITS_PER_CHAN_16BITS; - break; - default: - MM_ERR("unsupported sample width \n"); - goto error; - } - val |= (width << LPA_OBUF_CODEC_BITS_PER_CHAN_SHFT) & - LPA_OBUF_CODEC_BITS_PER_CHAN_BMSK; - - val |= LPA_OBUF_CODEC_LOAD_BMSK; - val |= (config_ptr->output_interface << LPA_OBUF_CODEC_INTF_SHFT) & - LPA_OBUF_CODEC_INTF_BMSK; - - LPA_REG_WRITEL(lpa, val, LPA_OBUF_CODEC); - mb(); - - return 0; -error: - return -EINVAL; -} -EXPORT_SYMBOL(lpa_cmd_codec_config); - -static int lpa_check_llb_clear(struct lpa_drv *lpa) -{ - u32 val; - val = LPA_REG_READL(lpa, LPA_OBUF_STATUS); - - return !(val & LPA_OBUF_STATUS_LLB_CLR_BMSK); -} - -static void lpa_clear_llb(struct lpa_drv *lpa) -{ - u32 val; - - val = LPA_REG_READL(lpa, LPA_OBUF_CONTROL); - LPA_REG_WRITEL(lpa, (val | LPA_OBUF_CONTROL_LLB_CLR_CMD_BMSK), - LPA_OBUF_CONTROL); - lpa_enable_obuf(lpa, LPA_BUF_ID_LLB, 0); - - while (!lpa_check_llb_clear(lpa)) - udelay(100); - LPA_REG_WRITEL(lpa, val, LPA_OBUF_CONTROL); -} - -int lpa_cmd_enable_codec(struct lpa_drv *lpa, bool enable) -{ - u32 val; - struct lpa_mem_bank_select mem_bank; - - MM_DBG(" %s\n", (enable ? "enable" : "disable")); - - if (!lpa) - return -EINVAL; - - val = LPA_REG_READL(lpa, LPA_OBUF_CODEC); - - if (enable) { - if (val & LPA_OBUF_CODEC_CODEC_INTF_EN_BMSK) - return -EBUSY; - /* Power up all memory bank for now */ - mem_bank.b0 = 1; - mem_bank.b1 = 1; - mem_bank.b2 = 1; - mem_bank.b3 = 1; - mem_bank.b4 = 1; - mem_bank.b5 = 1; - mem_bank.b6 = 1; - mem_bank.b7 = 1; - mem_bank.b8 = 1; - mem_bank.b9 = 1; - mem_bank.b10 = 1; - mem_bank.llb = 1; - lpa_powerup_mem_bank(lpa, &mem_bank); - - /*clear LLB*/ - lpa_clear_llb(lpa); - - lpa_enable_codec(lpa, 1); - MM_DBG("LPA codec is enabled\n"); - } else { - if (val & LPA_OBUF_CODEC_CODEC_INTF_EN_BMSK) { - lpa_enable_codec(lpa, 0); - MM_DBG("LPA codec is disabled\n"); - } else - MM_ERR("LPA codec is already disable\n"); - } - mb(); - return 0; -} -EXPORT_SYMBOL(lpa_cmd_enable_codec); - -static int lpa_probe(struct platform_device *pdev) -{ - int rc = 0; - struct resource *mem_src; - struct msm_lpa_platform_data *pdata; - - MM_INFO("lpa probe\n"); - - if (!pdev || !pdev->dev.platform_data) { - MM_ERR("no plaform data\n"); - rc = -ENODEV; - goto error; - } - - mem_src = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpa"); - if (!mem_src) { - MM_ERR("LPA base address undefined\n"); - rc = -ENODEV; - goto error; - } - - pdata = pdev->dev.platform_data; - the_lpa_state.lpa_drv.baseaddr = ioremap(mem_src->start, - (mem_src->end - mem_src->start) + 1); - if (!the_lpa_state.lpa_drv.baseaddr) { - rc = -ENOMEM; - goto error; - } - - the_lpa_state.lpa_drv.obuf_hlb_size = pdata->obuf_hlb_size; - the_lpa_state.lpa_drv.dsp_proc_id = pdata->dsp_proc_id; - the_lpa_state.lpa_drv.app_proc_id = pdata->app_proc_id; - the_lpa_state.lpa_drv.nosb_config = pdata->nosb_config; - the_lpa_state.lpa_drv.sb_config = pdata->sb_config; - /* default to enable summing buffer */ - the_lpa_state.lpa_drv.status = LPA_STATUS_SBUF_EN; - -error: - return rc; - -} - -static int lpa_remove(struct platform_device *pdev) -{ - iounmap(the_lpa_state.lpa_drv.baseaddr); - return 0; -} - -static struct platform_driver lpa_driver = { - .probe = lpa_probe, - .remove = lpa_remove, - .driver = { - .name = "lpa", - .owner = THIS_MODULE, - }, -}; - -static int __init lpa_init(void) -{ - the_lpa_state.assigned = 0; - mutex_init(&the_lpa_state.lpa_lock); - return platform_driver_register(&lpa_driver); -} - -static void __exit lpa_exit(void) -{ - platform_driver_unregister(&lpa_driver); -} - -module_init(lpa_init); -module_exit(lpa_exit); - -MODULE_DESCRIPTION("MSM LPA driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5v2/mi2s.c b/arch/arm/mach-msm/qdsp5v2/mi2s.c deleted file mode 100644 index b649ec14416507661c4c01f08345db9d5b14fb57..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/mi2s.c +++ /dev/null @@ -1,885 +0,0 @@ -/* Copyright (c) 2009,2011 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include - -#include -#include - -#define DEBUG -#ifdef DEBUG -#define dprintk(format, arg...) \ -printk(KERN_DEBUG format, ## arg) -#else -#define dprintk(format, arg...) do {} while (0) -#endif - -/*---------------------------------------------------------------------------- - * Preprocessor Definitions and Constants - * -------------------------------------------------------------------------*/ - -/* Device Types */ -#define HDMI 0 -#define CODEC_RX 1 -#define CODEC_TX 2 - -/* Static offset for now. If different target have different - * offset, update to platform data model - */ -#define MI2S_RESET_OFFSET 0x0 -#define MI2S_MODE_OFFSET 0x4 -#define MI2S_TX_MODE_OFFSET 0x8 -#define MI2S_RX_MODE_OFFSET 0xc - -#define MI2S_SD_N_EN_MASK 0xF0 -#define MI2S_TX_RX_N_MASK 0x0F - -#define MI2S_RESET__MI2S_RESET__RESET 0x1 -#define MI2S_RESET__MI2S_RESET__ACTIVE 0x0 -#define MI2S_MODE__MI2S_MASTER__MASTER 0x1 -#define MI2S_MODE__MI2S_MASTER__SLAVE 0x0 -#define MI2S_MODE__MI2S_TX_RX_WORD_TYPE__16_BIT 0x1 -#define MI2S_MODE__MI2S_TX_RX_WORD_TYPE__24_BIT 0x2 -#define MI2S_MODE__MI2S_TX_RX_WORD_TYPE__32_BIT 0x3 -#define MI2S_TX_MODE__MI2S_TX_CODEC_16_MONO_MODE__RAW 0x0 -#define MI2S_TX_MODE__MI2S_TX_CODEC_16_MONO_MODE__PACKED 0x1 -#define MI2S_TX_MODE__MI2S_TX_STEREO_MODE__MONO_SAMPLE 0x0 -#define MI2S_TX_MODE__MI2S_TX_STEREO_MODE__STEREO_SAMPLE 0x1 -#define MI2S_TX_MODE__MI2S_TX_CH_TYPE__2_CHANNEL 0x0 -#define MI2S_TX_MODE__MI2S_TX_CH_TYPE__4_CHANNEL 0x1 -#define MI2S_TX_MODE__MI2S_TX_CH_TYPE__6_CHANNEL 0x2 -#define MI2S_TX_MODE__MI2S_TX_CH_TYPE__8_CHANNEL 0x3 -#define MI2S_TX_MODE__MI2S_TX_DMA_ACK_SYNCH_EN__SYNC_ENABLE 0x1 -#define MI2S_RX_MODE__MI2S_RX_CODEC_16_MONO_MODE__RAW 0x0 -#define MI2S_RX_MODE__MI2S_RX_CODEC_16_MONO_MODE__PACKED 0x1 -#define MI2S_RX_MODE__MI2S_RX_STEREO_MODE__MONO_SAMPLE 0x0 -#define MI2S_RX_MODE__MI2S_RX_STEREO_MODE__STEREO_SAMPLE 0x1 -#define MI2S_RX_MODE__MI2S_RX_CH_TYPE__2_CH 0x0 -#define MI2S_RX_MODE__MI2S_RX_DMA_ACK_SYNCH_EN__SYNC_ENABLE 0x1 - -#define HWIO_AUDIO1_MI2S_MODE_MI2S_MASTER_BMSK 0x1000 -#define HWIO_AUDIO1_MI2S_MODE_MI2S_MASTER_SHFT 0xC -#define HWIO_AUDIO1_MI2S_MODE_MI2S_TX_RX_WORD_TYPE_BMSK 0x300 -#define HWIO_AUDIO1_MI2S_MODE_MI2S_TX_RX_WORD_TYPE_SHFT 0x8 -#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_BMSK 0x4 -#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_SHFT 0x2 -#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_P_MONO_BMSK 0x2 -#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_P_MONO_SHFT 0x1 -#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_CH_TYPE_BMSK 0x18 -#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_CH_TYPE_SHFT 0x3 -#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_4_0_CH_MAP_BMSK 0x80 -#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_4_0_CH_MAP_SHFT 0x7 -#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_2_0_CH_MAP_BMSK 0x60 -#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_2_0_CH_MAP_SHFT 0x5 -#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_DMA_ACK_SYNCH_EN_BMSK 0x1 -#define HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_I2S_LINE_BMSK 0x60 -#define HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_I2S_LINE_SHFT 0x5 -#define HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_STEREO_MODE_BMSK 0x4 -#define HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_STEREO_MODE_SHFT 0x2 -#define HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CODEC_P_MONO_BMSK 0x2 -#define HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CODEC_P_MONO_SHFT 0x1 -#define HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CH_TYPE_BMSK 0x18 -#define HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CH_TYPE_SHFT 0x3 -#define HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_DMA_ACK_SYNCH_EN_BMSK 0x1 - -/* Max number of channels */ -#define MAX_NUM_CHANNELS_OUT 8 -#define MAX_NUM_CHANNELS_IN 2 - -/* Num of SD Lines */ -#define MAX_SD_LINES 4 - -#define MI2S_SD_0_EN_MAP 0x10 -#define MI2S_SD_1_EN_MAP 0x20 -#define MI2S_SD_2_EN_MAP 0x40 -#define MI2S_SD_3_EN_MAP 0x80 -#define MI2S_SD_0_TX_MAP 0x01 -#define MI2S_SD_1_TX_MAP 0x02 -#define MI2S_SD_2_TX_MAP 0x04 -#define MI2S_SD_3_TX_MAP 0x08 - -struct mi2s_state { - void __iomem *mi2s_hdmi_base; - void __iomem *mi2s_rx_base; - void __iomem *mi2s_tx_base; - struct mutex mutex_lock; - -}; - -static struct mi2s_state the_mi2s_state; - -static void __iomem *get_base_addr(struct mi2s_state *mi2s, uint8_t dev_id) -{ - switch (dev_id) { - case HDMI: - return mi2s->mi2s_hdmi_base; - case CODEC_RX: - return mi2s->mi2s_rx_base; - case CODEC_TX: - return mi2s->mi2s_tx_base; - default: - break; - } - return ERR_PTR(-ENODEV); -} - -static void mi2s_reset(struct mi2s_state *mi2s, uint8_t dev_id) -{ - void __iomem *baddr = get_base_addr(mi2s, dev_id); - if (!IS_ERR(baddr)) - writel(MI2S_RESET__MI2S_RESET__RESET, - baddr + MI2S_RESET_OFFSET); -} - -static void mi2s_release(struct mi2s_state *mi2s, uint8_t dev_id) -{ - void __iomem *baddr = get_base_addr(mi2s, dev_id); - if (!IS_ERR(baddr)) - writel(MI2S_RESET__MI2S_RESET__ACTIVE, - baddr + MI2S_RESET_OFFSET); -} - -static void mi2s_master(struct mi2s_state *mi2s, uint8_t dev_id, bool master) -{ - void __iomem *baddr = get_base_addr(mi2s, dev_id); - uint32_t val; - if (!IS_ERR(baddr)) { - val = readl(baddr + MI2S_MODE_OFFSET); - if (master) { - writel( - ((val & ~HWIO_AUDIO1_MI2S_MODE_MI2S_MASTER_BMSK) | - (MI2S_MODE__MI2S_MASTER__MASTER << - HWIO_AUDIO1_MI2S_MODE_MI2S_MASTER_SHFT)), - baddr + MI2S_MODE_OFFSET); - } else { - writel( - ((val & ~HWIO_AUDIO1_MI2S_MODE_MI2S_MASTER_BMSK) | - (MI2S_MODE__MI2S_MASTER__SLAVE << - HWIO_AUDIO1_MI2S_MODE_MI2S_MASTER_SHFT)), - baddr + MI2S_MODE_OFFSET); - } - } -} - -static void mi2s_set_word_type(struct mi2s_state *mi2s, uint8_t dev_id, - uint8_t size) -{ - void __iomem *baddr = get_base_addr(mi2s, dev_id); - uint32_t val; - if (!IS_ERR(baddr)) { - val = readl(baddr + MI2S_MODE_OFFSET); - switch (size) { - case WT_16_BIT: - writel( - ((val & - ~HWIO_AUDIO1_MI2S_MODE_MI2S_TX_RX_WORD_TYPE_BMSK) | - (MI2S_MODE__MI2S_TX_RX_WORD_TYPE__16_BIT << - HWIO_AUDIO1_MI2S_MODE_MI2S_TX_RX_WORD_TYPE_SHFT)), - baddr + MI2S_MODE_OFFSET); - break; - case WT_24_BIT: - writel( - ((val & - ~HWIO_AUDIO1_MI2S_MODE_MI2S_TX_RX_WORD_TYPE_BMSK) | - (MI2S_MODE__MI2S_TX_RX_WORD_TYPE__24_BIT << - HWIO_AUDIO1_MI2S_MODE_MI2S_TX_RX_WORD_TYPE_SHFT)), - baddr + MI2S_MODE_OFFSET); - break; - case WT_32_BIT: - writel( - ((val & - ~HWIO_AUDIO1_MI2S_MODE_MI2S_TX_RX_WORD_TYPE_BMSK) | - (MI2S_MODE__MI2S_TX_RX_WORD_TYPE__32_BIT << - HWIO_AUDIO1_MI2S_MODE_MI2S_TX_RX_WORD_TYPE_SHFT)), - baddr + MI2S_MODE_OFFSET); - break; - default: - break; - } - } -} - -static void mi2s_set_sd(struct mi2s_state *mi2s, uint8_t dev_id, uint8_t sd_map) -{ - void __iomem *baddr = get_base_addr(mi2s, dev_id); - uint32_t val; - if (!IS_ERR(baddr)) { - val = readl(baddr + MI2S_MODE_OFFSET) & - ~(MI2S_SD_N_EN_MASK | MI2S_TX_RX_N_MASK); - writel(val | sd_map, baddr + MI2S_MODE_OFFSET); - } -} - -static void mi2s_set_output_num_channels(struct mi2s_state *mi2s, - uint8_t dev_id, uint8_t channels) -{ - void __iomem *baddr = get_base_addr(mi2s, dev_id); - uint32_t val; - if (!IS_ERR(baddr)) { - val = readl(baddr + MI2S_TX_MODE_OFFSET); - if (channels == MI2S_CHAN_MONO_RAW) { - val = (val & - ~(HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_BMSK | - HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_P_MONO_BMSK)) | - ((MI2S_TX_MODE__MI2S_TX_STEREO_MODE__MONO_SAMPLE << - HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_SHFT) | - (MI2S_TX_MODE__MI2S_TX_CODEC_16_MONO_MODE__RAW << - HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_P_MONO_SHFT)); - } else if (channels == MI2S_CHAN_MONO_PACKED) { - val = (val & - ~(HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_BMSK | - HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_P_MONO_BMSK)) | - ((MI2S_TX_MODE__MI2S_TX_STEREO_MODE__MONO_SAMPLE << - HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_SHFT) | - (MI2S_TX_MODE__MI2S_TX_CODEC_16_MONO_MODE__PACKED << - HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_P_MONO_SHFT)); - } else if (channels == MI2S_CHAN_STEREO) { - val = (val & - ~(HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_BMSK | - HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_CH_TYPE_BMSK)) | - ((MI2S_TX_MODE__MI2S_TX_STEREO_MODE__STEREO_SAMPLE << - HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_SHFT) | - (MI2S_TX_MODE__MI2S_TX_CH_TYPE__2_CHANNEL << - HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_CH_TYPE_SHFT)); - } else if (channels == MI2S_CHAN_4CHANNELS) { - val = (val & - ~(HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_BMSK | - HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_CH_TYPE_BMSK)) | - ((MI2S_TX_MODE__MI2S_TX_STEREO_MODE__STEREO_SAMPLE << - HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_SHFT) | - (MI2S_TX_MODE__MI2S_TX_CH_TYPE__4_CHANNEL << - HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_CH_TYPE_SHFT)); - } else if (channels == MI2S_CHAN_6CHANNELS) { - val = (val & - ~(HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_BMSK | - HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_CH_TYPE_BMSK)) | - ((MI2S_TX_MODE__MI2S_TX_STEREO_MODE__STEREO_SAMPLE << - HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_SHFT) | - (MI2S_TX_MODE__MI2S_TX_CH_TYPE__6_CHANNEL << - HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_CH_TYPE_SHFT)); - } else if (channels == MI2S_CHAN_8CHANNELS) { - val = (val & - ~(HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_BMSK | - HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_CH_TYPE_BMSK)) | - ((MI2S_TX_MODE__MI2S_TX_STEREO_MODE__STEREO_SAMPLE << - HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_SHFT) | - (MI2S_TX_MODE__MI2S_TX_CH_TYPE__8_CHANNEL << - HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_CH_TYPE_SHFT)); - } - writel(val, baddr + MI2S_TX_MODE_OFFSET); - } -} - -static void mi2s_set_output_4ch_map(struct mi2s_state *mi2s, uint8_t dev_id, - bool high_low) -{ - void __iomem *baddr = get_base_addr(mi2s, dev_id); - uint32_t val; - if (!IS_ERR(baddr)) { - val = readl(baddr + MI2S_TX_MODE_OFFSET); - val = (val & ~HWIO_AUDIO1_MI2S_TX_MODE_MI2S_4_0_CH_MAP_BMSK) | - (high_low << - HWIO_AUDIO1_MI2S_TX_MODE_MI2S_4_0_CH_MAP_SHFT); - writel(val, baddr + MI2S_TX_MODE_OFFSET); - } -} - -static void mi2s_set_output_2ch_map(struct mi2s_state *mi2s, uint8_t dev_id, - uint8_t sd_line) -{ - void __iomem *baddr = get_base_addr(mi2s, dev_id); - uint32_t val; - - if (!IS_ERR(baddr)) { - val = readl(baddr + MI2S_TX_MODE_OFFSET); - if (sd_line < 4) { - val = (val & - ~HWIO_AUDIO1_MI2S_TX_MODE_MI2S_2_0_CH_MAP_BMSK) | - (sd_line << - HWIO_AUDIO1_MI2S_TX_MODE_MI2S_2_0_CH_MAP_SHFT); - writel(val, baddr + MI2S_TX_MODE_OFFSET); - } - } -} - -static void mi2s_set_output_clk_synch(struct mi2s_state *mi2s, uint8_t dev_id) -{ - void __iomem *baddr = get_base_addr(mi2s, dev_id); - uint32_t val; - - if (!IS_ERR(baddr)) { - val = readl(baddr + MI2S_TX_MODE_OFFSET); - writel(((val & - ~HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_DMA_ACK_SYNCH_EN_BMSK) | - MI2S_TX_MODE__MI2S_TX_DMA_ACK_SYNCH_EN__SYNC_ENABLE), - baddr + MI2S_TX_MODE_OFFSET); - } -} - -static void mi2s_set_input_sd_line(struct mi2s_state *mi2s, uint8_t dev_id, - uint8_t sd_line) -{ - void __iomem *baddr = get_base_addr(mi2s, dev_id); - uint32_t val; - - if (!IS_ERR(baddr)) { - val = readl(baddr + MI2S_RX_MODE_OFFSET); - if (sd_line < 4) { - val = (val & - ~HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_I2S_LINE_BMSK) | - (sd_line << - HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_I2S_LINE_SHFT); - writel(val, baddr + MI2S_RX_MODE_OFFSET); - } - } -} - -static void mi2s_set_input_num_channels(struct mi2s_state *mi2s, uint8_t dev_id, - uint8_t channels) -{ - void __iomem *baddr = get_base_addr(mi2s, dev_id); - uint32_t val; - - if (!IS_ERR(baddr)) { - val = readl(baddr + MI2S_RX_MODE_OFFSET); - if (channels == MI2S_CHAN_MONO_RAW) { - val = (val & - ~(HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_STEREO_MODE_BMSK | - HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CODEC_P_MONO_BMSK)) | - ((MI2S_RX_MODE__MI2S_RX_STEREO_MODE__MONO_SAMPLE << - HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_STEREO_MODE_SHFT) | - (MI2S_RX_MODE__MI2S_RX_CODEC_16_MONO_MODE__RAW << - HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CODEC_P_MONO_SHFT)); - } else if (channels == MI2S_CHAN_MONO_PACKED) { - val = (val & - ~(HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_STEREO_MODE_BMSK | - HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CODEC_P_MONO_BMSK)) | - ((MI2S_RX_MODE__MI2S_RX_STEREO_MODE__MONO_SAMPLE << - HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_STEREO_MODE_SHFT) | - (MI2S_RX_MODE__MI2S_RX_CODEC_16_MONO_MODE__PACKED << - HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CODEC_P_MONO_SHFT)); - } else if (channels == MI2S_CHAN_STEREO) { - - if (dev_id == HDMI) - val = (val & - ~(HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_STEREO_MODE_BMSK | - HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CH_TYPE_BMSK)) | - ((MI2S_RX_MODE__MI2S_RX_STEREO_MODE__STEREO_SAMPLE << - HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_STEREO_MODE_SHFT) | - (MI2S_RX_MODE__MI2S_RX_CH_TYPE__2_CH << - HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CH_TYPE_SHFT)); - - else - val = (val & - ~(HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_STEREO_MODE_BMSK | - HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CH_TYPE_BMSK)) | - ((MI2S_RX_MODE__MI2S_RX_STEREO_MODE__STEREO_SAMPLE << - HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_STEREO_MODE_SHFT) | - (MI2S_RX_MODE__MI2S_RX_CODEC_16_MONO_MODE__PACKED << - HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CODEC_P_MONO_SHFT) | - (MI2S_RX_MODE__MI2S_RX_CH_TYPE__2_CH << - HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CH_TYPE_SHFT)); - - - } - writel(val, baddr + MI2S_RX_MODE_OFFSET); - } -} - -static void mi2s_set_input_clk_synch(struct mi2s_state *mi2s, uint8_t dev_id) -{ - void __iomem *baddr = get_base_addr(mi2s, dev_id); - uint32_t val; - - if (!IS_ERR(baddr)) { - val = readl(baddr + MI2S_RX_MODE_OFFSET); - writel( - ((val & - ~HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_DMA_ACK_SYNCH_EN_BMSK) | - MI2S_RX_MODE__MI2S_RX_DMA_ACK_SYNCH_EN__SYNC_ENABLE), - baddr + MI2S_RX_MODE_OFFSET); - } -} - - -static u8 num_of_bits_set(u8 sd_line_mask) -{ - u8 num_bits_set = 0; - - while (sd_line_mask) { - - if (sd_line_mask & 1) - num_bits_set++; - sd_line_mask = sd_line_mask >> 1; - } - return num_bits_set; -} - - -bool mi2s_set_hdmi_output_path(uint8_t channels, uint8_t size, - uint8_t sd_line_mask) -{ - bool ret_val = MI2S_TRUE; - struct mi2s_state *mi2s = &the_mi2s_state; - u8 sd_line, num_of_sd_lines = 0; - void __iomem *baddr; - uint32_t val; - - pr_debug("%s: channels = %u size = %u sd_line_mask = 0x%x\n", __func__, - channels, size, sd_line_mask); - - if ((channels == 0) || (channels > MAX_NUM_CHANNELS_OUT) || - ((channels != 1) && (channels % 2 != 0))) { - - pr_err("%s: invalid number of channels. channels = %u\n", - __func__, channels); - return MI2S_FALSE; - } - - sd_line_mask &= MI2S_SD_LINE_MASK; - - if (!sd_line_mask) { - pr_err("%s: Did not set any data lines to use " - " sd_line_mask =0x%x\n", __func__, sd_line_mask); - return MI2S_FALSE; - } - - mutex_lock(&mi2s->mutex_lock); - /* Put device in reset */ - mi2s_reset(mi2s, HDMI); - - mi2s_master(mi2s, HDMI, 1); - - /* Set word type */ - if (size <= WT_MAX) - mi2s_set_word_type(mi2s, HDMI, size); - else - ret_val = MI2S_FALSE; - - /* Enable clock crossing synchronization of RD DMA ACK */ - mi2s_set_output_clk_synch(mi2s, HDMI); - - mi2s_set_output_num_channels(mi2s, HDMI, channels); - - num_of_sd_lines = num_of_bits_set(sd_line_mask); - /*Second argument to find_first_bit should be maximum number of - bit*/ - - sd_line = find_first_bit((unsigned long *)&sd_line_mask, - sizeof(sd_line_mask) * 8); - pr_debug("sd_line = %d\n", sd_line); - - if (channels == 1) { - - if (num_of_sd_lines != 1) { - pr_err("%s: for one channel only one SD lines is" - " needed. num_of_sd_lines = %u\n", - __func__, num_of_sd_lines); - - ret_val = MI2S_FALSE; - goto error; - } - - if (sd_line != 0) { - pr_err("%s: for one channel tx, need to use SD_0 " - "sd_line = %u\n", __func__, sd_line); - - ret_val = MI2S_FALSE; - goto error; - } - - /* Enable SD line 0 for Tx (only option for - * mono audio) - */ - mi2s_set_sd(mi2s, HDMI, MI2S_SD_0_EN_MAP | MI2S_SD_0_TX_MAP); - - } else if (channels == 2) { - - if (num_of_sd_lines != 1) { - pr_err("%s: for two channel only one SD lines is" - " needed. num_of_sd_lines = %u\n", - __func__, num_of_sd_lines); - ret_val = MI2S_FALSE; - goto error; - } - - /* Enable single SD line for Tx */ - mi2s_set_sd(mi2s, HDMI, (MI2S_SD_0_EN_MAP << sd_line) | - (MI2S_SD_0_TX_MAP << sd_line)); - - /* Set 2-channel mapping */ - mi2s_set_output_2ch_map(mi2s, HDMI, sd_line); - - } else if (channels == 4) { - - if (num_of_sd_lines != 2) { - pr_err("%s: for 4 channels two SD lines are" - " needed. num_of_sd_lines = %u\\n", - __func__, num_of_sd_lines); - ret_val = MI2S_FALSE; - goto error; - } - - if ((sd_line_mask && MI2S_SD_0) && - (sd_line_mask && MI2S_SD_1)) { - - mi2s_set_sd(mi2s, HDMI, (MI2S_SD_0_EN_MAP | - MI2S_SD_1_EN_MAP) | (MI2S_SD_0_TX_MAP | - MI2S_SD_1_TX_MAP)); - mi2s_set_output_4ch_map(mi2s, HDMI, MI2S_FALSE); - - } else if ((sd_line_mask && MI2S_SD_2) && - (sd_line_mask && MI2S_SD_3)) { - - mi2s_set_sd(mi2s, HDMI, (MI2S_SD_2_EN_MAP | - MI2S_SD_3_EN_MAP) | (MI2S_SD_2_TX_MAP | - MI2S_SD_3_TX_MAP)); - - mi2s_set_output_4ch_map(mi2s, HDMI, MI2S_TRUE); - } else { - - pr_err("%s: for 4 channels invalid SD lines usage" - " sd_line_mask = 0x%x\n", - __func__, sd_line_mask); - ret_val = MI2S_FALSE; - goto error; - } - } else if (channels == 6) { - - if (num_of_sd_lines != 3) { - pr_err("%s: for 6 channels three SD lines are" - " needed. num_of_sd_lines = %u\n", - __func__, num_of_sd_lines); - ret_val = MI2S_FALSE; - goto error; - } - - if ((sd_line_mask && MI2S_SD_0) && - (sd_line_mask && MI2S_SD_1) && - (sd_line_mask && MI2S_SD_2)) { - - mi2s_set_sd(mi2s, HDMI, (MI2S_SD_0_EN_MAP | - MI2S_SD_1_EN_MAP | MI2S_SD_2_EN_MAP) | - (MI2S_SD_0_TX_MAP | MI2S_SD_1_TX_MAP | - MI2S_SD_2_TX_MAP)); - - } else if ((sd_line_mask && MI2S_SD_1) && - (sd_line_mask && MI2S_SD_2) && - (sd_line_mask && MI2S_SD_3)) { - - mi2s_set_sd(mi2s, HDMI, (MI2S_SD_1_EN_MAP | - MI2S_SD_2_EN_MAP | MI2S_SD_3_EN_MAP) | - (MI2S_SD_1_TX_MAP | MI2S_SD_2_TX_MAP | - MI2S_SD_3_TX_MAP)); - - } else { - - pr_err("%s: for 6 channels invalid SD lines usage" - " sd_line_mask = 0x%x\n", - __func__, sd_line_mask); - ret_val = MI2S_FALSE; - goto error; - } - } else if (channels == 8) { - - if (num_of_sd_lines != 4) { - pr_err("%s: for 8 channels four SD lines are" - " needed. num_of_sd_lines = %u\n", - __func__, num_of_sd_lines); - ret_val = MI2S_FALSE; - goto error; - } - - mi2s_set_sd(mi2s, HDMI, (MI2S_SD_0_EN_MAP | - MI2S_SD_1_EN_MAP | MI2S_SD_2_EN_MAP | - MI2S_SD_3_EN_MAP) | (MI2S_SD_0_TX_MAP | - MI2S_SD_1_TX_MAP | MI2S_SD_2_TX_MAP | - MI2S_SD_3_TX_MAP)); - } else { - pr_err("%s: invalid number channels = %u\n", - __func__, channels); - ret_val = MI2S_FALSE; - goto error; - } - - baddr = get_base_addr(mi2s, HDMI); - - val = readl(baddr + MI2S_MODE_OFFSET); - pr_debug("%s(): MI2S_MODE = 0x%x\n", __func__, val); - - val = readl(baddr + MI2S_TX_MODE_OFFSET); - pr_debug("%s(): MI2S_TX_MODE = 0x%x\n", __func__, val); - - -error: - /* Release device from reset */ - mi2s_release(mi2s, HDMI); - - mutex_unlock(&mi2s->mutex_lock); - mb(); - return ret_val; -} -EXPORT_SYMBOL(mi2s_set_hdmi_output_path); - -bool mi2s_set_hdmi_input_path(uint8_t channels, uint8_t size, - uint8_t sd_line_mask) -{ - bool ret_val = MI2S_TRUE; - struct mi2s_state *mi2s = &the_mi2s_state; - u8 sd_line, num_of_sd_lines = 0; - void __iomem *baddr; - uint32_t val; - - pr_debug("%s: channels = %u size = %u sd_line_mask = 0x%x\n", __func__, - channels, size, sd_line_mask); - - if ((channels != 1) && (channels != MAX_NUM_CHANNELS_IN)) { - - pr_err("%s: invalid number of channels. channels = %u\n", - __func__, channels); - return MI2S_FALSE; - } - - if (size > WT_MAX) { - - pr_err("%s: mi2s word size can not be greater than 32 bits\n", - __func__); - return MI2S_FALSE; - } - - sd_line_mask &= MI2S_SD_LINE_MASK; - - if (!sd_line_mask) { - pr_err("%s: Did not set any data lines to use " - " sd_line_mask =0x%x\n", __func__, sd_line_mask); - return MI2S_FALSE; - } - - num_of_sd_lines = num_of_bits_set(sd_line_mask); - - if (num_of_sd_lines != 1) { - pr_err("%s: for two channel input only one SD lines is" - " needed. num_of_sd_lines = %u sd_line_mask = 0x%x\n", - __func__, num_of_sd_lines, sd_line_mask); - return MI2S_FALSE; - } - - /*Second argument to find_first_bit should be maximum number of - bits interested*/ - sd_line = find_first_bit((unsigned long *)&sd_line_mask, - sizeof(sd_line_mask) * 8); - pr_debug("sd_line = %d\n", sd_line); - - /* Ensure sd_line parameter is valid (0-max) */ - if (sd_line > MAX_SD_LINES) { - pr_err("%s: Line number can not be greater than = %u\n", - __func__, MAX_SD_LINES); - return MI2S_FALSE; - } - - mutex_lock(&mi2s->mutex_lock); - /* Put device in reset */ - mi2s_reset(mi2s, HDMI); - - mi2s_master(mi2s, HDMI, 1); - - /* Set word type */ - mi2s_set_word_type(mi2s, HDMI, size); - - /* Enable clock crossing synchronization of WR DMA ACK */ - mi2s_set_input_clk_synch(mi2s, HDMI); - - /* Ensure channels parameter is valid (non-zero, less than max, - * and even or mono) - */ - mi2s_set_input_num_channels(mi2s, HDMI, channels); - - mi2s_set_input_sd_line(mi2s, HDMI, sd_line); - - mi2s_set_sd(mi2s, HDMI, (MI2S_SD_0_EN_MAP << sd_line)); - - baddr = get_base_addr(mi2s, HDMI); - - val = readl(baddr + MI2S_MODE_OFFSET); - pr_debug("%s(): MI2S_MODE = 0x%x\n", __func__, val); - - val = readl(baddr + MI2S_RX_MODE_OFFSET); - pr_debug("%s(): MI2S_RX_MODE = 0x%x\n", __func__, val); - - /* Release device from reset */ - mi2s_release(mi2s, HDMI); - - mutex_unlock(&mi2s->mutex_lock); - mb(); - return ret_val; -} -EXPORT_SYMBOL(mi2s_set_hdmi_input_path); - -bool mi2s_set_codec_output_path(uint8_t channels, uint8_t size) -{ - bool ret_val = MI2S_TRUE; - struct mi2s_state *mi2s = &the_mi2s_state; - - mutex_lock(&mi2s->mutex_lock); - /* Put device in reset */ - mi2s_reset(mi2s, CODEC_TX); - - mi2s_master(mi2s, CODEC_TX, 1); - - /* Enable clock crossing synchronization of RD DMA ACK */ - mi2s_set_output_clk_synch(mi2s, CODEC_TX); - - /* Set word type */ - if (size <= WT_MAX) - mi2s_set_word_type(mi2s, CODEC_TX, size); - else - ret_val = MI2S_FALSE; - - mi2s_set_output_num_channels(mi2s, CODEC_TX, channels); - - /* Enable SD line */ - mi2s_set_sd(mi2s, CODEC_TX, MI2S_SD_0_EN_MAP | MI2S_SD_0_TX_MAP); - - /* Release device from reset */ - mi2s_release(mi2s, CODEC_TX); - - mutex_unlock(&mi2s->mutex_lock); - mb(); - return ret_val; -} -EXPORT_SYMBOL(mi2s_set_codec_output_path); - -bool mi2s_set_codec_input_path(uint8_t channels, uint8_t size) -{ - bool ret_val = MI2S_TRUE; - struct mi2s_state *mi2s = &the_mi2s_state; - - mutex_lock(&the_mi2s_state.mutex_lock); - /* Put device in reset */ - mi2s_reset(mi2s, CODEC_RX); - - mi2s_master(mi2s, CODEC_RX, 1); - - /* Enable clock crossing synchronization of WR DMA ACK */ - mi2s_set_input_clk_synch(mi2s, CODEC_RX); - - /* Set word type */ - if (size <= WT_MAX) - mi2s_set_word_type(mi2s, CODEC_RX, size); - else - ret_val = MI2S_FALSE; - - mi2s_set_input_num_channels(mi2s, CODEC_RX, channels); - - /* Enable SD line */ - mi2s_set_sd(mi2s, CODEC_RX, MI2S_SD_0_EN_MAP); - - /* Release device from reset */ - mi2s_release(mi2s, CODEC_RX); - - mutex_unlock(&mi2s->mutex_lock); - mb(); - return ret_val; -} -EXPORT_SYMBOL(mi2s_set_codec_input_path); - - -static int mi2s_probe(struct platform_device *pdev) -{ - int rc = 0; - struct resource *mem_src; - - mem_src = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi"); - if (!mem_src) { - rc = -ENODEV; - goto error_hdmi; - } - the_mi2s_state.mi2s_hdmi_base = ioremap(mem_src->start, - (mem_src->end - mem_src->start) + 1); - if (!the_mi2s_state.mi2s_hdmi_base) { - rc = -ENOMEM; - goto error_hdmi; - } - mem_src = platform_get_resource_byname(pdev, - IORESOURCE_MEM, "codec_rx"); - if (!mem_src) { - rc = -ENODEV; - goto error_codec_rx; - } - the_mi2s_state.mi2s_rx_base = ioremap(mem_src->start, - (mem_src->end - mem_src->start) + 1); - if (!the_mi2s_state.mi2s_rx_base) { - rc = -ENOMEM; - goto error_codec_rx; - } - mem_src = platform_get_resource_byname(pdev, - IORESOURCE_MEM, "codec_tx"); - if (!mem_src) { - rc = -ENODEV; - goto error_codec_tx; - } - the_mi2s_state.mi2s_tx_base = ioremap(mem_src->start, - (mem_src->end - mem_src->start) + 1); - if (!the_mi2s_state.mi2s_tx_base) { - rc = -ENOMEM; - goto error_codec_tx; - } - mutex_init(&the_mi2s_state.mutex_lock); - - return rc; - -error_codec_tx: - iounmap(the_mi2s_state.mi2s_rx_base); -error_codec_rx: - iounmap(the_mi2s_state.mi2s_hdmi_base); -error_hdmi: - return rc; - -} - -static int mi2s_remove(struct platform_device *pdev) -{ - iounmap(the_mi2s_state.mi2s_tx_base); - iounmap(the_mi2s_state.mi2s_rx_base); - iounmap(the_mi2s_state.mi2s_hdmi_base); - return 0; -} - -static struct platform_driver mi2s_driver = { - .probe = mi2s_probe, - .remove = mi2s_remove, - .driver = { - .name = "mi2s", - .owner = THIS_MODULE, - }, -}; - -static int __init mi2s_init(void) -{ - return platform_driver_register(&mi2s_driver); -} - -static void __exit mi2s_exit(void) -{ - platform_driver_unregister(&mi2s_driver); -} - -module_init(mi2s_init); -module_exit(mi2s_exit); - -MODULE_DESCRIPTION("MSM MI2S driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5v2/mp3_funcs.c b/arch/arm/mach-msm/qdsp5v2/mp3_funcs.c deleted file mode 100644 index f857e5c302ff14711fec0d1fe7bbf421de536bff..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/mp3_funcs.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2010, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -long mp3_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - MM_DBG("mp3_ioctl() cmd = %d\b", cmd); - - return -EINVAL; -} - -void audpp_cmd_cfg_mp3_params(struct audio *audio) -{ - struct audpp_cmd_cfg_adec_params_mp3 cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_MP3_LEN; - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = audio->out_sample_rate; - - audpp_send_queue2(&cmd, sizeof(cmd)); -} diff --git a/arch/arm/mach-msm/qdsp5v2/pcm_funcs.c b/arch/arm/mach-msm/qdsp5v2/pcm_funcs.c deleted file mode 100644 index 866b71d74eb4b8b506fc0926218bd24434ab7a84..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/pcm_funcs.c +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (c) 2010, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -long pcm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - MM_DBG("pcm_ioctl() cmd = %d\n", cmd); - - return -EINVAL; -} - -void audpp_cmd_cfg_pcm_params(struct audio *audio) -{ - struct audpp_cmd_cfg_adec_params_wav cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; - cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_WAV_LEN >> 1; - cmd.common.dec_id = audio->dec_id; - cmd.common.input_sampling_frequency = audio->out_sample_rate; - cmd.stereo_cfg = audio->out_channel_mode; - cmd.pcm_width = audio->out_bits; - cmd.sign = 0; - audpp_send_queue2(&cmd, sizeof(cmd)); -} diff --git a/arch/arm/mach-msm/qdsp5v2/snddev_data_marimba.c b/arch/arm/mach-msm/qdsp5v2/snddev_data_marimba.c deleted file mode 100644 index b11cdb0e1398975ee68fab8c60a5013c38122f86..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/snddev_data_marimba.c +++ /dev/null @@ -1,1537 +0,0 @@ -/* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* define the value for BT_SCO */ -#define BT_SCO_PCM_CTL_VAL (PCM_CTL__RPCM_WIDTH__LINEAR_V |\ - PCM_CTL__TPCM_WIDTH__LINEAR_V) -#define BT_SCO_DATA_FORMAT_PADDING (DATA_FORMAT_PADDING_INFO__RPCM_FORMAT_V |\ - DATA_FORMAT_PADDING_INFO__TPCM_FORMAT_V) -#define BT_SCO_AUX_CODEC_INTF AUX_CODEC_INTF_CTL__PCMINTF_DATA_EN_V - -#ifdef CONFIG_DEBUG_FS -static struct dentry *debugfs_hsed_config; -static void snddev_hsed_config_modify_setting(int type); -static void snddev_hsed_config_restore_setting(void); -#endif - -static struct adie_codec_action_unit iearpiece_48KHz_osr256_actions[] = - HANDSET_RX_48000_OSR_256; - -static struct adie_codec_hwsetting_entry iearpiece_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = iearpiece_48KHz_osr256_actions, - .action_sz = ARRAY_SIZE(iearpiece_48KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile iearpiece_profile = { - .path_type = ADIE_CODEC_RX, - .settings = iearpiece_settings, - .setting_sz = ARRAY_SIZE(iearpiece_settings), -}; - -static struct snddev_icodec_data snddev_iearpiece_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE), - .name = "handset_rx", - .copp_id = 0, - .acdb_id = ACDB_ID_HANDSET_SPKR, - .profile = &iearpiece_profile, - .channel_mode = 1, - .pmctl_id = NULL, - .pmctl_id_sz = 0, - .default_sample_rate = 48000, - .pamp_on = NULL, - .pamp_off = NULL, - .property = SIDE_TONE_MASK, - .max_voice_rx_vol[VOC_NB_INDEX] = -200, - .min_voice_rx_vol[VOC_NB_INDEX] = -1700, - .max_voice_rx_vol[VOC_WB_INDEX] = -200, - .min_voice_rx_vol[VOC_WB_INDEX] = -1700 -}; - -static struct platform_device msm_iearpiece_device = { - .name = "snddev_icodec", - .id = 0, - .dev = { .platform_data = &snddev_iearpiece_data }, -}; - -static struct adie_codec_action_unit imic_8KHz_osr256_actions[] = - HANDSET_TX_8000_OSR_256; - -static struct adie_codec_action_unit imic_16KHz_osr256_actions[] = - HANDSET_TX_16000_OSR_256; - -static struct adie_codec_action_unit imic_48KHz_osr256_actions[] = - HANDSET_TX_48000_OSR_256; - -static struct adie_codec_hwsetting_entry imic_settings[] = { - { - .freq_plan = 8000, - .osr = 256, - .actions = imic_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(imic_8KHz_osr256_actions), - }, - { - .freq_plan = 16000, - .osr = 256, - .actions = imic_16KHz_osr256_actions, - .action_sz = ARRAY_SIZE(imic_16KHz_osr256_actions), - }, - { - .freq_plan = 48000, - .osr = 256, - .actions = imic_48KHz_osr256_actions, - .action_sz = ARRAY_SIZE(imic_48KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile imic_profile = { - .path_type = ADIE_CODEC_TX, - .settings = imic_settings, - .setting_sz = ARRAY_SIZE(imic_settings), -}; - -static enum hsed_controller imic_pmctl_id[] = {PM_HSED_CONTROLLER_0}; - -static struct snddev_icodec_data snddev_imic_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "handset_tx", - .copp_id = 0, - .acdb_id = ACDB_ID_HANDSET_MIC, - .profile = &imic_profile, - .channel_mode = 1, - .pmctl_id = imic_pmctl_id, - .pmctl_id_sz = ARRAY_SIZE(imic_pmctl_id), - .default_sample_rate = 48000, - .pamp_on = NULL, - .pamp_off = NULL, -}; - -static struct platform_device msm_imic_device = { - .name = "snddev_icodec", - .id = 1, - .dev = { .platform_data = &snddev_imic_data }, -}; - -static struct adie_codec_action_unit ihs_stereo_rx_48KHz_osr256_actions[] = - HEADSET_STEREO_RX_LEGACY_48000_OSR_256; - -static struct adie_codec_hwsetting_entry ihs_stereo_rx_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = ihs_stereo_rx_48KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ihs_stereo_rx_48KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile ihs_stereo_rx_profile = { - .path_type = ADIE_CODEC_RX, - .settings = ihs_stereo_rx_settings, - .setting_sz = ARRAY_SIZE(ihs_stereo_rx_settings), -}; - -static struct snddev_icodec_data snddev_ihs_stereo_rx_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE), - .name = "headset_stereo_rx", - .copp_id = 0, - .acdb_id = ACDB_ID_HEADSET_SPKR_STEREO, - .profile = &ihs_stereo_rx_profile, - .channel_mode = 2, - .default_sample_rate = 48000, - .pamp_on = NULL, - .pamp_off = NULL, - .property = SIDE_TONE_MASK, - .max_voice_rx_vol[VOC_NB_INDEX] = -700, - .min_voice_rx_vol[VOC_NB_INDEX] = -2200, - .max_voice_rx_vol[VOC_WB_INDEX] = -900, - .min_voice_rx_vol[VOC_WB_INDEX] = -2400 -}; - -static struct platform_device msm_ihs_stereo_rx_device = { - .name = "snddev_icodec", - .id = 2, - .dev = { .platform_data = &snddev_ihs_stereo_rx_data }, -}; - -static struct adie_codec_action_unit ihs_mono_rx_48KHz_osr256_actions[] = - HEADSET_RX_LEGACY_48000_OSR_256; - -static struct adie_codec_hwsetting_entry ihs_mono_rx_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = ihs_mono_rx_48KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ihs_mono_rx_48KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile ihs_mono_rx_profile = { - .path_type = ADIE_CODEC_RX, - .settings = ihs_mono_rx_settings, - .setting_sz = ARRAY_SIZE(ihs_mono_rx_settings), -}; - -static struct snddev_icodec_data snddev_ihs_mono_rx_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE), - .name = "headset_mono_rx", - .copp_id = 0, - .acdb_id = ACDB_ID_HEADSET_SPKR_MONO, - .profile = &ihs_mono_rx_profile, - .channel_mode = 1, - .default_sample_rate = 48000, - .pamp_on = NULL, - .pamp_off = NULL, - .property = SIDE_TONE_MASK, - .max_voice_rx_vol[VOC_NB_INDEX] = -700, - .min_voice_rx_vol[VOC_NB_INDEX] = -2200, - .max_voice_rx_vol[VOC_WB_INDEX] = -900, - .min_voice_rx_vol[VOC_WB_INDEX] = -2400, - -}; - -static struct platform_device msm_ihs_mono_rx_device = { - .name = "snddev_icodec", - .id = 3, - .dev = { .platform_data = &snddev_ihs_mono_rx_data }, -}; - -static struct adie_codec_action_unit ihs_ffa_stereo_rx_48KHz_osr256_actions[] = - HEADSET_STEREO_RX_CAPLESS_48000_OSR_256; - -static struct adie_codec_hwsetting_entry ihs_ffa_stereo_rx_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = ihs_ffa_stereo_rx_48KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ihs_ffa_stereo_rx_48KHz_osr256_actions), - } -}; - -#ifdef CONFIG_DEBUG_FS -static struct adie_codec_action_unit - ihs_ffa_stereo_rx_class_d_legacy_48KHz_osr256_actions[] = - HEADSET_STEREO_RX_CLASS_D_LEGACY_48000_OSR_256; - -static struct adie_codec_hwsetting_entry - ihs_ffa_stereo_rx_class_d_legacy_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = - ihs_ffa_stereo_rx_class_d_legacy_48KHz_osr256_actions, - .action_sz = ARRAY_SIZE - (ihs_ffa_stereo_rx_class_d_legacy_48KHz_osr256_actions), - } -}; - -static struct adie_codec_action_unit - ihs_ffa_stereo_rx_class_ab_legacy_48KHz_osr256_actions[] = - HEADSET_STEREO_RX_LEGACY_48000_OSR_256; - -static struct adie_codec_hwsetting_entry - ihs_ffa_stereo_rx_class_ab_legacy_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = - ihs_ffa_stereo_rx_class_ab_legacy_48KHz_osr256_actions, - .action_sz = ARRAY_SIZE - (ihs_ffa_stereo_rx_class_ab_legacy_48KHz_osr256_actions), - } -}; -#endif - -static struct adie_codec_dev_profile ihs_ffa_stereo_rx_profile = { - .path_type = ADIE_CODEC_RX, - .settings = ihs_ffa_stereo_rx_settings, - .setting_sz = ARRAY_SIZE(ihs_ffa_stereo_rx_settings), -}; - -static struct snddev_icodec_data snddev_ihs_ffa_stereo_rx_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE), - .name = "headset_stereo_rx", - .copp_id = 0, - .acdb_id = ACDB_ID_HEADSET_SPKR_STEREO, - .profile = &ihs_ffa_stereo_rx_profile, - .channel_mode = 2, - .default_sample_rate = 48000, - .voltage_on = msm_snddev_hsed_voltage_on, - .voltage_off = msm_snddev_hsed_voltage_off, - .max_voice_rx_vol[VOC_NB_INDEX] = -700, - .min_voice_rx_vol[VOC_NB_INDEX] = -2200, - .max_voice_rx_vol[VOC_WB_INDEX] = -900, - .min_voice_rx_vol[VOC_WB_INDEX] = -2400, -}; - -static struct platform_device msm_ihs_ffa_stereo_rx_device = { - .name = "snddev_icodec", - .id = 4, - .dev = { .platform_data = &snddev_ihs_ffa_stereo_rx_data }, -}; - -static struct adie_codec_action_unit ihs_ffa_mono_rx_48KHz_osr256_actions[] = - HEADSET_RX_CAPLESS_48000_OSR_256; - -static struct adie_codec_hwsetting_entry ihs_ffa_mono_rx_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = ihs_ffa_mono_rx_48KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ihs_ffa_mono_rx_48KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile ihs_ffa_mono_rx_profile = { - .path_type = ADIE_CODEC_RX, - .settings = ihs_ffa_mono_rx_settings, - .setting_sz = ARRAY_SIZE(ihs_ffa_mono_rx_settings), -}; - -static struct snddev_icodec_data snddev_ihs_ffa_mono_rx_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE), - .name = "headset_mono_rx", - .copp_id = 0, - .acdb_id = ACDB_ID_HEADSET_SPKR_MONO, - .profile = &ihs_ffa_mono_rx_profile, - .channel_mode = 1, - .default_sample_rate = 48000, - .pamp_on = msm_snddev_hsed_voltage_on, - .pamp_off = msm_snddev_hsed_voltage_off, - .max_voice_rx_vol[VOC_NB_INDEX] = -700, - .min_voice_rx_vol[VOC_NB_INDEX] = -2200, - .max_voice_rx_vol[VOC_WB_INDEX] = -900, - .min_voice_rx_vol[VOC_WB_INDEX] = -2400, -}; - -static struct platform_device msm_ihs_ffa_mono_rx_device = { - .name = "snddev_icodec", - .id = 5, - .dev = { .platform_data = &snddev_ihs_ffa_mono_rx_data }, -}; - -static struct adie_codec_action_unit ihs_mono_tx_8KHz_osr256_actions[] = - HEADSET_MONO_TX_8000_OSR_256; - -static struct adie_codec_action_unit ihs_mono_tx_16KHz_osr256_actions[] = - HEADSET_MONO_TX_16000_OSR_256; - -static struct adie_codec_action_unit ihs_mono_tx_48KHz_osr256_actions[] = - HEADSET_MONO_TX_48000_OSR_256; - -static struct adie_codec_hwsetting_entry ihs_mono_tx_settings[] = { - { - .freq_plan = 8000, - .osr = 256, - .actions = ihs_mono_tx_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ihs_mono_tx_8KHz_osr256_actions), - }, - { - .freq_plan = 16000, - .osr = 256, - .actions = ihs_mono_tx_16KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ihs_mono_tx_16KHz_osr256_actions), - }, - { - .freq_plan = 48000, - .osr = 256, - .actions = ihs_mono_tx_48KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ihs_mono_tx_48KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile ihs_mono_tx_profile = { - .path_type = ADIE_CODEC_TX, - .settings = ihs_mono_tx_settings, - .setting_sz = ARRAY_SIZE(ihs_mono_tx_settings), -}; - -static struct snddev_icodec_data snddev_ihs_mono_tx_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "headset_mono_tx", - .copp_id = 0, - .acdb_id = ACDB_ID_HEADSET_MIC, - .profile = &ihs_mono_tx_profile, - .channel_mode = 1, - .pmctl_id = NULL, - .pmctl_id_sz = 0, - .default_sample_rate = 48000, - .pamp_on = msm_snddev_tx_route_config, - .pamp_off = msm_snddev_tx_route_deconfig, -}; - -static struct platform_device msm_ihs_mono_tx_device = { - .name = "snddev_icodec", - .id = 6, - .dev = { .platform_data = &snddev_ihs_mono_tx_data }, -}; - -static struct adie_codec_action_unit ifmradio_handset_osr64_actions[] = - FM_HANDSET_OSR_64; - -static struct adie_codec_hwsetting_entry ifmradio_handset_settings[] = { - { - .freq_plan = 8000, - .osr = 256, - .actions = ifmradio_handset_osr64_actions, - .action_sz = ARRAY_SIZE(ifmradio_handset_osr64_actions), - } -}; - -static struct adie_codec_dev_profile ifmradio_handset_profile = { - .path_type = ADIE_CODEC_RX, - .settings = ifmradio_handset_settings, - .setting_sz = ARRAY_SIZE(ifmradio_handset_settings), -}; - -static struct snddev_icodec_data snddev_ifmradio_handset_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_FM), - .name = "fmradio_handset_rx", - .copp_id = 0, - .acdb_id = ACDB_ID_LP_FM_SPKR_PHONE_STEREO_RX, - .profile = &ifmradio_handset_profile, - .channel_mode = 1, - .default_sample_rate = 8000, - .pamp_on = NULL, - .pamp_off = NULL, - .dev_vol_type = SNDDEV_DEV_VOL_DIGITAL, -}; - -static struct platform_device msm_ifmradio_handset_device = { - .name = "snddev_icodec", - .id = 7, - .dev = { .platform_data = &snddev_ifmradio_handset_data }, -}; - - -static struct adie_codec_action_unit ispeaker_rx_48KHz_osr256_actions[] = - SPEAKER_STEREO_RX_48000_OSR_256; - -static struct adie_codec_hwsetting_entry ispeaker_rx_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = ispeaker_rx_48KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ispeaker_rx_48KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile ispeaker_rx_profile = { - .path_type = ADIE_CODEC_RX, - .settings = ispeaker_rx_settings, - .setting_sz = ARRAY_SIZE(ispeaker_rx_settings), -}; - -static struct snddev_icodec_data snddev_ispeaker_rx_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE), - .name = "speaker_stereo_rx", - .copp_id = 0, - .acdb_id = ACDB_ID_SPKR_PHONE_STEREO, - .profile = &ispeaker_rx_profile, - .channel_mode = 2, - .pmctl_id = NULL, - .pmctl_id_sz = 0, - .default_sample_rate = 48000, - .pamp_on = &msm_snddev_poweramp_on, - .pamp_off = &msm_snddev_poweramp_off, - .max_voice_rx_vol[VOC_NB_INDEX] = 1000, - .min_voice_rx_vol[VOC_NB_INDEX] = -500, - .max_voice_rx_vol[VOC_WB_INDEX] = 1000, - .min_voice_rx_vol[VOC_WB_INDEX] = -500, -}; - -static struct platform_device msm_ispeaker_rx_device = { - .name = "snddev_icodec", - .id = 8, - .dev = { .platform_data = &snddev_ispeaker_rx_data }, - -}; - -static struct adie_codec_action_unit ifmradio_speaker_osr64_actions[] = - FM_SPEAKER_OSR_64; - -static struct adie_codec_hwsetting_entry ifmradio_speaker_settings[] = { - { - .freq_plan = 8000, - .osr = 256, - .actions = ifmradio_speaker_osr64_actions, - .action_sz = ARRAY_SIZE(ifmradio_speaker_osr64_actions), - } -}; - -static struct adie_codec_dev_profile ifmradio_speaker_profile = { - .path_type = ADIE_CODEC_RX, - .settings = ifmradio_speaker_settings, - .setting_sz = ARRAY_SIZE(ifmradio_speaker_settings), -}; - -static struct snddev_icodec_data snddev_ifmradio_speaker_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_FM), - .name = "fmradio_speaker_rx", - .copp_id = 0, - .acdb_id = ACDB_ID_LP_FM_SPKR_PHONE_STEREO_RX, - .profile = &ifmradio_speaker_profile, - .channel_mode = 1, - .default_sample_rate = 8000, - .pamp_on = &msm_snddev_poweramp_on, - .pamp_off = &msm_snddev_poweramp_off, - .dev_vol_type = SNDDEV_DEV_VOL_DIGITAL, -}; - -static struct platform_device msm_ifmradio_speaker_device = { - .name = "snddev_icodec", - .id = 9, - .dev = { .platform_data = &snddev_ifmradio_speaker_data }, -}; - -static struct adie_codec_action_unit ifmradio_headset_osr64_actions[] = - FM_HEADSET_STEREO_CLASS_D_LEGACY_OSR_64; - -static struct adie_codec_hwsetting_entry ifmradio_headset_settings[] = { - { - .freq_plan = 8000, - .osr = 256, - .actions = ifmradio_headset_osr64_actions, - .action_sz = ARRAY_SIZE(ifmradio_headset_osr64_actions), - } -}; - -static struct adie_codec_dev_profile ifmradio_headset_profile = { - .path_type = ADIE_CODEC_RX, - .settings = ifmradio_headset_settings, - .setting_sz = ARRAY_SIZE(ifmradio_headset_settings), -}; - -static struct snddev_icodec_data snddev_ifmradio_headset_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_FM), - .name = "fmradio_headset_rx", - .copp_id = 0, - .acdb_id = ACDB_ID_LP_FM_HEADSET_SPKR_STEREO_RX, - .profile = &ifmradio_headset_profile, - .channel_mode = 1, - .default_sample_rate = 8000, - .pamp_on = NULL, - .pamp_off = NULL, - .dev_vol_type = SNDDEV_DEV_VOL_DIGITAL, -}; - -static struct platform_device msm_ifmradio_headset_device = { - .name = "snddev_icodec", - .id = 10, - .dev = { .platform_data = &snddev_ifmradio_headset_data }, -}; - - -static struct adie_codec_action_unit ifmradio_ffa_headset_osr64_actions[] = - FM_HEADSET_CLASS_AB_STEREO_CAPLESS_OSR_64; - -static struct adie_codec_hwsetting_entry ifmradio_ffa_headset_settings[] = { - { - .freq_plan = 8000, - .osr = 256, - .actions = ifmradio_ffa_headset_osr64_actions, - .action_sz = ARRAY_SIZE(ifmradio_ffa_headset_osr64_actions), - } -}; - -static struct adie_codec_dev_profile ifmradio_ffa_headset_profile = { - .path_type = ADIE_CODEC_RX, - .settings = ifmradio_ffa_headset_settings, - .setting_sz = ARRAY_SIZE(ifmradio_ffa_headset_settings), -}; - -static struct snddev_icodec_data snddev_ifmradio_ffa_headset_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_FM), - .name = "fmradio_headset_rx", - .copp_id = 0, - .acdb_id = ACDB_ID_LP_FM_HEADSET_SPKR_STEREO_RX, - .profile = &ifmradio_ffa_headset_profile, - .channel_mode = 1, - .default_sample_rate = 8000, - .pamp_on = msm_snddev_hsed_voltage_on, - .pamp_off = msm_snddev_hsed_voltage_off, - .dev_vol_type = SNDDEV_DEV_VOL_DIGITAL, -}; - -static struct platform_device msm_ifmradio_ffa_headset_device = { - .name = "snddev_icodec", - .id = 11, - .dev = { .platform_data = &snddev_ifmradio_ffa_headset_data }, -}; - -static struct snddev_ecodec_data snddev_bt_sco_earpiece_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE), - .name = "bt_sco_rx", - .copp_id = 1, - .acdb_id = ACDB_ID_BT_SCO_SPKR, - .channel_mode = 1, - .conf_pcm_ctl_val = BT_SCO_PCM_CTL_VAL, - .conf_aux_codec_intf = BT_SCO_AUX_CODEC_INTF, - .conf_data_format_padding_val = BT_SCO_DATA_FORMAT_PADDING, - .max_voice_rx_vol[VOC_NB_INDEX] = 400, - .min_voice_rx_vol[VOC_NB_INDEX] = -1100, - .max_voice_rx_vol[VOC_WB_INDEX] = 400, - .min_voice_rx_vol[VOC_WB_INDEX] = -1100, -}; - -static struct snddev_ecodec_data snddev_bt_sco_mic_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "bt_sco_tx", - .copp_id = 1, - .acdb_id = ACDB_ID_BT_SCO_MIC, - .channel_mode = 1, - .conf_pcm_ctl_val = BT_SCO_PCM_CTL_VAL, - .conf_aux_codec_intf = BT_SCO_AUX_CODEC_INTF, - .conf_data_format_padding_val = BT_SCO_DATA_FORMAT_PADDING, -}; - -struct platform_device msm_bt_sco_earpiece_device = { - .name = "msm_snddev_ecodec", - .id = 0, - .dev = { .platform_data = &snddev_bt_sco_earpiece_data }, -}; - -struct platform_device msm_bt_sco_mic_device = { - .name = "msm_snddev_ecodec", - .id = 1, - .dev = { .platform_data = &snddev_bt_sco_mic_data }, -}; - -static struct adie_codec_action_unit idual_mic_endfire_8KHz_osr256_actions[] = - MIC1_LEFT_LINE_IN_RIGHT_8000_OSR_256; - -static struct adie_codec_hwsetting_entry idual_mic_endfire_settings[] = { - { - .freq_plan = 8000, - .osr = 256, - .actions = idual_mic_endfire_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(idual_mic_endfire_8KHz_osr256_actions), - }, /* 8KHz profile can be used for 16KHz */ - { - .freq_plan = 16000, - .osr = 256, - .actions = idual_mic_endfire_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(idual_mic_endfire_8KHz_osr256_actions), - }, /* 8KHz profile can be used for 48KHz */ - { - .freq_plan = 48000, - .osr = 256, - .actions = idual_mic_endfire_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(idual_mic_endfire_8KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile idual_mic_endfire_profile = { - .path_type = ADIE_CODEC_TX, - .settings = idual_mic_endfire_settings, - .setting_sz = ARRAY_SIZE(idual_mic_endfire_settings), -}; - -static enum hsed_controller idual_mic_endfire_pmctl_id[] = { - PM_HSED_CONTROLLER_0, PM_HSED_CONTROLLER_2 -}; - -static struct snddev_icodec_data snddev_idual_mic_endfire_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "handset_dual_mic_endfire_tx", - .copp_id = 0, - .acdb_id = ACDB_ID_HANDSET_MIC_ENDFIRE, - .profile = &idual_mic_endfire_profile, - .channel_mode = 2, - .default_sample_rate = 48000, - .pmctl_id = idual_mic_endfire_pmctl_id, - .pmctl_id_sz = ARRAY_SIZE(idual_mic_endfire_pmctl_id), - .pamp_on = NULL, - .pamp_off = NULL, -}; - -static struct platform_device msm_idual_mic_endfire_device = { - .name = "snddev_icodec", - .id = 12, - .dev = { .platform_data = &snddev_idual_mic_endfire_data }, -}; - - -static struct snddev_icodec_data\ - snddev_idual_mic_endfire_real_stereo_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "handset_dual_mic_endfire_tx_real_stereo", - .copp_id = 0, - .acdb_id = PSEUDO_ACDB_ID, - .profile = &idual_mic_endfire_profile, - .channel_mode = REAL_STEREO_CHANNEL_MODE, - .default_sample_rate = 48000, - .pmctl_id = idual_mic_endfire_pmctl_id, - .pmctl_id_sz = ARRAY_SIZE(idual_mic_endfire_pmctl_id), - .pamp_on = NULL, - .pamp_off = NULL, -}; - -static struct platform_device msm_real_stereo_tx_device = { - .name = "snddev_icodec", - .id = 26, - .dev = { .platform_data = - &snddev_idual_mic_endfire_real_stereo_data }, -}; - -static struct adie_codec_action_unit idual_mic_bs_8KHz_osr256_actions[] = - MIC1_LEFT_AUX_IN_RIGHT_8000_OSR_256; - -static struct adie_codec_hwsetting_entry idual_mic_broadside_settings[] = { - { - .freq_plan = 8000, - .osr = 256, - .actions = idual_mic_bs_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(idual_mic_bs_8KHz_osr256_actions), - }, /* 8KHz profile can be used for 16KHz */ - { - .freq_plan = 16000, - .osr = 256, - .actions = idual_mic_bs_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(idual_mic_bs_8KHz_osr256_actions), - }, /* 8KHz profile can be used for 16KHz */ - { - .freq_plan = 48000, - .osr = 256, - .actions = idual_mic_bs_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(idual_mic_bs_8KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile idual_mic_broadside_profile = { - .path_type = ADIE_CODEC_TX, - .settings = idual_mic_broadside_settings, - .setting_sz = ARRAY_SIZE(idual_mic_broadside_settings), -}; - -static enum hsed_controller idual_mic_broadside_pmctl_id[] = { - PM_HSED_CONTROLLER_0, PM_HSED_CONTROLLER_2 -}; - -static struct snddev_icodec_data snddev_idual_mic_broadside_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "handset_dual_mic_broadside_tx", - .copp_id = 0, - .acdb_id = ACDB_ID_HANDSET_MIC_BROADSIDE, - .profile = &idual_mic_broadside_profile, - .channel_mode = 2, - .default_sample_rate = 48000, - .pmctl_id = idual_mic_broadside_pmctl_id, - .pmctl_id_sz = ARRAY_SIZE(idual_mic_broadside_pmctl_id), - .pamp_on = NULL, - .pamp_off = NULL, -}; - -static struct platform_device msm_idual_mic_broadside_device = { - .name = "snddev_icodec", - .id = 13, - .dev = { .platform_data = &snddev_idual_mic_broadside_data }, -}; - -static struct adie_codec_action_unit ispk_dual_mic_ef_8KHz_osr256_actions[] = - SPEAKER_MIC1_LEFT_LINE_IN_RIGHT_8000_OSR_256; - -static struct adie_codec_hwsetting_entry ispk_dual_mic_ef_settings[] = { - { - .freq_plan = 8000, - .osr = 256, - .actions = ispk_dual_mic_ef_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ispk_dual_mic_ef_8KHz_osr256_actions), - }, /* 8KHz profile can be used for 16Khz */ - { - .freq_plan = 16000, - .osr = 256, - .actions = ispk_dual_mic_ef_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ispk_dual_mic_ef_8KHz_osr256_actions), - }, /* 8KHz profile can be used for 48KHz */ - { - .freq_plan = 48000, - .osr = 256, - .actions = ispk_dual_mic_ef_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ispk_dual_mic_ef_8KHz_osr256_actions), - }, -}; - -static struct adie_codec_dev_profile ispk_dual_mic_ef_profile = { - .path_type = ADIE_CODEC_TX, - .settings = ispk_dual_mic_ef_settings, - .setting_sz = ARRAY_SIZE(ispk_dual_mic_ef_settings), -}; - -static struct snddev_icodec_data snddev_spk_idual_mic_endfire_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "speaker_dual_mic_endfire_tx", - .copp_id = 0, - .acdb_id = ACDB_ID_SPKR_PHONE_MIC_ENDFIRE, - .profile = &ispk_dual_mic_ef_profile, - .channel_mode = 2, - .default_sample_rate = 48000, - .pmctl_id = idual_mic_endfire_pmctl_id, - .pmctl_id_sz = ARRAY_SIZE(idual_mic_endfire_pmctl_id), - .pamp_on = NULL, - .pamp_off = NULL, -}; - -static struct platform_device msm_spk_idual_mic_endfire_device = { - .name = "snddev_icodec", - .id = 14, - .dev = { .platform_data = &snddev_spk_idual_mic_endfire_data }, -}; - -static struct adie_codec_action_unit ispk_dual_mic_bs_8KHz_osr256_actions[] = - SPEAKER_MIC1_LEFT_AUX_IN_RIGHT_8000_OSR_256; - -static struct adie_codec_hwsetting_entry ispk_dual_mic_bs_settings[] = { - { - .freq_plan = 8000, - .osr = 256, - .actions = ispk_dual_mic_bs_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ispk_dual_mic_bs_8KHz_osr256_actions), - }, /* 8KHz profile can be used for 16Khz */ - { - .freq_plan = 16000, - .osr = 256, - .actions = ispk_dual_mic_bs_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ispk_dual_mic_bs_8KHz_osr256_actions), - }, /* 8KHz profile can be used for 48KHz */ - { - .freq_plan = 48000, - .osr = 256, - .actions = ispk_dual_mic_bs_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ispk_dual_mic_bs_8KHz_osr256_actions), - }, -}; - -static struct adie_codec_dev_profile ispk_dual_mic_bs_profile = { - .path_type = ADIE_CODEC_TX, - .settings = ispk_dual_mic_bs_settings, - .setting_sz = ARRAY_SIZE(ispk_dual_mic_bs_settings), -}; -static struct snddev_icodec_data snddev_spk_idual_mic_broadside_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "speaker_dual_mic_broadside_tx", - .copp_id = 0, - .acdb_id = ACDB_ID_SPKR_PHONE_MIC_BROADSIDE, - .profile = &ispk_dual_mic_bs_profile, - .channel_mode = 2, - .default_sample_rate = 48000, - .pmctl_id = idual_mic_broadside_pmctl_id, - .pmctl_id_sz = ARRAY_SIZE(idual_mic_broadside_pmctl_id), - .pamp_on = NULL, - .pamp_off = NULL, -}; - -static struct platform_device msm_spk_idual_mic_broadside_device = { - .name = "snddev_icodec", - .id = 15, - .dev = { .platform_data = &snddev_spk_idual_mic_broadside_data }, -}; - -static struct adie_codec_action_unit itty_hs_mono_tx_8KHz_osr256_actions[] = - TTY_HEADSET_MONO_TX_8000_OSR_256; - -static struct adie_codec_hwsetting_entry itty_hs_mono_tx_settings[] = { - /* 8KHz, 16KHz, 48KHz TTY Tx devices can shared same set of actions */ - { - .freq_plan = 8000, - .osr = 256, - .actions = itty_hs_mono_tx_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(itty_hs_mono_tx_8KHz_osr256_actions), - }, - { - .freq_plan = 16000, - .osr = 256, - .actions = itty_hs_mono_tx_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(itty_hs_mono_tx_8KHz_osr256_actions), - }, - { - .freq_plan = 48000, - .osr = 256, - .actions = itty_hs_mono_tx_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(itty_hs_mono_tx_8KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile itty_hs_mono_tx_profile = { - .path_type = ADIE_CODEC_TX, - .settings = itty_hs_mono_tx_settings, - .setting_sz = ARRAY_SIZE(itty_hs_mono_tx_settings), -}; - -static struct snddev_icodec_data snddev_itty_hs_mono_tx_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE | SNDDEV_CAP_TTY), - .name = "tty_headset_mono_tx", - .copp_id = 0, - .acdb_id = ACDB_ID_TTY_HEADSET_MIC, - .profile = &itty_hs_mono_tx_profile, - .channel_mode = 1, - .default_sample_rate = 48000, - .pmctl_id = NULL, - .pmctl_id_sz = 0, - .pamp_on = NULL, - .pamp_off = NULL, -}; - -static struct platform_device msm_itty_hs_mono_tx_device = { - .name = "snddev_icodec", - .id = 16, - .dev = { .platform_data = &snddev_itty_hs_mono_tx_data }, -}; - -static struct adie_codec_action_unit itty_hs_mono_rx_8KHz_osr256_actions[] = - TTY_HEADSET_MONO_RX_CLASS_D_8000_OSR_256; - -static struct adie_codec_action_unit itty_hs_mono_rx_16KHz_osr256_actions[] = - TTY_HEADSET_MONO_RX_CLASS_D_16000_OSR_256; - -static struct adie_codec_action_unit itty_hs_mono_rx_48KHz_osr256_actions[] = - TTY_HEADSET_MONO_RX_CLASS_D_48000_OSR_256; - -static struct adie_codec_hwsetting_entry itty_hs_mono_rx_settings[] = { - { - .freq_plan = 8000, - .osr = 256, - .actions = itty_hs_mono_rx_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(itty_hs_mono_rx_8KHz_osr256_actions), - }, - { - .freq_plan = 16000, - .osr = 256, - .actions = itty_hs_mono_rx_16KHz_osr256_actions, - .action_sz = ARRAY_SIZE(itty_hs_mono_rx_16KHz_osr256_actions), - }, - { - .freq_plan = 48000, - .osr = 256, - .actions = itty_hs_mono_rx_48KHz_osr256_actions, - .action_sz = ARRAY_SIZE(itty_hs_mono_rx_48KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile itty_hs_mono_rx_profile = { - .path_type = ADIE_CODEC_RX, - .settings = itty_hs_mono_rx_settings, - .setting_sz = ARRAY_SIZE(itty_hs_mono_rx_settings), -}; - -static struct snddev_icodec_data snddev_itty_hs_mono_rx_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE | SNDDEV_CAP_TTY), - .name = "tty_headset_mono_rx", - .copp_id = 0, - .acdb_id = ACDB_ID_TTY_HEADSET_SPKR, - .profile = &itty_hs_mono_rx_profile, - .channel_mode = 1, - .default_sample_rate = 48000, - .pamp_on = NULL, - .pamp_off = NULL, - .max_voice_rx_vol[VOC_NB_INDEX] = 0, - .min_voice_rx_vol[VOC_NB_INDEX] = 0, - .max_voice_rx_vol[VOC_WB_INDEX] = 0, - .min_voice_rx_vol[VOC_WB_INDEX] = 0, -}; - -static struct platform_device msm_itty_hs_mono_rx_device = { - .name = "snddev_icodec", - .id = 17, - .dev = { .platform_data = &snddev_itty_hs_mono_rx_data }, -}; - -static struct adie_codec_action_unit ispeaker_tx_8KHz_osr256_actions[] = - SPEAKER_TX_8000_OSR_256; - -static struct adie_codec_action_unit ispeaker_tx_48KHz_osr256_actions[] = - SPEAKER_TX_48000_OSR_256; - -static struct adie_codec_hwsetting_entry ispeaker_tx_settings[] = { - { - .freq_plan = 8000, - .osr = 256, - .actions = ispeaker_tx_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ispeaker_tx_8KHz_osr256_actions), - }, - { /* 8KHz profile is good for 16KHz */ - .freq_plan = 16000, - .osr = 256, - .actions = ispeaker_tx_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ispeaker_tx_8KHz_osr256_actions), - }, - { - .freq_plan = 48000, - .osr = 256, - .actions = ispeaker_tx_48KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ispeaker_tx_48KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile ispeaker_tx_profile = { - .path_type = ADIE_CODEC_TX, - .settings = ispeaker_tx_settings, - .setting_sz = ARRAY_SIZE(ispeaker_tx_settings), -}; - -static enum hsed_controller ispk_pmctl_id[] = {PM_HSED_CONTROLLER_0}; - -static struct snddev_icodec_data snddev_ispeaker_tx_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "speaker_mono_tx", - .copp_id = 0, - .acdb_id = ACDB_ID_SPKR_PHONE_MIC, - .profile = &ispeaker_tx_profile, - .channel_mode = 1, - .pmctl_id = ispk_pmctl_id, - .pmctl_id_sz = ARRAY_SIZE(ispk_pmctl_id), - .default_sample_rate = 48000, - .pamp_on = msm_snddev_tx_route_config, - .pamp_off = msm_snddev_tx_route_deconfig, -}; - -static struct platform_device msm_ispeaker_tx_device = { - .name = "snddev_icodec", - .id = 18, - .dev = { .platform_data = &snddev_ispeaker_tx_data }, -}; - -static struct adie_codec_action_unit iearpiece_ffa_48KHz_osr256_actions[] = - HANDSET_RX_48000_OSR_256_FFA; - -static struct adie_codec_hwsetting_entry iearpiece_ffa_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = iearpiece_ffa_48KHz_osr256_actions, - .action_sz = ARRAY_SIZE(iearpiece_ffa_48KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile iearpiece_ffa_profile = { - .path_type = ADIE_CODEC_RX, - .settings = iearpiece_ffa_settings, - .setting_sz = ARRAY_SIZE(iearpiece_ffa_settings), -}; - -static struct snddev_icodec_data snddev_iearpiece_ffa_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE), - .name = "handset_rx", - .copp_id = 0, - .acdb_id = ACDB_ID_HANDSET_SPKR, - .profile = &iearpiece_ffa_profile, - .channel_mode = 1, - .pmctl_id = NULL, - .pmctl_id_sz = 0, - .default_sample_rate = 48000, - .pamp_on = NULL, - .pamp_off = NULL, - .max_voice_rx_vol[VOC_NB_INDEX] = -700, - .min_voice_rx_vol[VOC_NB_INDEX] = -2200, - .max_voice_rx_vol[VOC_WB_INDEX] = -1400, - .min_voice_rx_vol[VOC_WB_INDEX] = -2900, -}; - -static struct platform_device msm_iearpiece_ffa_device = { - .name = "snddev_icodec", - .id = 19, - .dev = { .platform_data = &snddev_iearpiece_ffa_data }, -}; - -static struct adie_codec_action_unit imic_ffa_8KHz_osr256_actions[] = - HANDSET_TX_8000_OSR_256_FFA; - -static struct adie_codec_action_unit imic_ffa_16KHz_osr256_actions[] = - HANDSET_TX_16000_OSR_256_FFA; - -static struct adie_codec_action_unit imic_ffa_48KHz_osr256_actions[] = - HANDSET_TX_48000_OSR_256_FFA; - -static struct adie_codec_hwsetting_entry imic_ffa_settings[] = { - { - .freq_plan = 8000, - .osr = 256, - .actions = imic_ffa_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(imic_ffa_8KHz_osr256_actions), - }, - { - .freq_plan = 16000, - .osr = 256, - .actions = imic_ffa_16KHz_osr256_actions, - .action_sz = ARRAY_SIZE(imic_ffa_16KHz_osr256_actions), - }, - { - .freq_plan = 48000, - .osr = 256, - .actions = imic_ffa_48KHz_osr256_actions, - .action_sz = ARRAY_SIZE(imic_ffa_48KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile imic_ffa_profile = { - .path_type = ADIE_CODEC_TX, - .settings = imic_ffa_settings, - .setting_sz = ARRAY_SIZE(imic_ffa_settings), -}; - -static struct snddev_icodec_data snddev_imic_ffa_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "handset_tx", - .copp_id = 0, - .acdb_id = ACDB_ID_HANDSET_MIC, - .profile = &imic_ffa_profile, - .channel_mode = 1, - .pmctl_id = imic_pmctl_id, - .pmctl_id_sz = ARRAY_SIZE(imic_pmctl_id), - .default_sample_rate = 48000, - .pamp_on = NULL, - .pamp_off = NULL, -}; - -static struct platform_device msm_imic_ffa_device = { - .name = "snddev_icodec", - .id = 20, - .dev = { .platform_data = &snddev_imic_ffa_data }, -}; - - -static struct adie_codec_action_unit - ihs_stereo_speaker_stereo_rx_48KHz_osr256_actions[] = - HEADSET_STEREO_SPEAKER_STEREO_RX_CAPLESS_48000_OSR_256; - - -static struct adie_codec_hwsetting_entry - ihs_stereo_speaker_stereo_rx_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = ihs_stereo_speaker_stereo_rx_48KHz_osr256_actions, - .action_sz = - ARRAY_SIZE(ihs_stereo_speaker_stereo_rx_48KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile ihs_stereo_speaker_stereo_rx_profile = { - .path_type = ADIE_CODEC_RX, - .settings = ihs_stereo_speaker_stereo_rx_settings, - .setting_sz = ARRAY_SIZE(ihs_stereo_speaker_stereo_rx_settings), -}; - -static struct snddev_icodec_data snddev_ihs_stereo_speaker_stereo_rx_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE), - .name = "headset_stereo_speaker_stereo_rx", - .copp_id = 0, - .acdb_id = ACDB_ID_HEADSET_STEREO_PLUS_SPKR_STEREO_RX, - .profile = &ihs_stereo_speaker_stereo_rx_profile, - .channel_mode = 2, - .default_sample_rate = 48000, - .pamp_on = msm_snddev_poweramp_on, - .pamp_off = msm_snddev_poweramp_off, - .voltage_on = msm_snddev_hsed_voltage_on, - .voltage_off = msm_snddev_hsed_voltage_off, - .max_voice_rx_vol[VOC_NB_INDEX] = -500, - .min_voice_rx_vol[VOC_NB_INDEX] = -2000, - .max_voice_rx_vol[VOC_WB_INDEX] = -500, - .min_voice_rx_vol[VOC_WB_INDEX] = -2000, -}; - -static struct platform_device msm_ihs_stereo_speaker_stereo_rx_device = { - .name = "snddev_icodec", - .id = 21, - .dev = { .platform_data = &snddev_ihs_stereo_speaker_stereo_rx_data }, -}; - -static struct snddev_mi2s_data snddev_mi2s_stereo_rx_data = { - .capability = SNDDEV_CAP_RX , - .name = "hdmi_stereo_rx", - .copp_id = 3, - .acdb_id = ACDB_ID_HDMI, - .channel_mode = 2, - .sd_lines = MI2S_SD_0, - .route = msm_snddev_tx_route_config, - .deroute = msm_snddev_tx_route_deconfig, - .default_sample_rate = 48000, -}; - -static struct platform_device msm_snddev_mi2s_stereo_rx_device = { - .name = "snddev_mi2s", - .id = 0, - .dev = { .platform_data = &snddev_mi2s_stereo_rx_data }, -}; - - -static struct snddev_mi2s_data snddev_mi2s_fm_tx_data = { - .capability = SNDDEV_CAP_TX , - .name = "fmradio_stereo_tx", - .copp_id = 2, - .acdb_id = ACDB_ID_FM_TX, - .channel_mode = 2, - .sd_lines = MI2S_SD_3, - .route = NULL, - .deroute = NULL, - .default_sample_rate = 48000, -}; - -static struct platform_device msm_snddev_mi2s_fm_tx_device = { - .name = "snddev_mi2s", - .id = 1, - .dev = { .platform_data = &snddev_mi2s_fm_tx_data}, -}; - -static struct snddev_icodec_data snddev_fluid_imic_tx_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "handset_tx", - .copp_id = 0, - .acdb_id = ACDB_ID_SPKR_PHONE_MIC, - .profile = &ispeaker_tx_profile, - .channel_mode = 1, - .pmctl_id = ispk_pmctl_id, - .pmctl_id_sz = ARRAY_SIZE(ispk_pmctl_id), - .default_sample_rate = 48000, - .pamp_on = msm_snddev_tx_route_config, - .pamp_off = msm_snddev_tx_route_deconfig, -}; - -static struct platform_device msm_fluid_imic_tx_device = { - .name = "snddev_icodec", - .id = 22, - .dev = { .platform_data = &snddev_fluid_imic_tx_data }, -}; - -static struct snddev_icodec_data snddev_fluid_iearpiece_rx_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE), - .name = "handset_rx", - .copp_id = 0, - .acdb_id = ACDB_ID_SPKR_PHONE_STEREO, - .profile = &ispeaker_rx_profile, - .channel_mode = 2, - .pmctl_id = NULL, - .pmctl_id_sz = 0, - .default_sample_rate = 48000, - .pamp_on = &msm_snddev_poweramp_on, - .pamp_off = &msm_snddev_poweramp_off, - .max_voice_rx_vol[VOC_NB_INDEX] = -500, - .min_voice_rx_vol[VOC_NB_INDEX] = -1000, - .max_voice_rx_vol[VOC_WB_INDEX] = -500, - .min_voice_rx_vol[VOC_WB_INDEX] = -1000, -}; - -static struct platform_device msm_fluid_iearpeice_rx_device = { - .name = "snddev_icodec", - .id = 23, - .dev = { .platform_data = &snddev_fluid_iearpiece_rx_data }, -}; - -static struct adie_codec_action_unit fluid_idual_mic_ef_8KHz_osr256_actions[] = - MIC1_LEFT_AUX_IN_RIGHT_8000_OSR_256; - -static struct adie_codec_hwsetting_entry fluid_idual_mic_endfire_settings[] = { - { - .freq_plan = 8000, - .osr = 256, - .actions = fluid_idual_mic_ef_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(fluid_idual_mic_ef_8KHz_osr256_actions), - }, /* 8KHz profile can be used for 16KHz */ - { - .freq_plan = 16000, - .osr = 256, - .actions = fluid_idual_mic_ef_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(fluid_idual_mic_ef_8KHz_osr256_actions), - }, /* 8KHz profile can also be used for 48KHz */ - { - .freq_plan = 48000, - .osr = 256, - .actions = fluid_idual_mic_ef_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(fluid_idual_mic_ef_8KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile fluid_idual_mic_endfire_profile = { - .path_type = ADIE_CODEC_TX, - .settings = fluid_idual_mic_endfire_settings, - .setting_sz = ARRAY_SIZE(fluid_idual_mic_endfire_settings), -}; - -static enum hsed_controller fluid_idual_mic_endfire_pmctl_id[] = { - PM_HSED_CONTROLLER_0, PM_HSED_CONTROLLER_2 -}; - -static struct snddev_icodec_data snddev_fluid_idual_mic_endfire_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "handset_dual_mic_endfire_tx", - .copp_id = 0, - .acdb_id = ACDB_ID_SPKR_PHONE_MIC_ENDFIRE, - .profile = &fluid_idual_mic_endfire_profile, - .channel_mode = 2, - .default_sample_rate = 48000, - .pmctl_id = fluid_idual_mic_endfire_pmctl_id, - .pmctl_id_sz = ARRAY_SIZE(fluid_idual_mic_endfire_pmctl_id), - .pamp_on = msm_snddev_tx_route_config, - .pamp_off = msm_snddev_tx_route_deconfig, -}; - -static struct platform_device msm_fluid_idual_mic_endfire_device = { - .name = "snddev_icodec", - .id = 24, - .dev = { .platform_data = &snddev_fluid_idual_mic_endfire_data }, -}; - -static struct snddev_icodec_data snddev_fluid_spk_idual_mic_endfire_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "speaker_dual_mic_endfire_tx", - .copp_id = 0, - .acdb_id = ACDB_ID_SPKR_PHONE_MIC_ENDFIRE, - .profile = &fluid_idual_mic_endfire_profile, - .channel_mode = 2, - .default_sample_rate = 48000, - .pmctl_id = fluid_idual_mic_endfire_pmctl_id, - .pmctl_id_sz = ARRAY_SIZE(fluid_idual_mic_endfire_pmctl_id), - .pamp_on = msm_snddev_tx_route_config, - .pamp_off = msm_snddev_tx_route_deconfig, -}; - -static struct platform_device msm_fluid_spk_idual_mic_endfire_device = { - .name = "snddev_icodec", - .id = 25, - .dev = { .platform_data = &snddev_fluid_spk_idual_mic_endfire_data }, -}; - -static struct snddev_virtual_data snddev_a2dp_tx_data = { - .capability = SNDDEV_CAP_TX, - .name = "a2dp_tx", - .copp_id = 5, - .acdb_id = PSEUDO_ACDB_ID, -}; - -static struct snddev_virtual_data snddev_a2dp_rx_data = { - .capability = SNDDEV_CAP_RX, - .name = "a2dp_rx", - .copp_id = 2, - .acdb_id = PSEUDO_ACDB_ID, -}; - -static struct platform_device msm_a2dp_rx_device = { - .name = "snddev_virtual", - .id = 0, - .dev = { .platform_data = &snddev_a2dp_rx_data }, -}; - -static struct platform_device msm_a2dp_tx_device = { - .name = "snddev_virtual", - .id = 1, - .dev = { .platform_data = &snddev_a2dp_tx_data }, -}; - -static struct snddev_virtual_data snddev_uplink_rx_data = { - .capability = SNDDEV_CAP_RX, - .name = "uplink_rx", - .copp_id = 5, - .acdb_id = PSEUDO_ACDB_ID, -}; - -static struct platform_device msm_uplink_rx_device = { - .name = "snddev_virtual", - .id = 2, - .dev = { .platform_data = &snddev_uplink_rx_data }, -}; - -static struct platform_device *snd_devices_ffa[] __initdata = { - &msm_iearpiece_ffa_device, - &msm_imic_ffa_device, - &msm_ifmradio_handset_device, - &msm_ihs_ffa_stereo_rx_device, - &msm_ihs_ffa_mono_rx_device, - &msm_ihs_mono_tx_device, - &msm_bt_sco_earpiece_device, - &msm_bt_sco_mic_device, - &msm_ispeaker_rx_device, - &msm_ifmradio_speaker_device, - &msm_ifmradio_ffa_headset_device, - &msm_idual_mic_endfire_device, - &msm_idual_mic_broadside_device, - &msm_spk_idual_mic_endfire_device, - &msm_spk_idual_mic_broadside_device, - &msm_itty_hs_mono_tx_device, - &msm_itty_hs_mono_rx_device, - &msm_ispeaker_tx_device, - &msm_ihs_stereo_speaker_stereo_rx_device, - &msm_a2dp_rx_device, - &msm_a2dp_tx_device, - &msm_snddev_mi2s_stereo_rx_device, - &msm_snddev_mi2s_fm_tx_device, - &msm_uplink_rx_device, - &msm_real_stereo_tx_device, -}; - -static struct platform_device *snd_devices_surf[] __initdata = { - &msm_iearpiece_device, - &msm_imic_device, - &msm_ihs_stereo_rx_device, - &msm_ihs_mono_rx_device, - &msm_ihs_mono_tx_device, - &msm_bt_sco_earpiece_device, - &msm_bt_sco_mic_device, - &msm_ifmradio_handset_device, - &msm_ispeaker_rx_device, - &msm_ifmradio_speaker_device, - &msm_ifmradio_headset_device, - &msm_itty_hs_mono_tx_device, - &msm_itty_hs_mono_rx_device, - &msm_ispeaker_tx_device, - &msm_ihs_stereo_speaker_stereo_rx_device, - &msm_a2dp_rx_device, - &msm_a2dp_tx_device, - &msm_snddev_mi2s_stereo_rx_device, - &msm_snddev_mi2s_fm_tx_device, - &msm_uplink_rx_device, -}; - -static struct platform_device *snd_devices_fluid[] __initdata = { - &msm_ihs_stereo_rx_device, - &msm_ihs_mono_rx_device, - &msm_ihs_mono_tx_device, - &msm_ispeaker_rx_device, - &msm_ispeaker_tx_device, - &msm_fluid_imic_tx_device, - &msm_fluid_iearpeice_rx_device, - &msm_fluid_idual_mic_endfire_device, - &msm_fluid_spk_idual_mic_endfire_device, - &msm_a2dp_rx_device, - &msm_a2dp_tx_device, - &msm_snddev_mi2s_stereo_rx_device, - &msm_uplink_rx_device, - &msm_ifmradio_speaker_device, - &msm_ifmradio_headset_device, -}; - -#ifdef CONFIG_DEBUG_FS -static void snddev_hsed_config_modify_setting(int type) -{ - struct platform_device *device; - struct snddev_icodec_data *icodec_data; - - device = &msm_ihs_ffa_stereo_rx_device; - icodec_data = (struct snddev_icodec_data *)device->dev.platform_data; - - if (icodec_data) { - if (type == 1) { - icodec_data->voltage_on = NULL; - icodec_data->voltage_off = NULL; - icodec_data->profile->settings = - ihs_ffa_stereo_rx_class_d_legacy_settings; - icodec_data->profile->setting_sz = - ARRAY_SIZE(ihs_ffa_stereo_rx_class_d_legacy_settings); - } else if (type == 2) { - icodec_data->voltage_on = NULL; - icodec_data->voltage_off = NULL; - icodec_data->profile->settings = - ihs_ffa_stereo_rx_class_ab_legacy_settings; - icodec_data->profile->setting_sz = - ARRAY_SIZE(ihs_ffa_stereo_rx_class_ab_legacy_settings); - } - } -} - -static void snddev_hsed_config_restore_setting(void) -{ - struct platform_device *device; - struct snddev_icodec_data *icodec_data; - - device = &msm_ihs_ffa_stereo_rx_device; - icodec_data = (struct snddev_icodec_data *)device->dev.platform_data; - - if (icodec_data) { - icodec_data->voltage_on = msm_snddev_hsed_voltage_on; - icodec_data->voltage_off = msm_snddev_hsed_voltage_off; - icodec_data->profile->settings = ihs_ffa_stereo_rx_settings; - icodec_data->profile->setting_sz = - ARRAY_SIZE(ihs_ffa_stereo_rx_settings); - } -} - -static ssize_t snddev_hsed_config_debug_write(struct file *filp, - const char __user *ubuf, size_t cnt, loff_t *ppos) -{ - char *lb_str = filp->private_data; - char cmd; - - if (get_user(cmd, ubuf)) - return -EFAULT; - - if (!strcmp(lb_str, "msm_hsed_config")) { - switch (cmd) { - case '0': - snddev_hsed_config_restore_setting(); - break; - - case '1': - snddev_hsed_config_modify_setting(1); - break; - - case '2': - snddev_hsed_config_modify_setting(2); - break; - - default: - break; - } - } - return cnt; -} - -static int snddev_hsed_config_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static const struct file_operations snddev_hsed_config_debug_fops = { - .open = snddev_hsed_config_debug_open, - .write = snddev_hsed_config_debug_write -}; -#endif - -void __ref msm_snddev_init(void) -{ - if (machine_is_msm7x30_ffa() || machine_is_msm8x55_ffa() || - machine_is_msm8x55_svlte_ffa()) { - platform_add_devices(snd_devices_ffa, - ARRAY_SIZE(snd_devices_ffa)); -#ifdef CONFIG_DEBUG_FS - debugfs_hsed_config = debugfs_create_file("msm_hsed_config", - S_IFREG | S_IRUGO, NULL, - (void *) "msm_hsed_config", &snddev_hsed_config_debug_fops); -#endif - } else if (machine_is_msm7x30_surf() || machine_is_msm8x55_surf() || - machine_is_msm8x55_svlte_surf()) - platform_add_devices(snd_devices_surf, - ARRAY_SIZE(snd_devices_surf)); - else if (machine_is_msm7x30_fluid()) - platform_add_devices(snd_devices_fluid, - ARRAY_SIZE(snd_devices_fluid)); - else - pr_err("%s: Unknown machine type\n", __func__); -} diff --git a/arch/arm/mach-msm/qdsp5v2/snddev_data_timpani.c b/arch/arm/mach-msm/qdsp5v2/snddev_data_timpani.c deleted file mode 100644 index a4e4dad34fb823aacd1effc88f9e68450126929f..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/snddev_data_timpani.c +++ /dev/null @@ -1,1006 +0,0 @@ -/* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "timpani_profile_7x30.h" -#include - -/* define the value for BT_SCO */ -#define BT_SCO_PCM_CTL_VAL (PCM_CTL__RPCM_WIDTH__LINEAR_V |\ - PCM_CTL__TPCM_WIDTH__LINEAR_V) -#define BT_SCO_DATA_FORMAT_PADDING (DATA_FORMAT_PADDING_INFO__RPCM_FORMAT_V |\ - DATA_FORMAT_PADDING_INFO__TPCM_FORMAT_V) -#define BT_SCO_AUX_CODEC_INTF AUX_CODEC_INTF_CTL__PCMINTF_DATA_EN_V - -#ifdef CONFIG_DEBUG_FS -static struct dentry *debugfs_hsed_config; -static void snddev_hsed_config_modify_setting(int type); -static void snddev_hsed_config_restore_setting(void); -#endif - -static struct adie_codec_action_unit iearpiece_ffa_48KHz_osr256_actions[] = - EAR_PRI_MONO_8000_OSR_256; /* 8000 profile also works for 48k */ - -static struct adie_codec_hwsetting_entry iearpiece_ffa_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = iearpiece_ffa_48KHz_osr256_actions, - .action_sz = ARRAY_SIZE(iearpiece_ffa_48KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile iearpiece_ffa_profile = { - .path_type = ADIE_CODEC_RX, - .settings = iearpiece_ffa_settings, - .setting_sz = ARRAY_SIZE(iearpiece_ffa_settings), -}; - -static struct snddev_icodec_data snddev_iearpiece_ffa_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE), - .name = "handset_rx", - .copp_id = 0, - .acdb_id = ACDB_ID_HANDSET_SPKR, - .profile = &iearpiece_ffa_profile, - .channel_mode = 1, - .pmctl_id = NULL, - .pmctl_id_sz = 0, - .default_sample_rate = 48000, - .pamp_on = NULL, - .pamp_off = NULL, - .property = SIDE_TONE_MASK, - .max_voice_rx_vol[VOC_NB_INDEX] = -700, - .min_voice_rx_vol[VOC_NB_INDEX] = -2200, - .max_voice_rx_vol[VOC_WB_INDEX] = -1400, - .min_voice_rx_vol[VOC_WB_INDEX] = -2900, -}; - -static struct platform_device msm_iearpiece_ffa_device = { - .name = "snddev_icodec", - .id = 19, - .dev = { .platform_data = &snddev_iearpiece_ffa_data }, -}; - -static struct adie_codec_action_unit imic_ffa_48KHz_osr256_actions[] = - AMIC_PRI_MONO_8000_OSR_256; /* 8000 profile also works for 48k */ - -static struct adie_codec_hwsetting_entry imic_ffa_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = imic_ffa_48KHz_osr256_actions, - .action_sz = ARRAY_SIZE(imic_ffa_48KHz_osr256_actions), - } -}; - -static enum hsed_controller imic_pmctl_id[] = {PM_HSED_CONTROLLER_0}; - -static struct adie_codec_dev_profile imic_ffa_profile = { - .path_type = ADIE_CODEC_TX, - .settings = imic_ffa_settings, - .setting_sz = ARRAY_SIZE(imic_ffa_settings), -}; - -static struct snddev_icodec_data snddev_imic_ffa_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "handset_tx", - .copp_id = 0, - .acdb_id = ACDB_ID_HANDSET_MIC, - .profile = &imic_ffa_profile, - .channel_mode = 1, - .pmctl_id = imic_pmctl_id, - .pmctl_id_sz = ARRAY_SIZE(imic_pmctl_id), - .default_sample_rate = 48000, - .pamp_on = NULL, - .pamp_off = NULL, -}; - -static struct platform_device msm_imic_ffa_device = { - .name = "snddev_icodec", - .id = 20, - .dev = { .platform_data = &snddev_imic_ffa_data }, -}; - -static struct adie_codec_action_unit ispkr_stereo_48KHz_osr256_actions[] = - SPEAKER_PRI_STEREO_48000_OSR_256; - -static struct adie_codec_hwsetting_entry ispkr_stereo_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = ispkr_stereo_48KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ispkr_stereo_48KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile ispkr_stereo_profile = { - .path_type = ADIE_CODEC_RX, - .settings = ispkr_stereo_settings, - .setting_sz = ARRAY_SIZE(ispkr_stereo_settings), -}; - -static struct snddev_icodec_data snddev_ispkr_stereo_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE), - .name = "speaker_stereo_rx", - .copp_id = 0, - .acdb_id = ACDB_ID_SPKR_PHONE_STEREO, - .profile = &ispkr_stereo_profile, - .channel_mode = 2, - .pmctl_id = NULL, - .pmctl_id_sz = 0, - .default_sample_rate = 48000, - .pamp_on = msm_snddev_poweramp_on, - .pamp_off = msm_snddev_poweramp_off, - .max_voice_rx_vol[VOC_NB_INDEX] = 1000, - .min_voice_rx_vol[VOC_NB_INDEX] = -500, - .max_voice_rx_vol[VOC_WB_INDEX] = 1000, - .min_voice_rx_vol[VOC_WB_INDEX] = -500 -}; - -static struct platform_device msm_ispkr_stereo_device = { - .name = "snddev_icodec", - .id = 8, - .dev = { .platform_data = &snddev_ispkr_stereo_data }, -}; - -static struct adie_codec_action_unit iheadset_mic_tx_osr256_actions[] = - AMIC1_HEADSET_TX_MONO_PRIMARY_OSR256; - -static struct adie_codec_hwsetting_entry iheadset_mic_tx_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = iheadset_mic_tx_osr256_actions, - .action_sz = ARRAY_SIZE(iheadset_mic_tx_osr256_actions), - } -}; - -static struct adie_codec_dev_profile iheadset_mic_profile = { - .path_type = ADIE_CODEC_TX, - .settings = iheadset_mic_tx_settings, - .setting_sz = ARRAY_SIZE(iheadset_mic_tx_settings), -}; - -static struct snddev_icodec_data snddev_headset_mic_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "headset_mono_tx", - .copp_id = 0, - .acdb_id = ACDB_ID_HEADSET_MIC, - .profile = &iheadset_mic_profile, - .channel_mode = 1, - .pmctl_id = NULL, - .pmctl_id_sz = 0, - .default_sample_rate = 48000, - .pamp_on = msm_snddev_tx_route_config, - .pamp_off = msm_snddev_tx_route_deconfig, -}; - -static struct platform_device msm_headset_mic_device = { - .name = "snddev_icodec", - .id = 6, - .dev = { .platform_data = &snddev_headset_mic_data }, -}; - -static struct snddev_mi2s_data snddev_mi2s_fm_tx_data = { - .capability = SNDDEV_CAP_TX , - .name = "fmradio_stereo_tx", - .copp_id = 2, - .acdb_id = ACDB_ID_FM_TX, - .channel_mode = 2, - .sd_lines = MI2S_SD_3, - .route = NULL, - .deroute = NULL, - .default_sample_rate = 48000, -}; - -static struct platform_device msm_snddev_mi2s_fm_tx_device = { - .name = "snddev_mi2s", - .id = 1, - .dev = { .platform_data = &snddev_mi2s_fm_tx_data}, -}; - -static struct snddev_mi2s_data snddev_mi2s_fm_rx_data = { - .capability = SNDDEV_CAP_RX , - .name = "fmradio_stereo_rx", - .copp_id = 3, - .acdb_id = ACDB_ID_FM_RX, - .channel_mode = 2, - .sd_lines = MI2S_SD_3, - .route = NULL, - .deroute = NULL, - .default_sample_rate = 48000, -}; - -static struct platform_device msm_snddev_mi2s_fm_rx_device = { - .name = "snddev_mi2s", - .id = 2, - .dev = { .platform_data = &snddev_mi2s_fm_rx_data}, -}; - -static struct snddev_ecodec_data snddev_bt_sco_earpiece_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE), - .name = "bt_sco_rx", - .copp_id = 1, - .acdb_id = ACDB_ID_BT_SCO_SPKR, - .channel_mode = 1, - .conf_pcm_ctl_val = BT_SCO_PCM_CTL_VAL, - .conf_aux_codec_intf = BT_SCO_AUX_CODEC_INTF, - .conf_data_format_padding_val = BT_SCO_DATA_FORMAT_PADDING, - .max_voice_rx_vol[VOC_NB_INDEX] = 400, - .min_voice_rx_vol[VOC_NB_INDEX] = -1100, - .max_voice_rx_vol[VOC_WB_INDEX] = 400, - .min_voice_rx_vol[VOC_WB_INDEX] = -1100, -}; - -static struct snddev_ecodec_data snddev_bt_sco_mic_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "bt_sco_tx", - .copp_id = 1, - .acdb_id = ACDB_ID_BT_SCO_MIC, - .channel_mode = 1, - .conf_pcm_ctl_val = BT_SCO_PCM_CTL_VAL, - .conf_aux_codec_intf = BT_SCO_AUX_CODEC_INTF, - .conf_data_format_padding_val = BT_SCO_DATA_FORMAT_PADDING, -}; - -static struct platform_device msm_bt_sco_earpiece_device = { - .name = "msm_snddev_ecodec", - .id = 0, - .dev = { .platform_data = &snddev_bt_sco_earpiece_data }, -}; - -static struct platform_device msm_bt_sco_mic_device = { - .name = "msm_snddev_ecodec", - .id = 1, - .dev = { .platform_data = &snddev_bt_sco_mic_data }, -}; - -static struct adie_codec_action_unit headset_ab_cpls_48KHz_osr256_actions[] = - HEADSET_AB_CPLS_48000_OSR_256; - -static struct adie_codec_hwsetting_entry headset_ab_cpls_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = headset_ab_cpls_48KHz_osr256_actions, - .action_sz = ARRAY_SIZE(headset_ab_cpls_48KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile headset_ab_cpls_profile = { - .path_type = ADIE_CODEC_RX, - .settings = headset_ab_cpls_settings, - .setting_sz = ARRAY_SIZE(headset_ab_cpls_settings), -}; - -static struct snddev_icodec_data snddev_ihs_stereo_rx_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE), - .name = "headset_stereo_rx", - .copp_id = 0, - .acdb_id = ACDB_ID_HEADSET_SPKR_STEREO, - .profile = &headset_ab_cpls_profile, - .channel_mode = 2, - .pmctl_id = NULL, - .pmctl_id_sz = 0, - .default_sample_rate = 48000, - .pamp_on = NULL, - .pamp_off = NULL, - .property = SIDE_TONE_MASK, - .voltage_on = msm_snddev_hsed_voltage_on, - .voltage_off = msm_snddev_hsed_voltage_off, - .max_voice_rx_vol[VOC_NB_INDEX] = -700, - .min_voice_rx_vol[VOC_NB_INDEX] = -2200, - .max_voice_rx_vol[VOC_WB_INDEX] = -900, - .min_voice_rx_vol[VOC_WB_INDEX] = -2400, -}; - -static struct platform_device msm_headset_stereo_device = { - .name = "snddev_icodec", - .id = 2, - .dev = { .platform_data = &snddev_ihs_stereo_rx_data }, -}; - -/*debug FS interface is exposed to test Class D and class AB mode - * amplifers for headset device folloowing options are supported - * 0 -> settings will be restored - * 1 -> Cladd D mode is selected - * 2 -> Class AB mode is selected -*/ -#ifdef CONFIG_DEBUG_FS -static struct adie_codec_action_unit - ihs_stereo_rx_class_d_legacy_48KHz_osr256_actions[] = - HPH_PRI_D_LEG_STEREO; - -static struct adie_codec_hwsetting_entry - ihs_stereo_rx_class_d_legacy_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = - ihs_stereo_rx_class_d_legacy_48KHz_osr256_actions, - .action_sz = ARRAY_SIZE - (ihs_stereo_rx_class_d_legacy_48KHz_osr256_actions), - } -}; - -static struct adie_codec_action_unit - ihs_stereo_rx_class_ab_legacy_48KHz_osr256_actions[] = - HPH_PRI_AB_LEG_STEREO; - -static struct adie_codec_hwsetting_entry - ihs_stereo_rx_class_ab_legacy_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = - ihs_stereo_rx_class_ab_legacy_48KHz_osr256_actions, - .action_sz = ARRAY_SIZE - (ihs_stereo_rx_class_ab_legacy_48KHz_osr256_actions), - } -}; - -static void snddev_hsed_config_modify_setting(int type) -{ - struct platform_device *device; - struct snddev_icodec_data *icodec_data; - - device = &msm_headset_stereo_device; - icodec_data = (struct snddev_icodec_data *)device->dev.platform_data; - - if (icodec_data) { - if (type == 1) { - icodec_data->voltage_on = NULL; - icodec_data->voltage_off = NULL; - icodec_data->profile->settings = - ihs_stereo_rx_class_d_legacy_settings; - icodec_data->profile->setting_sz = - ARRAY_SIZE(ihs_stereo_rx_class_d_legacy_settings); - } else if (type == 2) { - icodec_data->voltage_on = NULL; - icodec_data->voltage_off = NULL; - icodec_data->profile->settings = - ihs_stereo_rx_class_ab_legacy_settings; - icodec_data->profile->setting_sz = - ARRAY_SIZE(ihs_stereo_rx_class_ab_legacy_settings); - } - } -} - -static void snddev_hsed_config_restore_setting(void) -{ - struct platform_device *device; - struct snddev_icodec_data *icodec_data; - - device = &msm_headset_stereo_device; - icodec_data = device->dev.platform_data; - - if (icodec_data) { - icodec_data->voltage_on = msm_snddev_hsed_voltage_on; - icodec_data->voltage_off = msm_snddev_hsed_voltage_off; - icodec_data->profile->settings = headset_ab_cpls_settings; - icodec_data->profile->setting_sz = - ARRAY_SIZE(headset_ab_cpls_settings); - } -} - -static ssize_t snddev_hsed_config_debug_write(struct file *filp, - const char __user *ubuf, size_t cnt, loff_t *ppos) -{ - char *lb_str = filp->private_data; - char cmd; - - if (get_user(cmd, ubuf)) - return -EFAULT; - - if (!strcmp(lb_str, "msm_hsed_config")) { - switch (cmd) { - case '0': - snddev_hsed_config_restore_setting(); - break; - - case '1': - snddev_hsed_config_modify_setting(1); - break; - - case '2': - snddev_hsed_config_modify_setting(2); - break; - - default: - break; - } - } - return cnt; -} - -static int snddev_hsed_config_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static const struct file_operations snddev_hsed_config_debug_fops = { - .open = snddev_hsed_config_debug_open, - .write = snddev_hsed_config_debug_write -}; -#endif - -static enum hsed_controller ispk_pmctl_id[] = {PM_HSED_CONTROLLER_0}; - -static struct snddev_icodec_data snddev_ispkr_mic_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "speaker_mono_tx", - .copp_id = 0, - .acdb_id = ACDB_ID_SPKR_PHONE_MIC, - .profile = &imic_ffa_profile, - .channel_mode = 1, - .pmctl_id = ispk_pmctl_id, - .pmctl_id_sz = ARRAY_SIZE(ispk_pmctl_id), - .default_sample_rate = 48000, - .pamp_on = msm_snddev_tx_route_config, - .pamp_off = msm_snddev_tx_route_deconfig, -}; - -static struct platform_device msm_ispkr_mic_device = { - .name = "snddev_icodec", - .id = 18, - .dev = { .platform_data = &snddev_ispkr_mic_data }, -}; - -static struct adie_codec_action_unit idual_mic_endfire_8KHz_osr256_actions[] = - AMIC_DUAL_8000_OSR_256; - -static struct adie_codec_hwsetting_entry idual_mic_endfire_settings[] = { - { - .freq_plan = 8000, - .osr = 256, - .actions = idual_mic_endfire_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(idual_mic_endfire_8KHz_osr256_actions), - }, /* 8KHz profile can be used for 16KHz */ - { - .freq_plan = 16000, - .osr = 256, - .actions = idual_mic_endfire_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(idual_mic_endfire_8KHz_osr256_actions), - }, /* 8KHz profile can be used for 48KHz */ - { - .freq_plan = 48000, - .osr = 256, - .actions = idual_mic_endfire_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(idual_mic_endfire_8KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile idual_mic_endfire_profile = { - .path_type = ADIE_CODEC_TX, - .settings = idual_mic_endfire_settings, - .setting_sz = ARRAY_SIZE(idual_mic_endfire_settings), -}; - -static enum hsed_controller idual_mic_endfire_pmctl_id[] = { - PM_HSED_CONTROLLER_0, PM_HSED_CONTROLLER_2 -}; - -static struct snddev_icodec_data snddev_idual_mic_endfire_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "handset_dual_mic_endfire_tx", - .copp_id = 0, - .acdb_id = ACDB_ID_HANDSET_MIC_ENDFIRE, - .profile = &idual_mic_endfire_profile, - .channel_mode = 2, - .default_sample_rate = 48000, - .pmctl_id = idual_mic_endfire_pmctl_id, - .pmctl_id_sz = ARRAY_SIZE(idual_mic_endfire_pmctl_id), - .pamp_on = NULL, - .pamp_off = NULL, -}; - -static struct platform_device msm_idual_mic_endfire_device = { - .name = "snddev_icodec", - .id = 12, - .dev = { .platform_data = &snddev_idual_mic_endfire_data }, -}; - -static struct snddev_icodec_data snddev_spk_idual_mic_endfire_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "speaker_dual_mic_endfire_tx", - .copp_id = 0, - .acdb_id = ACDB_ID_SPKR_PHONE_MIC_ENDFIRE, - .profile = &idual_mic_endfire_profile, - .channel_mode = 2, - .default_sample_rate = 48000, - .pmctl_id = idual_mic_endfire_pmctl_id, - .pmctl_id_sz = ARRAY_SIZE(idual_mic_endfire_pmctl_id), - .pamp_on = NULL, - .pamp_off = NULL, -}; - -static struct platform_device msm_spk_idual_mic_endfire_device = { - .name = "snddev_icodec", - .id = 14, - .dev = { .platform_data = &snddev_spk_idual_mic_endfire_data }, -}; - -static struct adie_codec_action_unit itty_mono_tx_actions[] = - TTY_HEADSET_MONO_TX_8000_OSR_256; - -static struct adie_codec_hwsetting_entry itty_mono_tx_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = itty_mono_tx_actions, - .action_sz = ARRAY_SIZE(itty_mono_tx_actions), - }, -}; - -static struct adie_codec_dev_profile itty_mono_tx_profile = { - .path_type = ADIE_CODEC_TX, - .settings = itty_mono_tx_settings, - .setting_sz = ARRAY_SIZE(itty_mono_tx_settings), -}; - -static struct snddev_icodec_data snddev_itty_mono_tx_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE | SNDDEV_CAP_TTY), - .name = "tty_headset_mono_tx", - .copp_id = 0, - .acdb_id = ACDB_ID_TTY_HEADSET_MIC, - .profile = &itty_mono_tx_profile, - .channel_mode = 1, - .default_sample_rate = 48000, - .pmctl_id = NULL, - .pmctl_id_sz = 0, - .pamp_on = NULL, - .pamp_off = NULL, -}; - -static struct platform_device msm_itty_mono_tx_device = { - .name = "snddev_icodec", - .id = 16, - .dev = { .platform_data = &snddev_itty_mono_tx_data }, -}; - -static struct adie_codec_action_unit itty_mono_rx_actions[] = - TTY_HEADSET_MONO_RX_8000_OSR_256; - -static struct adie_codec_hwsetting_entry itty_mono_rx_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = itty_mono_rx_actions, - .action_sz = ARRAY_SIZE(itty_mono_rx_actions), - }, -}; - -static struct adie_codec_dev_profile itty_mono_rx_profile = { - .path_type = ADIE_CODEC_RX, - .settings = itty_mono_rx_settings, - .setting_sz = ARRAY_SIZE(itty_mono_rx_settings), -}; - -static struct snddev_icodec_data snddev_itty_mono_rx_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE | SNDDEV_CAP_TTY), - .name = "tty_headset_mono_rx", - .copp_id = 0, - .acdb_id = ACDB_ID_TTY_HEADSET_SPKR, - .profile = &itty_mono_rx_profile, - .channel_mode = 1, - .default_sample_rate = 48000, - .pamp_on = NULL, - .pamp_off = NULL, - .max_voice_rx_vol[VOC_NB_INDEX] = 0, - .min_voice_rx_vol[VOC_NB_INDEX] = 0, - .max_voice_rx_vol[VOC_WB_INDEX] = 0, - .min_voice_rx_vol[VOC_WB_INDEX] = 0, -}; - -static struct platform_device msm_itty_mono_rx_device = { - .name = "snddev_icodec", - .id = 17, - .dev = { .platform_data = &snddev_itty_mono_rx_data }, -}; - -static struct snddev_virtual_data snddev_a2dp_tx_data = { - .capability = SNDDEV_CAP_TX, - .name = "a2dp_tx", - .copp_id = 5, - .acdb_id = PSEUDO_ACDB_ID, -}; - -static struct snddev_virtual_data snddev_a2dp_rx_data = { - .capability = SNDDEV_CAP_RX, - .name = "a2dp_rx", - .copp_id = 2, - .acdb_id = PSEUDO_ACDB_ID, -}; - -static struct platform_device msm_a2dp_rx_device = { - .name = "snddev_virtual", - .id = 0, - .dev = { .platform_data = &snddev_a2dp_rx_data }, -}; - -static struct platform_device msm_a2dp_tx_device = { - .name = "snddev_virtual", - .id = 1, - .dev = { .platform_data = &snddev_a2dp_tx_data }, -}; - -static struct snddev_virtual_data snddev_uplink_rx_data = { - .capability = SNDDEV_CAP_RX, - .name = "uplink_rx", - .copp_id = 5, - .acdb_id = PSEUDO_ACDB_ID, -}; - -static struct platform_device msm_uplink_rx_device = { - .name = "snddev_virtual", - .id = 2, - .dev = { .platform_data = &snddev_uplink_rx_data }, -}; - -static struct snddev_icodec_data\ - snddev_idual_mic_endfire_real_stereo_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "handset_dual_mic_endfire_tx_real_stereo", - .copp_id = 0, - .acdb_id = PSEUDO_ACDB_ID, - .profile = &idual_mic_endfire_profile, - .channel_mode = REAL_STEREO_CHANNEL_MODE, - .default_sample_rate = 48000, - .pmctl_id = idual_mic_endfire_pmctl_id, - .pmctl_id_sz = ARRAY_SIZE(idual_mic_endfire_pmctl_id), - .pamp_on = NULL, - .pamp_off = NULL, -}; - -static struct platform_device msm_real_stereo_tx_device = { - .name = "snddev_icodec", - .id = 26, - .dev = { .platform_data = - &snddev_idual_mic_endfire_real_stereo_data }, -}; - -static struct adie_codec_action_unit ihs_ffa_mono_rx_48KHz_osr256_actions[] = - HEADSET_RX_CAPLESS_48000_OSR_256; - -static struct adie_codec_hwsetting_entry ihs_ffa_mono_rx_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = ihs_ffa_mono_rx_48KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ihs_ffa_mono_rx_48KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile ihs_ffa_mono_rx_profile = { - .path_type = ADIE_CODEC_RX, - .settings = ihs_ffa_mono_rx_settings, - .setting_sz = ARRAY_SIZE(ihs_ffa_mono_rx_settings), -}; - -static struct snddev_icodec_data snddev_ihs_ffa_mono_rx_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE), - .name = "headset_mono_rx", - .copp_id = 0, - .acdb_id = ACDB_ID_HEADSET_SPKR_MONO, - .profile = &ihs_ffa_mono_rx_profile, - .channel_mode = 1, - .default_sample_rate = 48000, - .pamp_on = msm_snddev_hsed_voltage_on, - .pamp_off = msm_snddev_hsed_voltage_off, - .max_voice_rx_vol[VOC_NB_INDEX] = -700, - .min_voice_rx_vol[VOC_NB_INDEX] = -2200, - .max_voice_rx_vol[VOC_WB_INDEX] = -900, - .min_voice_rx_vol[VOC_WB_INDEX] = -2400, - .property = SIDE_TONE_MASK, -}; - -static struct platform_device msm_ihs_ffa_mono_rx_device = { - .name = "snddev_icodec", - .id = 5, - .dev = { .platform_data = &snddev_ihs_ffa_mono_rx_data }, -}; - -static struct adie_codec_action_unit - ihs_stereo_speaker_stereo_rx_48KHz_osr256_actions[] = - HEADSET_STEREO_SPEAKER_STEREO_RX_CAPLESS_48000_OSR_256; - - -static struct adie_codec_hwsetting_entry - ihs_stereo_speaker_stereo_rx_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = ihs_stereo_speaker_stereo_rx_48KHz_osr256_actions, - .action_sz = - ARRAY_SIZE(ihs_stereo_speaker_stereo_rx_48KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile ihs_stereo_speaker_stereo_rx_profile = { - .path_type = ADIE_CODEC_RX, - .settings = ihs_stereo_speaker_stereo_rx_settings, - .setting_sz = ARRAY_SIZE(ihs_stereo_speaker_stereo_rx_settings), -}; - -static struct snddev_icodec_data snddev_ihs_stereo_speaker_stereo_rx_data = { - .capability = (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE), - .name = "headset_stereo_speaker_stereo_rx", - .copp_id = 0, - .acdb_id = ACDB_ID_HEADSET_STEREO_PLUS_SPKR_STEREO_RX, - .profile = &ihs_stereo_speaker_stereo_rx_profile, - .channel_mode = 2, - .default_sample_rate = 48000, - .pamp_on = msm_snddev_poweramp_on, - .pamp_off = msm_snddev_poweramp_off, - .voltage_on = msm_snddev_hsed_voltage_on, - .voltage_off = msm_snddev_hsed_voltage_off, - .max_voice_rx_vol[VOC_NB_INDEX] = -500, - .min_voice_rx_vol[VOC_NB_INDEX] = -2000, - .max_voice_rx_vol[VOC_WB_INDEX] = -900, - .min_voice_rx_vol[VOC_WB_INDEX] = -2400, -}; - -static struct platform_device msm_ihs_stereo_speaker_stereo_rx_device = { - .name = "snddev_icodec", - .id = 21, - .dev = { .platform_data = &snddev_ihs_stereo_speaker_stereo_rx_data }, -}; - -static struct adie_codec_action_unit ispk_dual_mic_bs_8KHz_osr256_actions[] = - HS_DMIC2_STEREO_8000_OSR_256; - -static struct adie_codec_hwsetting_entry ispk_dual_mic_bs_settings[] = { - { - .freq_plan = 8000, - .osr = 256, - .actions = ispk_dual_mic_bs_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ispk_dual_mic_bs_8KHz_osr256_actions), - }, /* 8KHz profile can be used for 16Khz */ - { - .freq_plan = 16000, - .osr = 256, - .actions = ispk_dual_mic_bs_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ispk_dual_mic_bs_8KHz_osr256_actions), - }, /* 8KHz profile can be used for 48KHz */ - { - .freq_plan = 48000, - .osr = 256, - .actions = ispk_dual_mic_bs_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(ispk_dual_mic_bs_8KHz_osr256_actions), - }, -}; - -static enum hsed_controller idual_mic_broadside_pmctl_id[] = { - PM_HSED_CONTROLLER_0, PM_HSED_CONTROLLER_2 -}; - -static struct adie_codec_dev_profile ispk_dual_mic_bs_profile = { - .path_type = ADIE_CODEC_TX, - .settings = ispk_dual_mic_bs_settings, - .setting_sz = ARRAY_SIZE(ispk_dual_mic_bs_settings), -}; -static struct snddev_icodec_data snddev_spk_idual_mic_broadside_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "speaker_dual_mic_broadside_tx", - .copp_id = 0, - .acdb_id = ACDB_ID_SPKR_PHONE_MIC_BROADSIDE, - .profile = &ispk_dual_mic_bs_profile, - .channel_mode = 2, - .default_sample_rate = 48000, - .pmctl_id = idual_mic_broadside_pmctl_id, - .pmctl_id_sz = ARRAY_SIZE(idual_mic_broadside_pmctl_id), - .pamp_on = NULL, - .pamp_off = NULL, -}; - -static struct platform_device msm_spk_idual_mic_broadside_device = { - .name = "snddev_icodec", - .id = 15, - .dev = { .platform_data = &snddev_spk_idual_mic_broadside_data }, -}; - -static struct adie_codec_action_unit idual_mic_bs_8KHz_osr256_actions[] = - HS_DMIC2_STEREO_8000_OSR_256; - -static struct adie_codec_hwsetting_entry idual_mic_broadside_settings[] = { - { - .freq_plan = 8000, - .osr = 256, - .actions = idual_mic_bs_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(idual_mic_bs_8KHz_osr256_actions), - }, /* 8KHz profile can be used for 16KHz */ - { - .freq_plan = 16000, - .osr = 256, - .actions = idual_mic_bs_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(idual_mic_bs_8KHz_osr256_actions), - }, /* 8KHz profile can be used for 16KHz */ - { - .freq_plan = 48000, - .osr = 256, - .actions = idual_mic_bs_8KHz_osr256_actions, - .action_sz = ARRAY_SIZE(idual_mic_bs_8KHz_osr256_actions), - } -}; - -static struct adie_codec_dev_profile idual_mic_broadside_profile = { - .path_type = ADIE_CODEC_TX, - .settings = idual_mic_broadside_settings, - .setting_sz = ARRAY_SIZE(idual_mic_broadside_settings), -}; - -static struct snddev_icodec_data snddev_idual_mic_broadside_data = { - .capability = (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE), - .name = "handset_dual_mic_broadside_tx", - .copp_id = 0, - .acdb_id = ACDB_ID_HANDSET_MIC_BROADSIDE, - .profile = &idual_mic_broadside_profile, - .channel_mode = 2, - .default_sample_rate = 48000, - .pmctl_id = idual_mic_broadside_pmctl_id, - .pmctl_id_sz = ARRAY_SIZE(idual_mic_broadside_pmctl_id), - .pamp_on = NULL, - .pamp_off = NULL, -}; - -static struct platform_device msm_idual_mic_broadside_device = { - .name = "snddev_icodec", - .id = 13, - .dev = { .platform_data = &snddev_idual_mic_broadside_data }, -}; - -static struct snddev_mi2s_data snddev_mi2s_stereo_rx_data = { - .capability = SNDDEV_CAP_RX , - .name = "hdmi_stereo_rx", - .copp_id = 3, - .acdb_id = ACDB_ID_HDMI, - .channel_mode = 2, - .sd_lines = MI2S_SD_0, - .route = msm_snddev_tx_route_config, - .deroute = msm_snddev_tx_route_deconfig, - .default_sample_rate = 48000, -}; - -static struct platform_device msm_snddev_mi2s_stereo_rx_device = { - .name = "snddev_mi2s", - .id = 0, - .dev = { .platform_data = &snddev_mi2s_stereo_rx_data }, -}; - -static struct adie_codec_action_unit auxpga_lb_lo_actions[] = - LB_AUXPGA_LO_STEREO; - -static struct adie_codec_hwsetting_entry auxpga_lb_lo_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = auxpga_lb_lo_actions, - .action_sz = ARRAY_SIZE(auxpga_lb_lo_actions), - }, -}; - -static struct adie_codec_dev_profile auxpga_lb_lo_profile = { - .path_type = ADIE_CODEC_LB, - .settings = auxpga_lb_lo_settings, - .setting_sz = ARRAY_SIZE(auxpga_lb_lo_settings), -}; - -static struct snddev_icodec_data snddev_auxpga_lb_lo_data = { - .capability = SNDDEV_CAP_LB, - .name = "auxpga_loopback_lo", - .copp_id = 0, - .acdb_id = PSEUDO_ACDB_ID, - .profile = &auxpga_lb_lo_profile, - .channel_mode = 2, - .default_sample_rate = 48000, - .pamp_on = msm_snddev_poweramp_on, - .pamp_off = msm_snddev_poweramp_off, - .dev_vol_type = SNDDEV_DEV_VOL_ANALOG, -}; - -static struct platform_device msm_auxpga_lb_lo_device = { - .name = "snddev_icodec", - .id = 27, - .dev = { .platform_data = &snddev_auxpga_lb_lo_data }, -}; - -static struct adie_codec_action_unit auxpga_lb_hs_actions[] = - LB_AUXPGA_HPH_AB_CPLS_STEREO; - -static struct adie_codec_hwsetting_entry auxpga_lb_hs_settings[] = { - { - .freq_plan = 48000, - .osr = 256, - .actions = auxpga_lb_hs_actions, - .action_sz = ARRAY_SIZE(auxpga_lb_hs_actions), - }, -}; - -static struct adie_codec_dev_profile auxpga_lb_hs_profile = { - .path_type = ADIE_CODEC_LB, - .settings = auxpga_lb_hs_settings, - .setting_sz = ARRAY_SIZE(auxpga_lb_hs_settings), -}; - -static struct snddev_icodec_data snddev_auxpga_lb_hs_data = { - .capability = SNDDEV_CAP_LB, - .name = "auxpga_loopback_hs", - .copp_id = 0, - .acdb_id = PSEUDO_ACDB_ID, - .profile = &auxpga_lb_hs_profile, - .channel_mode = 2, - .default_sample_rate = 48000, - .voltage_on = msm_snddev_hsed_voltage_on, - .voltage_off = msm_snddev_hsed_voltage_off, - .dev_vol_type = SNDDEV_DEV_VOL_ANALOG, -}; - -static struct platform_device msm_auxpga_lb_hs_device = { - .name = "snddev_icodec", - .id = 25, - .dev = { .platform_data = &snddev_auxpga_lb_hs_data }, -}; - -static struct platform_device *snd_devices_ffa[] __initdata = { - &msm_iearpiece_ffa_device, - &msm_imic_ffa_device, - &msm_ispkr_stereo_device, - &msm_headset_mic_device, - &msm_ihs_ffa_mono_rx_device, - &msm_snddev_mi2s_fm_rx_device, - &msm_snddev_mi2s_fm_tx_device, - &msm_bt_sco_earpiece_device, - &msm_bt_sco_mic_device, - &msm_ispkr_mic_device, - &msm_headset_stereo_device, - &msm_idual_mic_endfire_device, - &msm_spk_idual_mic_endfire_device, - &msm_itty_mono_tx_device, - &msm_itty_mono_rx_device, - &msm_a2dp_rx_device, - &msm_a2dp_tx_device, - &msm_uplink_rx_device, - &msm_real_stereo_tx_device, - &msm_ihs_stereo_speaker_stereo_rx_device, - &msm_spk_idual_mic_broadside_device, - &msm_idual_mic_broadside_device, - &msm_snddev_mi2s_stereo_rx_device, - &msm_auxpga_lb_hs_device, - &msm_auxpga_lb_lo_device, -}; - -void __ref msm_snddev_init_timpani(void) -{ - platform_add_devices(snd_devices_ffa, - ARRAY_SIZE(snd_devices_ffa)); -#ifdef CONFIG_DEBUG_FS - debugfs_hsed_config = debugfs_create_file("msm_hsed_config", - S_IFREG | S_IWUGO, NULL, - (void *) "msm_hsed_config", &snddev_hsed_config_debug_fops); - if (!debugfs_hsed_config) - pr_err("failed to create msm_head_config debug fs entry\n"); -#endif - -} diff --git a/arch/arm/mach-msm/qdsp5v2/snddev_ecodec.c b/arch/arm/mach-msm/qdsp5v2/snddev_ecodec.c deleted file mode 100644 index d8009aa2460c8f06d5509827e74ab3d44b5feff9..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/snddev_ecodec.c +++ /dev/null @@ -1,484 +0,0 @@ -/* Copyright (c) 2009,2011 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Context for each external codec device */ -struct snddev_ecodec_state { - struct snddev_ecodec_data *data; - u32 sample_rate; - bool enabled; -}; - -/* Global state for the driver */ -struct snddev_ecodec_drv_state { - struct mutex dev_lock; - u32 rx_active; /* ensure one rx device at a time */ - u32 tx_active; /* ensure one tx device at a time */ - struct clk *lpa_core_clk; - struct clk *ecodec_clk; -}; - -#define ADSP_CTL 1 - -static struct snddev_ecodec_drv_state snddev_ecodec_drv; - -static int snddev_ecodec_open_rx(struct snddev_ecodec_state *ecodec) -{ - int rc = 0; - struct snddev_ecodec_drv_state *drv = &snddev_ecodec_drv; - struct msm_afe_config afe_config; - int ret = 0; - - MM_DBG("snddev_ecodec_open_rx\n"); - - if (!drv->tx_active) { - /* request GPIO */ - rc = aux_pcm_gpios_request(); - if (rc) { - MM_ERR("GPIO enable failed\n"); - goto done; - } - /* config clocks */ - clk_prepare_enable(drv->lpa_core_clk); - - /*if long sync is selected in aux PCM interface - ecodec clock is updated to work with 128KHz, - if short sync is selected ecodec clock is updated to - work with 2.048MHz frequency, actual clock output is - different than the SW configuration by factor of two*/ - if (!(ecodec->data->conf_aux_codec_intf & - AUX_CODEC_CTL__AUX_CODEC_MODE__I2S_V)) { - if (ecodec->data->conf_aux_codec_intf & - AUX_CODEC_CTL__AUX_PCM_MODE__AUX_MASTER_V) { - MM_DBG("Update ecodec clock to 128 KHz, long " - "sync in master mode is selected\n"); - ret = clk_set_rate(drv->ecodec_clk, 256000); - if (ret < 0) - MM_ERR("Error updating ecodec clock" - " to 128KHz\n"); - } else if (ecodec->data->conf_aux_codec_intf & - AUX_CODEC_CTL__AUX_PCM_MODE__PRIM_SLAVE_V) { - MM_DBG("Update ecodec clock to 2 MHz, short" - " sync in slave mode is selected\n"); - ret = clk_set_rate(drv->ecodec_clk, 4096000); - if (ret < 0) - MM_ERR("Error updating ecodec clock" - " to 2.048MHz\n"); - } else { - MM_DBG("Update ecodec clock to 2 MHz, short" - " sync in master mode is selected\n"); - ret = clk_set_rate(drv->ecodec_clk, 4096000); - if (ret < 0) - MM_ERR("Error updating ecodec clock" - " to 2.048MHz\n"); - } - } - - /* enable ecodec clk */ - clk_prepare_enable(drv->ecodec_clk); - - /* let ADSP confiure AUX PCM regs */ - aux_codec_adsp_codec_ctl_en(ADSP_CTL); - - /* let adsp configure pcm path */ - aux_codec_pcm_path_ctl_en(ADSP_CTL); - - /* choose ADSP_A */ - audio_interct_aux_regsel(AUDIO_ADSP_A); - audio_interct_tpcm_source(AUDIO_ADSP_A); - audio_interct_rpcm_source(AUDIO_ADSP_A); - - clk_disable_unprepare(drv->lpa_core_clk); - - /* send AUX_CODEC_CONFIG to AFE */ - rc = afe_config_aux_codec(ecodec->data->conf_pcm_ctl_val, - ecodec->data->conf_aux_codec_intf, - ecodec->data->conf_data_format_padding_val); - if (IS_ERR_VALUE(rc)) - goto error; - } - /* send CODEC CONFIG to AFE */ - afe_config.sample_rate = ecodec->sample_rate / 1000; - afe_config.channel_mode = ecodec->data->channel_mode; - afe_config.volume = AFE_VOLUME_UNITY; - rc = afe_enable(AFE_HW_PATH_AUXPCM_RX, &afe_config); - if (IS_ERR_VALUE(rc)) { - if (!drv->tx_active) { - aux_pcm_gpios_free(); - clk_disable_unprepare(drv->ecodec_clk); - } - goto done; - } - - ecodec->enabled = 1; - return 0; - -error: - aux_pcm_gpios_free(); - clk_disable_unprepare(drv->ecodec_clk); -done: - return rc; -} - -static int snddev_ecodec_close_rx(struct snddev_ecodec_state *ecodec) -{ - struct snddev_ecodec_drv_state *drv = &snddev_ecodec_drv; - - /* free GPIO */ - if (!drv->tx_active) { - aux_pcm_gpios_free(); - clk_disable_unprepare(drv->ecodec_clk); - } - - /* disable AFE */ - afe_disable(AFE_HW_PATH_AUXPCM_RX); - - ecodec->enabled = 0; - - return 0; -} - -static int snddev_ecodec_open_tx(struct snddev_ecodec_state *ecodec) -{ - int rc = 0; - struct snddev_ecodec_drv_state *drv = &snddev_ecodec_drv; - struct msm_afe_config afe_config; - int ret = 0; - - MM_DBG("snddev_ecodec_open_tx\n"); - - /* request GPIO */ - if (!drv->rx_active) { - rc = aux_pcm_gpios_request(); - if (rc) { - MM_ERR("GPIO enable failed\n"); - goto done; - } - /* config clocks */ - clk_prepare_enable(drv->lpa_core_clk); - - /*if long sync is selected in aux PCM interface - ecodec clock is updated to work with 128KHz, - if short sync is selected ecodec clock is updated to - work with 2.048MHz frequency, actual clock output is - different than the SW configuration by factor of two*/ - if (!(ecodec->data->conf_aux_codec_intf & - AUX_CODEC_CTL__AUX_CODEC_MODE__I2S_V)) { - if (ecodec->data->conf_aux_codec_intf & - AUX_CODEC_CTL__AUX_PCM_MODE__AUX_MASTER_V) { - MM_DBG("Update ecodec clock to 128 KHz, long " - "sync in master mode is selected\n"); - ret = clk_set_rate(drv->ecodec_clk, 256000); - if (ret < 0) - MM_ERR("Error updating ecodec clock" - " to 128KHz\n"); - } else if (ecodec->data->conf_aux_codec_intf & - AUX_CODEC_CTL__AUX_PCM_MODE__PRIM_SLAVE_V) { - MM_DBG("Update ecodec clock to 2 MHz, short" - " sync in slave mode is selected\n"); - ret = clk_set_rate(drv->ecodec_clk, 4096000); - if (ret < 0) - MM_ERR("Error updating ecodec clock" - " to 2.048MHz\n"); - } else { - MM_DBG("Update ecodec clock to 2 MHz, short" - " sync in master mode is selected\n"); - ret = clk_set_rate(drv->ecodec_clk, 4096000); - if (ret < 0) - MM_ERR("Error updating ecodec clock" - " to 2.048MHz\n"); - } - } - - /* enable ecodec clk */ - clk_prepare_enable(drv->ecodec_clk); - - /* let ADSP confiure AUX PCM regs */ - aux_codec_adsp_codec_ctl_en(ADSP_CTL); - - /* let adsp configure pcm path */ - aux_codec_pcm_path_ctl_en(ADSP_CTL); - - /* choose ADSP_A */ - audio_interct_aux_regsel(AUDIO_ADSP_A); - audio_interct_tpcm_source(AUDIO_ADSP_A); - audio_interct_rpcm_source(AUDIO_ADSP_A); - - clk_disable_unprepare(drv->lpa_core_clk); - - /* send AUX_CODEC_CONFIG to AFE */ - rc = afe_config_aux_codec(ecodec->data->conf_pcm_ctl_val, - ecodec->data->conf_aux_codec_intf, - ecodec->data->conf_data_format_padding_val); - if (IS_ERR_VALUE(rc)) - goto error; - } - /* send CODEC CONFIG to AFE */ - afe_config.sample_rate = ecodec->sample_rate / 1000; - afe_config.channel_mode = ecodec->data->channel_mode; - afe_config.volume = AFE_VOLUME_UNITY; - rc = afe_enable(AFE_HW_PATH_AUXPCM_TX, &afe_config); - if (IS_ERR_VALUE(rc)) { - if (!drv->rx_active) { - aux_pcm_gpios_free(); - clk_disable_unprepare(drv->ecodec_clk); - } - goto done; - } - - ecodec->enabled = 1; - return 0; - -error: - clk_disable_unprepare(drv->ecodec_clk); - aux_pcm_gpios_free(); -done: - return rc; -} - -static int snddev_ecodec_close_tx(struct snddev_ecodec_state *ecodec) -{ - struct snddev_ecodec_drv_state *drv = &snddev_ecodec_drv; - - /* free GPIO */ - if (!drv->rx_active) { - aux_pcm_gpios_free(); - clk_disable_unprepare(drv->ecodec_clk); - } - - /* disable AFE */ - afe_disable(AFE_HW_PATH_AUXPCM_TX); - - ecodec->enabled = 0; - - return 0; -} - - -static int snddev_ecodec_open(struct msm_snddev_info *dev_info) -{ - int rc = 0; - struct snddev_ecodec_state *ecodec; - struct snddev_ecodec_drv_state *drv = &snddev_ecodec_drv; - - if (!dev_info) { - rc = -EINVAL; - goto error; - } - - ecodec = dev_info->private_data; - - if (ecodec->data->capability & SNDDEV_CAP_RX) { - mutex_lock(&drv->dev_lock); - if (drv->rx_active) { - mutex_unlock(&drv->dev_lock); - rc = -EBUSY; - goto error; - } - rc = snddev_ecodec_open_rx(ecodec); - if (!IS_ERR_VALUE(rc)) - drv->rx_active = 1; - mutex_unlock(&drv->dev_lock); - } else { - mutex_lock(&drv->dev_lock); - if (drv->tx_active) { - mutex_unlock(&drv->dev_lock); - rc = -EBUSY; - goto error; - } - rc = snddev_ecodec_open_tx(ecodec); - if (!IS_ERR_VALUE(rc)) - drv->tx_active = 1; - mutex_unlock(&drv->dev_lock); - } -error: - return rc; -} - -static int snddev_ecodec_close(struct msm_snddev_info *dev_info) -{ - int rc = 0; - struct snddev_ecodec_state *ecodec; - struct snddev_ecodec_drv_state *drv = &snddev_ecodec_drv; - if (!dev_info) { - rc = -EINVAL; - goto error; - } - - ecodec = dev_info->private_data; - - if (ecodec->data->capability & SNDDEV_CAP_RX) { - mutex_lock(&drv->dev_lock); - if (!drv->rx_active) { - mutex_unlock(&drv->dev_lock); - rc = -EPERM; - goto error; - } - rc = snddev_ecodec_close_rx(ecodec); - if (!IS_ERR_VALUE(rc)) - drv->rx_active = 0; - mutex_unlock(&drv->dev_lock); - } else { - mutex_lock(&drv->dev_lock); - if (!drv->tx_active) { - mutex_unlock(&drv->dev_lock); - rc = -EPERM; - goto error; - } - rc = snddev_ecodec_close_tx(ecodec); - if (!IS_ERR_VALUE(rc)) - drv->tx_active = 0; - mutex_unlock(&drv->dev_lock); - } - -error: - return rc; -} - -static int snddev_ecodec_set_freq(struct msm_snddev_info *dev_info, u32 rate) -{ - int rc = 0; - - if (!dev_info) { - rc = -EINVAL; - goto error; - } - return 8000; - -error: - return rc; -} - -static int snddev_ecodec_probe(struct platform_device *pdev) -{ - int rc = 0, i; - struct snddev_ecodec_data *pdata; - struct msm_snddev_info *dev_info; - struct snddev_ecodec_state *ecodec; - - if (!pdev || !pdev->dev.platform_data) { - printk(KERN_ALERT "Invalid caller \n"); - rc = -1; - goto error; - } - pdata = pdev->dev.platform_data; - - ecodec = kzalloc(sizeof(struct snddev_ecodec_state), GFP_KERNEL); - if (!ecodec) { - rc = -ENOMEM; - goto error; - } - - dev_info = kzalloc(sizeof(struct msm_snddev_info), GFP_KERNEL); - if (!dev_info) { - kfree(ecodec); - rc = -ENOMEM; - goto error; - } - - dev_info->name = pdata->name; - dev_info->copp_id = pdata->copp_id; - dev_info->acdb_id = pdata->acdb_id; - dev_info->private_data = (void *) ecodec; - dev_info->dev_ops.open = snddev_ecodec_open; - dev_info->dev_ops.close = snddev_ecodec_close; - dev_info->dev_ops.set_freq = snddev_ecodec_set_freq; - dev_info->dev_ops.enable_sidetone = NULL; - dev_info->capability = pdata->capability; - dev_info->opened = 0; - - msm_snddev_register(dev_info); - ecodec->data = pdata; - ecodec->sample_rate = 8000; /* Default to 8KHz */ - if (pdata->capability & SNDDEV_CAP_RX) { - for (i = 0; i < VOC_RX_VOL_ARRAY_NUM; i++) { - dev_info->max_voc_rx_vol[i] = - pdata->max_voice_rx_vol[i]; - dev_info->min_voc_rx_vol[i] = - pdata->min_voice_rx_vol[i]; - } - } -error: - return rc; -} - -static int snddev_ecodec_remove(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_driver snddev_ecodec_driver = { - .probe = snddev_ecodec_probe, - .remove = snddev_ecodec_remove, - .driver = { .name = "msm_snddev_ecodec" } -}; - -static int __init snddev_ecodec_init(void) -{ - int rc = 0; - struct snddev_ecodec_drv_state *ecodec_drv = &snddev_ecodec_drv; - - MM_INFO("snddev_ecodec_init\n"); - rc = platform_driver_register(&snddev_ecodec_driver); - if (IS_ERR_VALUE(rc)) - goto error_platform_driver; - ecodec_drv->ecodec_clk = clk_get(NULL, "ecodec_clk"); - if (IS_ERR(ecodec_drv->ecodec_clk)) - goto error_ecodec_clk; - ecodec_drv->lpa_core_clk = clk_get(NULL, "lpa_core_clk"); - if (IS_ERR(ecodec_drv->lpa_core_clk)) - goto error_lpa_core_clk; - - - mutex_init(&ecodec_drv->dev_lock); - ecodec_drv->rx_active = 0; - ecodec_drv->tx_active = 0; - return 0; - -error_lpa_core_clk: - clk_put(ecodec_drv->ecodec_clk); -error_ecodec_clk: - platform_driver_unregister(&snddev_ecodec_driver); -error_platform_driver: - - MM_ERR("encounter error\n"); - return -ENODEV; -} - -static void __exit snddev_ecodec_exit(void) -{ - struct snddev_ecodec_drv_state *ecodec_drv = &snddev_ecodec_drv; - - platform_driver_unregister(&snddev_ecodec_driver); - clk_put(ecodec_drv->ecodec_clk); - - return; -} - -module_init(snddev_ecodec_init); -module_exit(snddev_ecodec_exit); - -MODULE_DESCRIPTION("ECodec Sound Device driver"); -MODULE_VERSION("1.0"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5v2/snddev_icodec.c b/arch/arm/mach-msm/qdsp5v2/snddev_icodec.c deleted file mode 100644 index cbb05872bb3743387be99acfe7ed0d5753bbfff7..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/snddev_icodec.c +++ /dev/null @@ -1,1218 +0,0 @@ -/* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SMPS_AUDIO_PLAYBACK_ID "AUPB" -#define SMPS_AUDIO_RECORD_ID "AURC" - -#define SNDDEV_ICODEC_PCM_SZ 32 /* 16 bit / sample stereo mode */ -#define SNDDEV_ICODEC_MUL_FACTOR 3 /* Multi by 8 Shift by 3 */ -#define SNDDEV_ICODEC_CLK_RATE(freq) \ - (((freq) * (SNDDEV_ICODEC_PCM_SZ)) << (SNDDEV_ICODEC_MUL_FACTOR)) - -#ifdef CONFIG_DEBUG_FS -static struct adie_codec_action_unit debug_rx_actions[] = - HANDSET_RX_8000_OSR_256; - -static struct adie_codec_action_unit debug_tx_lb_actions[] = { - { ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF }, - { ADIE_CODEC_ACTION_ENTRY, - ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x01)}, - { ADIE_CODEC_ACTION_ENTRY, - ADIE_CODEC_PACK_ENTRY(0x80, 0x01, 0x00) }, - { ADIE_CODEC_ACTION_ENTRY, - ADIE_CODEC_PACK_ENTRY(0x8A, 0x30, 0x30)}, - { ADIE_CODEC_ACTION_ENTRY, - ADIE_CODEC_PACK_ENTRY(0x11, 0xfc, 0xfc)}, - { ADIE_CODEC_ACTION_ENTRY, - ADIE_CODEC_PACK_ENTRY(0x13, 0xfc, 0x58)}, - { ADIE_CODEC_ACTION_ENTRY, - ADIE_CODEC_PACK_ENTRY(0x14, 0xff, 0x65)}, - { ADIE_CODEC_ACTION_ENTRY, - ADIE_CODEC_PACK_ENTRY(0x15, 0xff, 0x64)}, - { ADIE_CODEC_ACTION_ENTRY, - ADIE_CODEC_PACK_ENTRY(0x82, 0xff, 0x5C)}, - { ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY }, - { ADIE_CODEC_ACTION_ENTRY, - ADIE_CODEC_PACK_ENTRY(0x0D, 0xF0, 0xd0)}, - { ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8}, - { ADIE_CODEC_ACTION_ENTRY, - ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x14)}, - { ADIE_CODEC_ACTION_ENTRY, - ADIE_CODEC_PACK_ENTRY(0x86, 0xff, 0x00)}, - { ADIE_CODEC_ACTION_ENTRY, - ADIE_CODEC_PACK_ENTRY(0x8A, 0x50, 0x40)}, - { ADIE_CODEC_ACTION_ENTRY, - ADIE_CODEC_PACK_ENTRY(0x91, 0xFF, 0x01)}, /* Start loop back */ - { ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, - { ADIE_CODEC_ACTION_ENTRY, - ADIE_CODEC_PACK_ENTRY(0x8A, 0x10, 0x30)}, - { ADIE_CODEC_ACTION_ENTRY, - ADIE_CODEC_PACK_ENTRY(0x0D, 0xFF, 0x00)}, - { ADIE_CODEC_ACTION_ENTRY, - ADIE_CODEC_PACK_ENTRY(0x83, 0x14, 0x00)}, - { ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, - { ADIE_CODEC_ACTION_ENTRY, - ADIE_CODEC_PACK_ENTRY(0x11, 0xff, 0x00)} -}; - -static struct adie_codec_action_unit debug_tx_actions[] = - HANDSET_TX_8000_OSR_256; - -static struct adie_codec_hwsetting_entry debug_rx_settings[] = { - { - .freq_plan = 8000, - .osr = 256, - .actions = debug_rx_actions, - .action_sz = ARRAY_SIZE(debug_rx_actions), - } -}; - -static struct adie_codec_hwsetting_entry debug_tx_settings[] = { - { - .freq_plan = 8000, - .osr = 256, - .actions = debug_tx_actions, - .action_sz = ARRAY_SIZE(debug_tx_actions), - } -}; - -static struct adie_codec_hwsetting_entry debug_tx_lb_settings[] = { - { - .freq_plan = 8000, - .osr = 256, - .actions = debug_tx_lb_actions, - .action_sz = ARRAY_SIZE(debug_tx_lb_actions), - } -}; - -static struct adie_codec_dev_profile debug_rx_profile = { - .path_type = ADIE_CODEC_RX, - .settings = debug_rx_settings, - .setting_sz = ARRAY_SIZE(debug_rx_settings), -}; - -static struct adie_codec_dev_profile debug_tx_profile = { - .path_type = ADIE_CODEC_TX, - .settings = debug_tx_settings, - .setting_sz = ARRAY_SIZE(debug_tx_settings), -}; - -static struct adie_codec_dev_profile debug_tx_lb_profile = { - .path_type = ADIE_CODEC_TX, - .settings = debug_tx_lb_settings, - .setting_sz = ARRAY_SIZE(debug_tx_lb_settings), -}; -#endif /* CONFIG_DEBUG_FS */ - -/* Context for each internal codec sound device */ -struct snddev_icodec_state { - struct snddev_icodec_data *data; - struct adie_codec_path *adie_path; - u32 sample_rate; - u32 enabled; -}; - -/* Global state for the driver */ -struct snddev_icodec_drv_state { - struct mutex rx_lock; - struct mutex lb_lock; - struct mutex tx_lock; - u32 rx_active; /* ensure one rx device at a time */ - u32 tx_active; /* ensure one tx device at a time */ - struct clk *rx_mclk; - struct clk *rx_sclk; - struct clk *tx_mclk; - struct clk *tx_sclk; - struct clk *lpa_codec_clk; - struct clk *lpa_core_clk; - struct clk *lpa_p_clk; - struct lpa_drv *lpa; - - struct pm_qos_request rx_pm_qos_req; - struct pm_qos_request tx_pm_qos_req; -}; - -static struct snddev_icodec_drv_state snddev_icodec_drv; - -static int snddev_icodec_open_rx(struct snddev_icodec_state *icodec) -{ - int trc, err; - int smps_mode = PMAPP_SMPS_MODE_VOTE_PWM; - struct msm_afe_config afe_config; - struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; - struct lpa_codec_config lpa_config; - - pm_qos_update_request(&drv->rx_pm_qos_req, - msm_cpuidle_get_deep_idle_latency()); - - if ((icodec->data->acdb_id == ACDB_ID_HEADSET_SPKR_MONO) || - (icodec->data->acdb_id == ACDB_ID_HEADSET_SPKR_STEREO)) { - /* Vote PMAPP_SMPS_MODE_VOTE_PFM for headset */ - smps_mode = PMAPP_SMPS_MODE_VOTE_PFM; - MM_DBG("snddev_icodec_open_rx: PMAPP_SMPS_MODE_VOTE_PFM \n"); - } else - MM_DBG("snddev_icodec_open_rx: PMAPP_SMPS_MODE_VOTE_PWM \n"); - - /* Vote for SMPS mode*/ - err = pmapp_smps_mode_vote(SMPS_AUDIO_PLAYBACK_ID, - PMAPP_VREG_S4, smps_mode); - if (err != 0) - MM_ERR("pmapp_smps_mode_vote error %d\n", err); - - /* enable MI2S RX master block */ - /* enable MI2S RX bit clock */ - trc = clk_set_rate(drv->rx_mclk, - SNDDEV_ICODEC_CLK_RATE(icodec->sample_rate)); - if (IS_ERR_VALUE(trc)) - goto error_invalid_freq; - clk_prepare_enable(drv->rx_mclk); - clk_prepare_enable(drv->rx_sclk); - /* clk_set_rate(drv->lpa_codec_clk, 1); */ /* Remove if use pcom */ - clk_prepare_enable(drv->lpa_p_clk); - clk_prepare_enable(drv->lpa_codec_clk); - clk_prepare_enable(drv->lpa_core_clk); - - /* Enable LPA sub system - */ - drv->lpa = lpa_get(); - if (!drv->lpa) - goto error_lpa; - lpa_config.sample_rate = icodec->sample_rate; - lpa_config.sample_width = 16; - lpa_config.output_interface = LPA_OUTPUT_INTF_WB_CODEC; - lpa_config.num_channels = icodec->data->channel_mode; - lpa_cmd_codec_config(drv->lpa, &lpa_config); - - /* Set audio interconnect reg to LPA */ - audio_interct_codec(AUDIO_INTERCT_LPA); - - /* Set MI2S */ - mi2s_set_codec_output_path((icodec->data->channel_mode == 2 ? - MI2S_CHAN_STEREO : MI2S_CHAN_MONO_PACKED), WT_16_BIT); - - if (icodec->data->voltage_on) - icodec->data->voltage_on(); - - /* Configure ADIE */ - trc = adie_codec_open(icodec->data->profile, &icodec->adie_path); - if (IS_ERR_VALUE(trc)) - goto error_adie; - /* OSR default to 256, can be changed for power optimization - * If OSR is to be changed, need clock API for setting the divider - */ - adie_codec_setpath(icodec->adie_path, icodec->sample_rate, 256); - /* Start AFE */ - afe_config.sample_rate = icodec->sample_rate / 1000; - afe_config.channel_mode = icodec->data->channel_mode; - afe_config.volume = AFE_VOLUME_UNITY; - trc = afe_enable(AFE_HW_PATH_CODEC_RX, &afe_config); - if (IS_ERR_VALUE(trc)) - goto error_afe; - lpa_cmd_enable_codec(drv->lpa, 1); - /* Enable ADIE */ - adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_READY); - adie_codec_proceed_stage(icodec->adie_path, - ADIE_CODEC_DIGITAL_ANALOG_READY); - - /* Enable power amplifier */ - if (icodec->data->pamp_on) - icodec->data->pamp_on(); - - icodec->enabled = 1; - - pm_qos_update_request(&drv->rx_pm_qos_req, PM_QOS_DEFAULT_VALUE); - return 0; - -error_afe: - adie_codec_close(icodec->adie_path); - icodec->adie_path = NULL; -error_adie: - lpa_put(drv->lpa); -error_lpa: - clk_disable_unprepare(drv->lpa_p_clk); - clk_disable_unprepare(drv->lpa_codec_clk); - clk_disable_unprepare(drv->lpa_core_clk); - clk_disable_unprepare(drv->rx_sclk); - clk_disable_unprepare(drv->rx_mclk); -error_invalid_freq: - - MM_ERR("encounter error\n"); - - pm_qos_update_request(&drv->rx_pm_qos_req, PM_QOS_DEFAULT_VALUE); - return -ENODEV; -} - -static int snddev_icodec_open_tx(struct snddev_icodec_state *icodec) -{ - int trc; - int i, err; - struct msm_afe_config afe_config; - struct snddev_icodec_drv_state *drv = &snddev_icodec_drv;; - - pm_qos_update_request(&drv->tx_pm_qos_req, - msm_cpuidle_get_deep_idle_latency()); - - /* Vote for PWM mode*/ - err = pmapp_smps_mode_vote(SMPS_AUDIO_RECORD_ID, - PMAPP_VREG_S4, PMAPP_SMPS_MODE_VOTE_PWM); - if (err != 0) - MM_ERR("pmapp_smps_mode_vote error %d\n", err); - - /* Reuse pamp_on for TX platform-specific setup */ - if (icodec->data->pamp_on) - icodec->data->pamp_on(); - - for (i = 0; i < icodec->data->pmctl_id_sz; i++) { - pmic_hsed_enable(icodec->data->pmctl_id[i], - PM_HSED_ENABLE_PWM_TCXO); - } - - /* enable MI2S TX master block */ - /* enable MI2S TX bit clock */ - trc = clk_set_rate(drv->tx_mclk, - SNDDEV_ICODEC_CLK_RATE(icodec->sample_rate)); - if (IS_ERR_VALUE(trc)) - goto error_invalid_freq; - clk_prepare_enable(drv->tx_mclk); - clk_prepare_enable(drv->tx_sclk); - - /* Set MI2S */ - mi2s_set_codec_input_path((icodec->data->channel_mode == - REAL_STEREO_CHANNEL_MODE ? MI2S_CHAN_STEREO : - (icodec->data->channel_mode == 2 ? - MI2S_CHAN_STEREO : MI2S_CHAN_MONO_RAW)), - WT_16_BIT); - /* Configure ADIE */ - trc = adie_codec_open(icodec->data->profile, &icodec->adie_path); - if (IS_ERR_VALUE(trc)) - goto error_adie; - /* Enable ADIE */ - adie_codec_setpath(icodec->adie_path, icodec->sample_rate, 256); - adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_READY); - adie_codec_proceed_stage(icodec->adie_path, - ADIE_CODEC_DIGITAL_ANALOG_READY); - - /* Start AFE */ - afe_config.sample_rate = icodec->sample_rate / 1000; - afe_config.channel_mode = icodec->data->channel_mode; - afe_config.volume = AFE_VOLUME_UNITY; - trc = afe_enable(AFE_HW_PATH_CODEC_TX, &afe_config); - if (IS_ERR_VALUE(trc)) - goto error_afe; - - - icodec->enabled = 1; - - pm_qos_update_request(&drv->tx_pm_qos_req, PM_QOS_DEFAULT_VALUE); - return 0; - -error_afe: - adie_codec_close(icodec->adie_path); - icodec->adie_path = NULL; -error_adie: - clk_disable_unprepare(drv->tx_sclk); - clk_disable_unprepare(drv->tx_mclk); -error_invalid_freq: - - /* Disable mic bias */ - for (i = 0; i < icodec->data->pmctl_id_sz; i++) { - pmic_hsed_enable(icodec->data->pmctl_id[i], - PM_HSED_ENABLE_OFF); - } - - if (icodec->data->pamp_off) - icodec->data->pamp_off(); - - MM_ERR("encounter error\n"); - - pm_qos_update_request(&drv->tx_pm_qos_req, PM_QOS_DEFAULT_VALUE); - return -ENODEV; -} - -static int snddev_icodec_close_lb(struct snddev_icodec_state *icodec) -{ - /* Disable power amplifier */ - if (icodec->data->pamp_off) - icodec->data->pamp_off(); - - if (icodec->adie_path) { - adie_codec_proceed_stage(icodec->adie_path, - ADIE_CODEC_DIGITAL_OFF); - adie_codec_close(icodec->adie_path); - icodec->adie_path = NULL; - } - if (icodec->data->voltage_off) - icodec->data->voltage_off(); - - return 0; -} - -static int snddev_icodec_close_rx(struct snddev_icodec_state *icodec) -{ - int err; - struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; - - pm_qos_update_request(&drv->rx_pm_qos_req, - msm_cpuidle_get_deep_idle_latency()); - - /* Remove the vote for SMPS mode*/ - err = pmapp_smps_mode_vote(SMPS_AUDIO_PLAYBACK_ID, - PMAPP_VREG_S4, PMAPP_SMPS_MODE_VOTE_DONTCARE); - if (err != 0) - MM_ERR("pmapp_smps_mode_vote error %d\n", err); - - /* Disable power amplifier */ - if (icodec->data->pamp_off) - icodec->data->pamp_off(); - - /* Disable ADIE */ - adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_OFF); - adie_codec_close(icodec->adie_path); - icodec->adie_path = NULL; - - afe_disable(AFE_HW_PATH_CODEC_RX); - - if (icodec->data->voltage_off) - icodec->data->voltage_off(); - - /* Disable LPA Sub system */ - lpa_cmd_enable_codec(drv->lpa, 0); - lpa_put(drv->lpa); - - /* Disable LPA clocks */ - clk_disable_unprepare(drv->lpa_p_clk); - clk_disable_unprepare(drv->lpa_codec_clk); - clk_disable_unprepare(drv->lpa_core_clk); - - /* Disable MI2S RX master block */ - /* Disable MI2S RX bit clock */ - clk_disable_unprepare(drv->rx_sclk); - clk_disable_unprepare(drv->rx_mclk); - - icodec->enabled = 0; - - pm_qos_update_request(&drv->rx_pm_qos_req, PM_QOS_DEFAULT_VALUE); - return 0; -} - -static int snddev_icodec_close_tx(struct snddev_icodec_state *icodec) -{ - struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; - int i, err; - - pm_qos_update_request(&drv->tx_pm_qos_req, - msm_cpuidle_get_deep_idle_latency()); - - /* Remove the vote for SMPS mode*/ - err = pmapp_smps_mode_vote(SMPS_AUDIO_RECORD_ID, - PMAPP_VREG_S4, PMAPP_SMPS_MODE_VOTE_DONTCARE); - if (err != 0) - MM_ERR("pmapp_smps_mode_vote error %d\n", err); - - afe_disable(AFE_HW_PATH_CODEC_TX); - - /* Disable ADIE */ - adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_OFF); - adie_codec_close(icodec->adie_path); - icodec->adie_path = NULL; - - /* Disable MI2S TX master block */ - /* Disable MI2S TX bit clock */ - clk_disable_unprepare(drv->tx_sclk); - clk_disable_unprepare(drv->tx_mclk); - - /* Disable mic bias */ - for (i = 0; i < icodec->data->pmctl_id_sz; i++) { - pmic_hsed_enable(icodec->data->pmctl_id[i], - PM_HSED_ENABLE_OFF); - } - - /* Reuse pamp_off for TX platform-specific setup */ - if (icodec->data->pamp_off) - icodec->data->pamp_off(); - - icodec->enabled = 0; - - pm_qos_update_request(&drv->tx_pm_qos_req, PM_QOS_DEFAULT_VALUE); - return 0; -} - -static int snddev_icodec_open_lb(struct snddev_icodec_state *icodec) -{ - int trc; - trc = adie_codec_open(icodec->data->profile, &icodec->adie_path); - if (IS_ERR_VALUE(trc)) - pr_err("%s: adie codec open failed\n", __func__); - else - adie_codec_setpath(icodec->adie_path, - icodec->sample_rate, 256); - - if (icodec->adie_path) - adie_codec_proceed_stage(icodec->adie_path, - ADIE_CODEC_DIGITAL_ANALOG_READY); - if (icodec->data->pamp_on) - icodec->data->pamp_on(); - - icodec->enabled = 1; - return 0; -} - -static int snddev_icodec_set_device_volume_impl( - struct msm_snddev_info *dev_info, u32 volume) -{ - struct snddev_icodec_state *icodec; - u8 afe_path_id; - - int rc = 0; - - icodec = dev_info->private_data; - - if (icodec->data->capability & SNDDEV_CAP_RX) - afe_path_id = AFE_HW_PATH_CODEC_RX; - else - afe_path_id = AFE_HW_PATH_CODEC_TX; - - if (icodec->data->dev_vol_type & SNDDEV_DEV_VOL_DIGITAL) { - - rc = adie_codec_set_device_digital_volume(icodec->adie_path, - icodec->data->channel_mode == - REAL_STEREO_CHANNEL_MODE ? - 2 : icodec->data->channel_mode, volume); - if (rc < 0) { - MM_ERR("unable to set_device_digital_volume for" - "%s volume in percentage = %u\n", - dev_info->name, volume); - return rc; - } - - } else if (icodec->data->dev_vol_type & SNDDEV_DEV_VOL_ANALOG) { - rc = adie_codec_set_device_analog_volume(icodec->adie_path, - icodec->data->channel_mode == - REAL_STEREO_CHANNEL_MODE ? - 2 : icodec->data->channel_mode, volume); - if (rc < 0) { - MM_ERR("unable to set_device_analog_volume for" - "%s volume in percentage = %u\n", - dev_info->name, volume); - return rc; - } - } - else { - MM_ERR("Invalid device volume control\n"); - return -EPERM; - } - return rc; -} - -static int snddev_icodec_close(struct msm_snddev_info *dev_info) -{ - int rc = 0; - struct snddev_icodec_state *icodec; - struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; - if (!dev_info) { - rc = -EINVAL; - goto error; - } - - icodec = dev_info->private_data; - - if (icodec->data->capability & SNDDEV_CAP_RX) { - mutex_lock(&drv->rx_lock); - if (!drv->rx_active) { - mutex_unlock(&drv->rx_lock); - rc = -EPERM; - goto error; - } - rc = snddev_icodec_close_rx(icodec); - if (!IS_ERR_VALUE(rc)) - drv->rx_active = 0; - mutex_unlock(&drv->rx_lock); - } else if (icodec->data->capability & SNDDEV_CAP_LB) { - mutex_lock(&drv->lb_lock); - rc = snddev_icodec_close_lb(icodec); - mutex_unlock(&drv->lb_lock); - } else { - mutex_lock(&drv->tx_lock); - if (!drv->tx_active) { - mutex_unlock(&drv->tx_lock); - rc = -EPERM; - goto error; - } - rc = snddev_icodec_close_tx(icodec); - if (!IS_ERR_VALUE(rc)) - drv->tx_active = 0; - mutex_unlock(&drv->tx_lock); - } - -error: - return rc; -} - -static int snddev_icodec_open(struct msm_snddev_info *dev_info) -{ - int rc = 0; - struct snddev_icodec_state *icodec; - struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; - - if (!dev_info) { - rc = -EINVAL; - goto error; - } - - icodec = dev_info->private_data; - - if (icodec->data->capability & SNDDEV_CAP_RX) { - mutex_lock(&drv->rx_lock); - if (drv->rx_active) { - mutex_unlock(&drv->rx_lock); - rc = -EBUSY; - goto error; - } - rc = snddev_icodec_open_rx(icodec); - - if (!IS_ERR_VALUE(rc)) { - drv->rx_active = 1; - if ((icodec->data->dev_vol_type & ( - SNDDEV_DEV_VOL_DIGITAL | - SNDDEV_DEV_VOL_ANALOG))) - rc = snddev_icodec_set_device_volume_impl( - dev_info, dev_info->dev_volume); - if (IS_ERR_VALUE(rc)) { - MM_ERR("Failed to set device volume" - " impl for rx device\n"); - snddev_icodec_close(dev_info); - mutex_unlock(&drv->rx_lock); - goto error; - } - } - mutex_unlock(&drv->rx_lock); - } else if (icodec->data->capability & SNDDEV_CAP_LB) { - mutex_lock(&drv->lb_lock); - rc = snddev_icodec_open_lb(icodec); - if (!IS_ERR_VALUE(rc)) { - if ((icodec->data->dev_vol_type & ( - SNDDEV_DEV_VOL_DIGITAL | - SNDDEV_DEV_VOL_ANALOG))) - rc = snddev_icodec_set_device_volume_impl( - dev_info, - dev_info->dev_volume); - if (rc < 0) - MM_ERR("failed to set device volume\n"); - } - mutex_unlock(&drv->lb_lock); - } else { - mutex_lock(&drv->tx_lock); - if (drv->tx_active) { - mutex_unlock(&drv->tx_lock); - rc = -EBUSY; - goto error; - } - rc = snddev_icodec_open_tx(icodec); - - if (!IS_ERR_VALUE(rc)) { - drv->tx_active = 1; - if ((icodec->data->dev_vol_type & ( - SNDDEV_DEV_VOL_DIGITAL | - SNDDEV_DEV_VOL_ANALOG))) - rc = snddev_icodec_set_device_volume_impl( - dev_info, dev_info->dev_volume); - if (IS_ERR_VALUE(rc)) { - MM_ERR("Failed to set device volume" - " impl for tx device\n"); - snddev_icodec_close(dev_info); - mutex_unlock(&drv->tx_lock); - goto error; - } - } - mutex_unlock(&drv->tx_lock); - } -error: - return rc; -} - -static int snddev_icodec_check_freq(u32 req_freq) -{ - int rc = -EINVAL; - - if ((req_freq != 0) && (req_freq >= 8000) && (req_freq <= 48000)) { - if ((req_freq == 8000) || (req_freq == 11025) || - (req_freq == 12000) || (req_freq == 16000) || - (req_freq == 22050) || (req_freq == 24000) || - (req_freq == 32000) || (req_freq == 44100) || - (req_freq == 48000)) { - rc = 0; - } else - MM_INFO("Unsupported Frequency:%d\n", req_freq); - } - return rc; -} - -static int snddev_icodec_set_freq(struct msm_snddev_info *dev_info, u32 rate) -{ - int rc; - struct snddev_icodec_state *icodec; - - if (!dev_info) { - rc = -EINVAL; - goto error; - } - - icodec = dev_info->private_data; - if (adie_codec_freq_supported(icodec->data->profile, rate) != 0) { - rc = -EINVAL; - goto error; - } else { - if (snddev_icodec_check_freq(rate) != 0) { - rc = -EINVAL; - goto error; - } else - icodec->sample_rate = rate; - } - - if (icodec->enabled) { - snddev_icodec_close(dev_info); - snddev_icodec_open(dev_info); - } - - return icodec->sample_rate; - -error: - return rc; -} - -static int snddev_icodec_enable_sidetone(struct msm_snddev_info *dev_info, - u32 enable) -{ - int rc = 0; - struct snddev_icodec_state *icodec; - struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; - - if (!dev_info) { - MM_ERR("invalid dev_info\n"); - rc = -EINVAL; - goto error; - } - - icodec = dev_info->private_data; - - if (icodec->data->capability & SNDDEV_CAP_RX) { - mutex_lock(&drv->rx_lock); - if (!drv->rx_active || !dev_info->opened) { - MM_ERR("dev not active\n"); - rc = -EPERM; - mutex_unlock(&drv->rx_lock); - goto error; - } - rc = adie_codec_enable_sidetone(icodec->adie_path, enable); - mutex_unlock(&drv->rx_lock); - } else { - rc = -EINVAL; - MM_ERR("rx device only\n"); - } - -error: - return rc; - -} - -int snddev_icodec_set_device_volume(struct msm_snddev_info *dev_info, - u32 volume) -{ - struct snddev_icodec_state *icodec; - struct mutex *lock; - struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; - int rc = -EPERM; - - if (!dev_info) { - MM_INFO("device not intilized.\n"); - return -EINVAL; - } - - icodec = dev_info->private_data; - - if (!(icodec->data->dev_vol_type & (SNDDEV_DEV_VOL_DIGITAL - | SNDDEV_DEV_VOL_ANALOG))) { - - MM_INFO("device %s does not support device volume " - "control.", dev_info->name); - return -EPERM; - } - dev_info->dev_volume = volume; - - if (icodec->data->capability & SNDDEV_CAP_RX) - lock = &drv->rx_lock; - else if (icodec->data->capability & SNDDEV_CAP_LB) - lock = &drv->lb_lock; - else - lock = &drv->tx_lock; - - mutex_lock(lock); - - rc = snddev_icodec_set_device_volume_impl(dev_info, - dev_info->dev_volume); - mutex_unlock(lock); - return rc; -} - -static int snddev_icodec_probe(struct platform_device *pdev) -{ - int rc = 0, i; - struct snddev_icodec_data *pdata; - struct msm_snddev_info *dev_info; - struct snddev_icodec_state *icodec; - - if (!pdev || !pdev->dev.platform_data) { - printk(KERN_ALERT "Invalid caller \n"); - rc = -1; - goto error; - } - pdata = pdev->dev.platform_data; - if ((pdata->capability & SNDDEV_CAP_RX) && - (pdata->capability & SNDDEV_CAP_TX)) { - MM_ERR("invalid device data either RX or TX\n"); - goto error; - } - icodec = kzalloc(sizeof(struct snddev_icodec_state), GFP_KERNEL); - if (!icodec) { - rc = -ENOMEM; - goto error; - } - dev_info = kmalloc(sizeof(struct msm_snddev_info), GFP_KERNEL); - if (!dev_info) { - kfree(icodec); - rc = -ENOMEM; - goto error; - } - - dev_info->name = pdata->name; - dev_info->copp_id = pdata->copp_id; - dev_info->acdb_id = pdata->acdb_id; - dev_info->private_data = (void *) icodec; - dev_info->dev_ops.open = snddev_icodec_open; - dev_info->dev_ops.close = snddev_icodec_close; - dev_info->dev_ops.set_freq = snddev_icodec_set_freq; - dev_info->dev_ops.set_device_volume = snddev_icodec_set_device_volume; - dev_info->capability = pdata->capability; - dev_info->opened = 0; - msm_snddev_register(dev_info); - icodec->data = pdata; - icodec->sample_rate = pdata->default_sample_rate; - dev_info->sample_rate = pdata->default_sample_rate; - if (pdata->capability & SNDDEV_CAP_RX) { - for (i = 0; i < VOC_RX_VOL_ARRAY_NUM; i++) { - dev_info->max_voc_rx_vol[i] = - pdata->max_voice_rx_vol[i]; - dev_info->min_voc_rx_vol[i] = - pdata->min_voice_rx_vol[i]; - } - /*sidetone is enabled only for the device which - property set for side tone*/ - if (pdata->property & SIDE_TONE_MASK) - dev_info->dev_ops.enable_sidetone = - snddev_icodec_enable_sidetone; - else - dev_info->dev_ops.enable_sidetone = NULL; - } else { - dev_info->dev_ops.enable_sidetone = NULL; - } - -error: - return rc; -} - -static int snddev_icodec_remove(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_driver snddev_icodec_driver = { - .probe = snddev_icodec_probe, - .remove = snddev_icodec_remove, - .driver = { .name = "snddev_icodec" } -}; - -#ifdef CONFIG_DEBUG_FS -static struct dentry *debugfs_sdev_dent; -static struct dentry *debugfs_afelb; -static struct dentry *debugfs_adielb; -static struct adie_codec_path *debugfs_rx_adie; -static struct adie_codec_path *debugfs_tx_adie; - -static int snddev_icodec_debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - MM_INFO("snddev_icodec: debug intf %s\n", (char *) file->private_data); - return 0; -} - -static void debugfs_adie_loopback(u32 loop) -{ - struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; - - if (loop) { - - /* enable MI2S RX master block */ - /* enable MI2S RX bit clock */ - clk_set_rate(drv->rx_mclk, - SNDDEV_ICODEC_CLK_RATE(8000)); - clk_prepare_enable(drv->rx_mclk); - clk_prepare_enable(drv->rx_sclk); - - MM_INFO("configure ADIE RX path\n"); - /* Configure ADIE */ - adie_codec_open(&debug_rx_profile, &debugfs_rx_adie); - adie_codec_setpath(debugfs_rx_adie, 8000, 256); - adie_codec_proceed_stage(debugfs_rx_adie, - ADIE_CODEC_DIGITAL_ANALOG_READY); - - MM_INFO("Enable Handset Mic bias\n"); - pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_PWM_TCXO); - /* enable MI2S TX master block */ - /* enable MI2S TX bit clock */ - clk_set_rate(drv->tx_mclk, - SNDDEV_ICODEC_CLK_RATE(8000)); - clk_prepare_enable(drv->tx_mclk); - clk_prepare_enable(drv->tx_sclk); - - MM_INFO("configure ADIE TX path\n"); - /* Configure ADIE */ - adie_codec_open(&debug_tx_lb_profile, &debugfs_tx_adie); - adie_codec_setpath(debugfs_tx_adie, 8000, 256); - adie_codec_proceed_stage(debugfs_tx_adie, - ADIE_CODEC_DIGITAL_ANALOG_READY); - } else { - /* Disable ADIE */ - adie_codec_proceed_stage(debugfs_rx_adie, - ADIE_CODEC_DIGITAL_OFF); - adie_codec_close(debugfs_rx_adie); - adie_codec_proceed_stage(debugfs_tx_adie, - ADIE_CODEC_DIGITAL_OFF); - adie_codec_close(debugfs_tx_adie); - - pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_OFF); - - /* Disable MI2S RX master block */ - /* Disable MI2S RX bit clock */ - clk_disable_unprepare(drv->rx_sclk); - clk_disable_unprepare(drv->rx_mclk); - - /* Disable MI2S TX master block */ - /* Disable MI2S TX bit clock */ - clk_disable_unprepare(drv->tx_sclk); - clk_disable_unprepare(drv->tx_mclk); - } -} - -static void debugfs_afe_loopback(u32 loop) -{ - int trc; - struct msm_afe_config afe_config; - struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; - struct lpa_codec_config lpa_config; - - if (loop) { - /* Vote for SMPS mode*/ - pmapp_smps_mode_vote(SMPS_AUDIO_PLAYBACK_ID, - PMAPP_VREG_S4, PMAPP_SMPS_MODE_VOTE_PWM); - - /* enable MI2S RX master block */ - /* enable MI2S RX bit clock */ - trc = clk_set_rate(drv->rx_mclk, - SNDDEV_ICODEC_CLK_RATE(8000)); - if (IS_ERR_VALUE(trc)) - MM_ERR("failed to set clk rate\n"); - clk_prepare_enable(drv->rx_mclk); - clk_prepare_enable(drv->rx_sclk); - clk_prepare_enable(drv->lpa_p_clk); - clk_prepare_enable(drv->lpa_codec_clk); - clk_prepare_enable(drv->lpa_core_clk); - /* Enable LPA sub system - */ - drv->lpa = lpa_get(); - if (!drv->lpa) - MM_ERR("failed to enable lpa\n"); - lpa_config.sample_rate = 8000; - lpa_config.sample_width = 16; - lpa_config.output_interface = LPA_OUTPUT_INTF_WB_CODEC; - lpa_config.num_channels = 1; - lpa_cmd_codec_config(drv->lpa, &lpa_config); - /* Set audio interconnect reg to LPA */ - audio_interct_codec(AUDIO_INTERCT_LPA); - mi2s_set_codec_output_path(MI2S_CHAN_MONO_PACKED, WT_16_BIT); - MM_INFO("configure ADIE RX path\n"); - /* Configure ADIE */ - adie_codec_open(&debug_rx_profile, &debugfs_rx_adie); - adie_codec_setpath(debugfs_rx_adie, 8000, 256); - lpa_cmd_enable_codec(drv->lpa, 1); - - /* Start AFE for RX */ - afe_config.sample_rate = 0x8; - afe_config.channel_mode = 1; - afe_config.volume = AFE_VOLUME_UNITY; - MM_INFO("enable afe\n"); - trc = afe_enable(AFE_HW_PATH_CODEC_RX, &afe_config); - if (IS_ERR_VALUE(trc)) - MM_ERR("fail to enable afe RX\n"); - adie_codec_proceed_stage(debugfs_rx_adie, - ADIE_CODEC_DIGITAL_READY); - adie_codec_proceed_stage(debugfs_rx_adie, - ADIE_CODEC_DIGITAL_ANALOG_READY); - - /* Vote for PWM mode*/ - pmapp_smps_mode_vote(SMPS_AUDIO_RECORD_ID, - PMAPP_VREG_S4, PMAPP_SMPS_MODE_VOTE_PWM); - - MM_INFO("Enable Handset Mic bias\n"); - pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_PWM_TCXO); - - /* enable MI2S TX master block */ - /* enable MI2S TX bit clock */ - clk_set_rate(drv->tx_mclk, - SNDDEV_ICODEC_CLK_RATE(8000)); - clk_prepare_enable(drv->tx_mclk); - clk_prepare_enable(drv->tx_sclk); - /* Set MI2S */ - mi2s_set_codec_input_path(MI2S_CHAN_MONO_PACKED, WT_16_BIT); - MM_INFO("configure ADIE TX path\n"); - /* Configure ADIE */ - adie_codec_open(&debug_tx_profile, &debugfs_tx_adie); - adie_codec_setpath(debugfs_tx_adie, 8000, 256); - adie_codec_proceed_stage(debugfs_tx_adie, - ADIE_CODEC_DIGITAL_READY); - adie_codec_proceed_stage(debugfs_tx_adie, - ADIE_CODEC_DIGITAL_ANALOG_READY); - /* Start AFE for TX */ - afe_config.sample_rate = 0x8; - afe_config.channel_mode = 1; - afe_config.volume = AFE_VOLUME_UNITY; - trc = afe_enable(AFE_HW_PATH_CODEC_TX, &afe_config); - if (IS_ERR_VALUE(trc)) - MM_ERR("failed to enable AFE TX\n"); - /* Set the volume level to non unity, to avoid - loopback effect */ - afe_device_volume_ctrl(AFE_HW_PATH_CODEC_RX, 0x0500); - - /* enable afe loopback */ - afe_loopback(1); - MM_INFO("AFE loopback enabled\n"); - } else { - /* disable afe loopback */ - afe_loopback(0); - /* Remove the vote for SMPS mode*/ - pmapp_smps_mode_vote(SMPS_AUDIO_PLAYBACK_ID, - PMAPP_VREG_S4, PMAPP_SMPS_MODE_VOTE_DONTCARE); - - /* Disable ADIE */ - adie_codec_proceed_stage(debugfs_rx_adie, - ADIE_CODEC_DIGITAL_OFF); - adie_codec_close(debugfs_rx_adie); - /* Disable AFE for RX */ - afe_disable(AFE_HW_PATH_CODEC_RX); - - /* Disable LPA Sub system */ - lpa_cmd_enable_codec(drv->lpa, 0); - lpa_put(drv->lpa); - - /* Disable LPA clocks */ - clk_disable_unprepare(drv->lpa_p_clk); - clk_disable_unprepare(drv->lpa_codec_clk); - clk_disable_unprepare(drv->lpa_core_clk); - - /* Disable MI2S RX master block */ - /* Disable MI2S RX bit clock */ - clk_disable_unprepare(drv->rx_sclk); - clk_disable_unprepare(drv->rx_mclk); - - pmapp_smps_mode_vote(SMPS_AUDIO_RECORD_ID, - PMAPP_VREG_S4, PMAPP_SMPS_MODE_VOTE_DONTCARE); - - /* Disable AFE for TX */ - afe_disable(AFE_HW_PATH_CODEC_TX); - - /* Disable ADIE */ - adie_codec_proceed_stage(debugfs_tx_adie, - ADIE_CODEC_DIGITAL_OFF); - adie_codec_close(debugfs_tx_adie); - /* Disable MI2S TX master block */ - /* Disable MI2S TX bit clock */ - clk_disable_unprepare(drv->tx_sclk); - clk_disable_unprepare(drv->tx_mclk); - pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_OFF); - MM_INFO("AFE loopback disabled\n"); - } -} - -static ssize_t snddev_icodec_debug_write(struct file *filp, - const char __user *ubuf, size_t cnt, loff_t *ppos) -{ - char *lb_str = filp->private_data; - char cmd; - - if (get_user(cmd, ubuf)) - return -EFAULT; - - MM_INFO("%s %c\n", lb_str, cmd); - - if (!strcmp(lb_str, "adie_loopback")) { - switch (cmd) { - case '1': - debugfs_adie_loopback(1); - break; - case '0': - debugfs_adie_loopback(0); - break; - } - } else if (!strcmp(lb_str, "afe_loopback")) { - switch (cmd) { - case '1': - debugfs_afe_loopback(1); - break; - case '0': - debugfs_afe_loopback(0); - break; - } - } - - return cnt; -} - -static const struct file_operations snddev_icodec_debug_fops = { - .open = snddev_icodec_debug_open, - .write = snddev_icodec_debug_write -}; -#endif - -static int __init snddev_icodec_init(void) -{ - s32 rc; - struct snddev_icodec_drv_state *icodec_drv = &snddev_icodec_drv; - - rc = platform_driver_register(&snddev_icodec_driver); - if (IS_ERR_VALUE(rc)) - goto error_platform_driver; - icodec_drv->rx_mclk = clk_get(NULL, "mi2s_codec_rx_m_clk"); - if (IS_ERR(icodec_drv->rx_mclk)) - goto error_rx_mclk; - icodec_drv->rx_sclk = clk_get(NULL, "mi2s_codec_rx_s_clk"); - if (IS_ERR(icodec_drv->rx_sclk)) - goto error_rx_sclk; - icodec_drv->tx_mclk = clk_get(NULL, "mi2s_codec_tx_m_clk"); - if (IS_ERR(icodec_drv->tx_mclk)) - goto error_tx_mclk; - icodec_drv->tx_sclk = clk_get(NULL, "mi2s_codec_tx_s_clk"); - if (IS_ERR(icodec_drv->tx_sclk)) - goto error_tx_sclk; - icodec_drv->lpa_codec_clk = clk_get(NULL, "lpa_codec_clk"); - if (IS_ERR(icodec_drv->lpa_codec_clk)) - goto error_lpa_codec_clk; - icodec_drv->lpa_core_clk = clk_get(NULL, "lpa_core_clk"); - if (IS_ERR(icodec_drv->lpa_core_clk)) - goto error_lpa_core_clk; - icodec_drv->lpa_p_clk = clk_get(NULL, "lpa_pclk"); - if (IS_ERR(icodec_drv->lpa_p_clk)) - goto error_lpa_p_clk; - -#ifdef CONFIG_DEBUG_FS - debugfs_sdev_dent = debugfs_create_dir("snddev_icodec", 0); - if (debugfs_sdev_dent) { - debugfs_afelb = debugfs_create_file("afe_loopback", - S_IFREG | S_IWUGO, debugfs_sdev_dent, - (void *) "afe_loopback", &snddev_icodec_debug_fops); - debugfs_adielb = debugfs_create_file("adie_loopback", - S_IFREG | S_IWUGO, debugfs_sdev_dent, - (void *) "adie_loopback", &snddev_icodec_debug_fops); - } -#endif - mutex_init(&icodec_drv->rx_lock); - mutex_init(&icodec_drv->lb_lock); - mutex_init(&icodec_drv->tx_lock); - icodec_drv->rx_active = 0; - icodec_drv->tx_active = 0; - icodec_drv->lpa = NULL; - pm_qos_add_request(&icodec_drv->tx_pm_qos_req, PM_QOS_CPU_DMA_LATENCY, - PM_QOS_DEFAULT_VALUE); - pm_qos_add_request(&icodec_drv->rx_pm_qos_req, PM_QOS_CPU_DMA_LATENCY, - PM_QOS_DEFAULT_VALUE); - return 0; - -error_lpa_p_clk: - clk_put(icodec_drv->lpa_core_clk); -error_lpa_core_clk: - clk_put(icodec_drv->lpa_codec_clk); -error_lpa_codec_clk: - clk_put(icodec_drv->tx_sclk); -error_tx_sclk: - clk_put(icodec_drv->tx_mclk); -error_tx_mclk: - clk_put(icodec_drv->rx_sclk); -error_rx_sclk: - clk_put(icodec_drv->rx_mclk); -error_rx_mclk: - platform_driver_unregister(&snddev_icodec_driver); -error_platform_driver: - - MM_ERR("encounter error\n"); - return -ENODEV; -} - -static void __exit snddev_icodec_exit(void) -{ - struct snddev_icodec_drv_state *icodec_drv = &snddev_icodec_drv; - -#ifdef CONFIG_DEBUG_FS - if (debugfs_afelb) - debugfs_remove(debugfs_afelb); - if (debugfs_adielb) - debugfs_remove(debugfs_adielb); - if (debugfs_sdev_dent) - debugfs_remove(debugfs_sdev_dent); -#endif - platform_driver_unregister(&snddev_icodec_driver); - - clk_put(icodec_drv->rx_sclk); - clk_put(icodec_drv->rx_mclk); - clk_put(icodec_drv->tx_sclk); - clk_put(icodec_drv->tx_mclk); - return; -} - -module_init(snddev_icodec_init); -module_exit(snddev_icodec_exit); - -MODULE_DESCRIPTION("ICodec Sound Device driver"); -MODULE_VERSION("1.0"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5v2/snddev_mi2s.c b/arch/arm/mach-msm/qdsp5v2/snddev_mi2s.c deleted file mode 100644 index 7f4ee265461d9dbda700a34d541354754695c56e..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/snddev_mi2s.c +++ /dev/null @@ -1,405 +0,0 @@ -/* Copyright (c) 2010, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Global state for the driver */ -struct snddev_mi2s_drv_state { - struct clk *mclk; - struct clk *sclk; - struct mutex lock; - u8 sd_lines_used; - u8 clocks_enabled; -}; - -static struct snddev_mi2s_drv_state snddev_mi2s_drv; - -static int snddev_mi2s_open_tx(struct msm_snddev_info *dev_info) -{ - u8 channels; - struct msm_afe_config afe_config; - int rc; - struct snddev_mi2s_data *snddev_mi2s_data = dev_info->private_data; - - MM_DBG("%s: channel_mode = %u sd_line_mask = 0x%x " - "default_sample_rate = %u\n", __func__, - snddev_mi2s_data->channel_mode, snddev_mi2s_data->sd_lines, - snddev_mi2s_data->default_sample_rate); - - if (snddev_mi2s_data->channel_mode == 2) { - channels = MI2S_CHAN_STEREO; - } else { - MM_ERR("%s: Invalid number of channels = %u\n", __func__, - snddev_mi2s_data->channel_mode); - return -EINVAL; - } - - /* Set MI2S */ - mi2s_set_hdmi_input_path(channels, WT_16_BIT, - snddev_mi2s_data->sd_lines); - - afe_config.sample_rate = snddev_mi2s_data->default_sample_rate / 1000; - afe_config.channel_mode = snddev_mi2s_data->channel_mode; - afe_config.volume = AFE_VOLUME_UNITY; - rc = afe_enable(AFE_HW_PATH_MI2S_TX, &afe_config); - - if (IS_ERR_VALUE(rc)) { - MM_ERR("%s: afe_enable failed for AFE_HW_PATH_MI2S_TX " - "rc = %d\n", __func__, rc); - return -ENODEV; - } - - /* Enable audio path */ - if (snddev_mi2s_data->route) - snddev_mi2s_data->route(); - - return 0; -} - -static int snddev_mi2s_open_rx(struct msm_snddev_info *dev_info) -{ - int rc; - struct msm_afe_config afe_config; - u8 channels; - struct snddev_mi2s_data *snddev_mi2s_data = dev_info->private_data; - - MM_DBG("%s: channel_mode = %u sd_line_mask = 0x%x " - "default_sample_rate = %u\n", __func__, - snddev_mi2s_data->channel_mode, snddev_mi2s_data->sd_lines, - snddev_mi2s_data->default_sample_rate); - - if (snddev_mi2s_data->channel_mode == 2) - channels = MI2S_CHAN_STEREO; - else if (snddev_mi2s_data->channel_mode == 4) - channels = MI2S_CHAN_4CHANNELS; - else if (snddev_mi2s_data->channel_mode == 6) - channels = MI2S_CHAN_6CHANNELS; - else if (snddev_mi2s_data->channel_mode == 8) - channels = MI2S_CHAN_8CHANNELS; - else - channels = MI2S_CHAN_MONO_RAW; - - /* Set MI2S */ - mi2s_set_hdmi_output_path(channels, WT_16_BIT, - snddev_mi2s_data->sd_lines); - - /* Start AFE */ - afe_config.sample_rate = snddev_mi2s_data->default_sample_rate / 1000; - afe_config.channel_mode = snddev_mi2s_data->channel_mode; - afe_config.volume = AFE_VOLUME_UNITY; - rc = afe_enable(AFE_HW_PATH_MI2S_RX, &afe_config); - - if (IS_ERR_VALUE(rc)) { - MM_ERR("%s: encounter error\n", __func__); - return -ENODEV; - } - - /* Enable audio path */ - if (snddev_mi2s_data->route) - snddev_mi2s_data->route(); - - MM_DBG("%s: enabled %s \n", __func__, snddev_mi2s_data->name); - - return 0; -} - -static int snddev_mi2s_open(struct msm_snddev_info *dev_info) -{ - int rc = 0; - struct snddev_mi2s_drv_state *drv = &snddev_mi2s_drv; - u32 dir; - struct snddev_mi2s_data *snddev_mi2s_data = dev_info->private_data; - - if (!dev_info) { - MM_ERR("%s: msm_snddev_info is null \n", __func__); - return -EINVAL; - } - - mutex_lock(&drv->lock); - - if (drv->sd_lines_used & snddev_mi2s_data->sd_lines) { - MM_ERR("%s: conflict in SD data line. can not use the device\n", - __func__); - mutex_unlock(&drv->lock); - return -EBUSY; - } - - if (!drv->clocks_enabled) { - - rc = mi2s_config_clk_gpio(); - if (rc) { - MM_ERR("%s: mi2s GPIO config failed for %s\n", - __func__, snddev_mi2s_data->name); - mutex_unlock(&drv->lock); - return -EIO; - } - clk_prepare_enable(drv->mclk); - clk_prepare_enable(drv->sclk); - drv->clocks_enabled = 1; - MM_DBG("%s: clks enabled\n", __func__); - } else - MM_DBG("%s: clks already enabled\n", __func__); - - if (snddev_mi2s_data->capability & SNDDEV_CAP_RX) { - - dir = DIR_RX; - rc = mi2s_config_data_gpio(dir, snddev_mi2s_data->sd_lines); - - if (rc) { - rc = -EIO; - MM_ERR("%s: mi2s GPIO config failed for %s\n", - __func__, snddev_mi2s_data->name); - goto mi2s_data_gpio_failure; - } - - MM_DBG("%s: done gpio config rx SD lines\n", __func__); - - rc = snddev_mi2s_open_rx(dev_info); - - if (IS_ERR_VALUE(rc)) { - MM_ERR(" snddev_mi2s_open_rx failed \n"); - goto mi2s_cleanup_open; - } - - drv->sd_lines_used |= snddev_mi2s_data->sd_lines; - - MM_DBG("%s: sd_lines_used = 0x%x\n", __func__, - drv->sd_lines_used); - mutex_unlock(&drv->lock); - - } else { - dir = DIR_TX; - rc = mi2s_config_data_gpio(dir, snddev_mi2s_data->sd_lines); - - if (rc) { - rc = -EIO; - MM_ERR("%s: mi2s GPIO config failed for %s\n", - __func__, snddev_mi2s_data->name); - goto mi2s_data_gpio_failure; - } - MM_DBG("%s: done data line gpio config for %s\n", - __func__, snddev_mi2s_data->name); - - rc = snddev_mi2s_open_tx(dev_info); - - if (IS_ERR_VALUE(rc)) { - MM_ERR(" snddev_mi2s_open_tx failed \n"); - goto mi2s_cleanup_open; - } - - drv->sd_lines_used |= snddev_mi2s_data->sd_lines; - MM_DBG("%s: sd_lines_used = 0x%x\n", __func__, - drv->sd_lines_used); - mutex_unlock(&drv->lock); - } - - return 0; - -mi2s_cleanup_open: - mi2s_unconfig_data_gpio(dir, snddev_mi2s_data->sd_lines); - - /* Disable audio path */ - if (snddev_mi2s_data->deroute) - snddev_mi2s_data->deroute(); - -mi2s_data_gpio_failure: - if (!drv->sd_lines_used) { - clk_disable_unprepare(drv->sclk); - clk_disable_unprepare(drv->mclk); - drv->clocks_enabled = 0; - mi2s_unconfig_clk_gpio(); - } - mutex_unlock(&drv->lock); - return rc; -} - -static int snddev_mi2s_close(struct msm_snddev_info *dev_info) -{ - struct snddev_mi2s_drv_state *drv = &snddev_mi2s_drv; - int dir; - struct snddev_mi2s_data *snddev_mi2s_data = dev_info->private_data; - - if (!dev_info) { - MM_ERR("%s: msm_snddev_info is null \n", __func__); - return -EINVAL; - } - - if (!dev_info->opened) { - MM_ERR(" %s: calling close device with out opening the" - " device \n", __func__); - return -EIO; - } - - mutex_lock(&drv->lock); - - drv->sd_lines_used &= ~snddev_mi2s_data->sd_lines; - - MM_DBG("%s: sd_lines in use = 0x%x\n", __func__, drv->sd_lines_used); - - if (snddev_mi2s_data->capability & SNDDEV_CAP_RX) { - dir = DIR_RX; - afe_disable(AFE_HW_PATH_MI2S_RX); - } else { - dir = DIR_TX; - afe_disable(AFE_HW_PATH_MI2S_TX); - } - - mi2s_unconfig_data_gpio(dir, snddev_mi2s_data->sd_lines); - - if (!drv->sd_lines_used) { - clk_disable_unprepare(drv->sclk); - clk_disable_unprepare(drv->mclk); - drv->clocks_enabled = 0; - mi2s_unconfig_clk_gpio(); - } - - /* Disable audio path */ - if (snddev_mi2s_data->deroute) - snddev_mi2s_data->deroute(); - - mutex_unlock(&drv->lock); - - return 0; -} - -static int snddev_mi2s_set_freq(struct msm_snddev_info *dev_info, u32 req_freq) -{ - if (req_freq != 48000) { - MM_DBG("%s: Unsupported Frequency:%d\n", __func__, req_freq); - return -EINVAL; - } - return 48000; -} - -static int snddev_mi2s_probe(struct platform_device *pdev) -{ - int rc = 0; - struct snddev_mi2s_data *pdata; - struct msm_snddev_info *dev_info; - - if (!pdev || !pdev->dev.platform_data) { - printk(KERN_ALERT "Invalid caller \n"); - return -ENODEV; - } - - pdata = pdev->dev.platform_data; - if ((pdata->capability & SNDDEV_CAP_RX) && - (pdata->capability & SNDDEV_CAP_TX)) { - MM_ERR("%s: invalid device data either RX or TX\n", __func__); - return -ENODEV; - } - - dev_info = kzalloc(sizeof(struct msm_snddev_info), GFP_KERNEL); - if (!dev_info) { - MM_ERR("%s: uneable to allocate memeory for msm_snddev_info \n", - __func__); - - return -ENOMEM; - } - - dev_info->name = pdata->name; - dev_info->copp_id = pdata->copp_id; - dev_info->acdb_id = pdata->acdb_id; - dev_info->private_data = (void *)pdata; - dev_info->dev_ops.open = snddev_mi2s_open; - dev_info->dev_ops.close = snddev_mi2s_close; - dev_info->dev_ops.set_freq = snddev_mi2s_set_freq; - dev_info->capability = pdata->capability; - dev_info->opened = 0; - msm_snddev_register(dev_info); - dev_info->sample_rate = pdata->default_sample_rate; - - MM_DBG("%s: probe done for %s\n", __func__, pdata->name); - return rc; -} - -static int snddev_mi2s_remove(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_driver snddev_mi2s_driver = { - .probe = snddev_mi2s_probe, - .remove = snddev_mi2s_remove, - .driver = {.name = "snddev_mi2s"} -}; - -static int __init snddev_mi2s_init(void) -{ - s32 rc; - struct snddev_mi2s_drv_state *drv = &snddev_mi2s_drv; - - rc = platform_driver_register(&snddev_mi2s_driver); - if (IS_ERR_VALUE(rc)) { - - MM_ERR("%s: platform_driver_register failed \n", __func__); - goto error_platform_driver; - } - - drv->mclk = clk_get(NULL, "mi2s_m_clk"); - if (IS_ERR(drv->mclk)) { - MM_ERR("%s: clk_get mi2s_mclk failed \n", __func__); - goto error_mclk; - } - - drv->sclk = clk_get(NULL, "mi2s_s_clk"); - if (IS_ERR(drv->sclk)) { - MM_ERR("%s: clk_get mi2s_sclk failed \n", __func__); - - goto error_sclk; - } - - mutex_init(&drv->lock); - - MM_DBG("snddev_mi2s_init : done \n"); - - return 0; - -error_sclk: - clk_put(drv->mclk); -error_mclk: - platform_driver_unregister(&snddev_mi2s_driver); -error_platform_driver: - - MM_ERR("%s: encounter error\n", __func__); - return -ENODEV; -} - -static void __exit snddev_mi2s_exit(void) -{ - struct snddev_mi2s_drv_state *drv = &snddev_mi2s_drv; - - platform_driver_unregister(&snddev_mi2s_driver); - - clk_put(drv->sclk); - clk_put(drv->mclk); - return; -} - -module_init(snddev_mi2s_init); -module_exit(snddev_mi2s_exit); - -MODULE_DESCRIPTION("mi2s Sound Device driver"); -MODULE_VERSION("1.0"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5v2/snddev_virtual.c b/arch/arm/mach-msm/qdsp5v2/snddev_virtual.c deleted file mode 100644 index aa1d55780114276d7f2809b3b45780615cf0b537..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/snddev_virtual.c +++ /dev/null @@ -1,122 +0,0 @@ -/* Copyright (c) 2010, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -static int snddev_virtual_open(struct msm_snddev_info *dev_info) -{ - int rc = 0; - - if (!dev_info) - rc = -EINVAL; - return rc; -} - -static int snddev_virtual_close(struct msm_snddev_info *dev_info) -{ - int rc = 0; - - if (!dev_info) - rc = -EINVAL; - return rc; -} - -static int snddev_virtual_set_freq(struct msm_snddev_info *dev_info, u32 rate) -{ - int rc = 0; - - if (!dev_info) - rc = -EINVAL; - return rate; -} - -static int snddev_virtual_probe(struct platform_device *pdev) -{ - int rc = 0; - struct snddev_virtual_data *pdata; - struct msm_snddev_info *dev_info; - - if (!pdev || !pdev->dev.platform_data) { - MM_ERR("Invalid caller\n"); - rc = -EPERM; - goto error; - } - pdata = pdev->dev.platform_data; - - dev_info = kmalloc(sizeof(struct msm_snddev_info), GFP_KERNEL); - if (!dev_info) { - rc = -ENOMEM; - goto error; - } - - dev_info->name = pdata->name; - dev_info->copp_id = pdata->copp_id; - dev_info->acdb_id = pdata->acdb_id; - dev_info->private_data = (void *) NULL; - dev_info->dev_ops.open = snddev_virtual_open; - dev_info->dev_ops.close = snddev_virtual_close; - dev_info->dev_ops.set_freq = snddev_virtual_set_freq; - dev_info->capability = pdata->capability; - dev_info->sample_rate = 8000; - dev_info->opened = 0; - dev_info->sessions = 0; - - msm_snddev_register(dev_info); - -error: - return rc; -} - -static int snddev_virtual_remove(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_driver snddev_virtual_driver = { - .probe = snddev_virtual_probe, - .remove = snddev_virtual_remove, - .driver = { .name = "snddev_virtual" } -}; - -static int __init snddev_virtual_init(void) -{ - int rc = 0; - - MM_DBG(" snddev_virtual_init \n"); - rc = platform_driver_register(&snddev_virtual_driver); - if (IS_ERR_VALUE(rc)) { - MM_ERR("platform driver register failure\n"); - return -ENODEV; - } - return 0; -} - -static void __exit snddev_virtual_exit(void) -{ - platform_driver_unregister(&snddev_virtual_driver); - - return; -} - -module_init(snddev_virtual_init); -module_exit(snddev_virtual_exit); - -MODULE_DESCRIPTION("Virtual Sound Device driver"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-msm/qdsp5v2/timpani_profile_7x30.h b/arch/arm/mach-msm/qdsp5v2/timpani_profile_7x30.h deleted file mode 100644 index e4cf1313ef72202068bdcab7a9bb1906977e5456..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/timpani_profile_7x30.h +++ /dev/null @@ -1,623 +0,0 @@ -/* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __MACH_QDSP5_V2_TIMPANI_PROFILE_H__ -#define __MACH_QDSP5_V2_MTIMPANI_PROFILE_H__ - -/* - * TX Device Profiles - */ - -/* Analog MIC */ -/* AMIC Primary mono */ -#define AMIC_PRI_MONO_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x05, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x0C, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x87, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xF0)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xFF, 0xD0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xFF, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xFF, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xFF, 0x65)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xFF, 0x1E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xA3, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x93, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x94, 0xFF, 0x1B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x99, 0x0F, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x9F, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x04, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8b, 0xff, 0xE6)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8c, 0x03, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x87, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xC0)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xF0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x0C, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xFF, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xAB, 0x09, 0x09)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -/* Headset MIC */ -#define AMIC1_HEADSET_TX_MONO_PRIMARY_OSR256 \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x05, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x0C, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x87, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xF0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xFF, 0x1E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xA3, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x93, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x94, 0xFF, 0x1B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x99, 0x0F, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x9F, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xFF, 0xC8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xFF, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xFF, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xFF, 0x65)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8 }, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x04, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8b, 0xff, 0xE7)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8c, 0x03, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x87, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xC0)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xF0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x0C, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xFF, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xFF, 0x00)} } - -/* - * RX Device Profiles - */ - -/* RX EAR */ -#define EAR_PRI_MONO_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x03, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x0F)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xA3, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x97, 0xFF, 0x01)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0xFF, 0x4C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x0E)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0x03, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x39, 0x01, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -/* RX SPEAKER */ -#define SPEAKER_PRI_STEREO_48000_OSR_256 \ - {{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x03, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xA3, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x0C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x6C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xB7, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x32, 0xF8, 0x08)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x1388}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x32, 0xF8, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x1388}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x32, 0xF8, 0xF8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0x24, 0x24)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0x10)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x32, 0xF8, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0x05, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0x24, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} }; - -/* - * RX HPH PRIMARY - */ - -/* RX HPH CLASS AB CAPLESS */ - -#define HEADSET_AB_CPLS_48000_OSR_256 \ - {{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x03, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xA3, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x0C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x6C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xB7, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFF, 0x55)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4C, 0xFF, 0x29)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xBB8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFF, 0xF5)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4C, 0xFE, 0xC8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0x27, 0x24)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x04)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -/* AMIC dual */ -#define AMIC_DUAL_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x05, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x0C, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x87, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xF0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xFF, 0x1E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xA3, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x93, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x94, 0xFF, 0x1B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x99, 0x0F, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x9F, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xFF, 0xD0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0E, 0xFF, 0xC2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xFF, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xFF, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xFF, 0x65)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8 }, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x0C, 0x0C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8b, 0xff, 0xCE)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xB4, 0xFF, 0xCE)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8c, 0xFF, 0x5A)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x87, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xC0)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xF0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x0C, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0E, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xFF, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -/* TTY RX */ -#define TTY_HEADSET_MONO_RX_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x03, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xA3, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x97, 0xFF, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x06)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x03, 0x01)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x4C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xB7, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFF, 0x45)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4C, 0xFF, 0x29)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xBB8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFF, 0xC5)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4C, 0xFE, 0xC8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0x27, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x04)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -/* TTY TX */ -#define TTY_HEADSET_MONO_TX_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x05, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x0C, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x87, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xF0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0xFF, 0x1E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xA3, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x93, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x94, 0xFF, 0x1B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x99, 0x0F, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x9F, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xFF, 0xA8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xFF, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xFF, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xFF, 0x65)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xBB8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x04, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x87, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xC0)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xF0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x0C, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x0D, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x14, 0xFF, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x11, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x12, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_RX_CAPLESS_48000_OSR_256 \ - {{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x4e)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x04, 0xff, 0xBC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x64)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x25, 0x0F, 0x0B)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xfc, 0xfc)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xff, 0xa2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0xFF, 0xab)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x80)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0xf0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x23, 0xff, 0x20)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3B, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xff, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0f, 0x0c)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8a, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3b, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3c, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x34, 0xf0, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x80, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HEADSET_STEREO_SPEAKER_STEREO_RX_CAPLESS_48000_OSR_256 \ - {{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x03, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xA3, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x0C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x6C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xB7, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFF, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFF, 0x55)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x32, 0xF8, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4C, 0xFF, 0x29)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x1388}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFF, 0xF5)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x32, 0xF8, 0x48)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x1388}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x32, 0xF8, 0xF8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0x24, 0x24)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0x27, 0x24)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x04)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x32, 0xF8, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0x24, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HS_DMIC2_STEREO_8000_OSR_256 \ - {{ADIE_CODEC_ACTION_DELAY_WAIT, 0xbb8 }, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x05, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x05, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x0C, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x87, 0xFF, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xF0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x82, 0x1F, 0x1E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x0C, 0x0C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x92, 0x3F, 0x19)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x94, 0x3F, 0x24)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xA3, 0x39, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xA8, 0x0F, 0x0E)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xAB, 0x3F, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x86, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x87, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xC0)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0xF0, 0xF0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0xC0, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x92, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x94, 0xFF, 0x1B)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HPH_PRI_AB_LEG_STEREO \ - {{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x03, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xA3, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x0C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0E)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x6C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xB7, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFF, 0x09)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFF, 0x59)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0x186A0}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFF, 0xF9)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0x27, 0x27)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x10)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define HPH_PRI_D_LEG_STEREO \ - {{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x80, 0x02, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x03, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xA3, 0x02, 0x02)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x84, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x85, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x0C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x81, 0xFF, 0x0E)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x83, 0x03, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x21, 0xFF, 0x60)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x22, 0xFF, 0xE1)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x24, 0x6F, 0x6C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x26, 0xFF, 0xD0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2D, 0xFF, 0x6F)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2E, 0xFF, 0x55)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xB7, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3F, 0xFF, 0x0F)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x40, 0xFF, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x41, 0x08, 0x08)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x42, 0xFF, 0xBB)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x43, 0xFF, 0xF2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x44, 0xF7, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x45, 0xFF, 0xFF)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x46, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x47, 0xFF, 0xF2)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x48, 0xF7, 0x37)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x49, 0xFF, 0xFF)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4A, 0xFF, 0x77)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFF, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0x8C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x0F, 0x0A)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 300000}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x0F, 0x0F)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x04)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3E, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x0F, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define LB_AUXPGA_HPH_AB_CPLS_STEREO \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2F, 0xFF, 0x44)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x30, 0xFF, 0x92)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFD, 0x05)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFD, 0x55)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x30, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xFF, 0xAA)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xBB8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFD, 0xF5)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xB7, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x4C, 0xFF, 0x29)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0x90, 0x90)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x04)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x04)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE2, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE3, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0x30, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3C, 0xFF, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0xFD, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#define LB_AUXPGA_LO_STEREO \ - {{ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x2F, 0xFF, 0x44)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x30, 0xFF, 0x92)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x32, 0xF8, 0x08)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xBB8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x32, 0xF8, 0x58)}, \ - {ADIE_CODEC_ACTION_DELAY_WAIT, 0xBB8}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x32, 0xF8, 0xF8)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0xF0, 0xF0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x38, 0xFF, 0xAA)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0x90, 0x90)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0xF0, 0x30)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xB7, 0x01, 0x01)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0x10)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0x10)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_ANALOG_READY}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0xF0, 0xF0)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x8A, 0x0F, 0x03)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0x1C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0x3C)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFC, 0xAC)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x33, 0xF0, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x32, 0xF8, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x31, 0x01, 0x00)}, \ - {ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0x90, 0x00)}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_ANALOG_OFF}, \ - {ADIE_CODEC_ACTION_STAGE_REACHED, ADIE_CODEC_DIGITAL_OFF} } - -#endif diff --git a/arch/arm/mach-msm/qdsp5v2/voice.c b/arch/arm/mach-msm/qdsp5v2/voice.c deleted file mode 100644 index 1ac79d463e428e65872f33efeb45d625bd656146..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp5v2/voice.c +++ /dev/null @@ -1,752 +0,0 @@ -/* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct voice_data { - void *handle; /* DALRPC handle */ - void *cb_handle; /* DALRPC callback handle */ - int network; /* Network information */ - int dev_state;/*READY, CHANGE, REL_DONE,INIT*/ - int voc_state;/*INIT, CHANGE, RELEASE, ACQUIRE */ - struct mutex voc_lock; - struct mutex vol_lock; - int voc_event; - int dev_event; - atomic_t rel_start_flag; - atomic_t acq_start_flag; - atomic_t chg_start_flag; - struct task_struct *task; - struct completion complete; - wait_queue_head_t dev_wait; - wait_queue_head_t voc_wait; - uint32_t device_events; - /* cache the values related to Rx and Tx */ - struct device_data dev_rx; - struct device_data dev_tx; - /* these default values are for all devices */ - uint32_t default_mute_val; - uint32_t default_vol_val; - uint32_t default_sample_val; - /* call status */ - int v_call_status; /* Start or End */ - s32 max_rx_vol[VOC_RX_VOL_ARRAY_NUM]; /* [0] is for NB, [1] for WB */ - s32 min_rx_vol[VOC_RX_VOL_ARRAY_NUM]; -}; - -static struct voice_data voice; - -static int voice_cmd_device_info(struct voice_data *); -static int voice_cmd_acquire_done(struct voice_data *); -static void voice_auddev_cb_function(u32 evt_id, - union auddev_evt_data *evt_payload, - void *private_data); - -static int voice_cmd_change(void) -{ - - struct voice_header hdr; - struct voice_data *v = &voice; - int err; - - hdr.id = CMD_DEVICE_CHANGE; - hdr.data_len = 0; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - err = dalrpc_fcn_5(VOICE_DALRPC_CMD, v->handle, &hdr, - sizeof(struct voice_header)); - - if (err) - MM_ERR("Voice change command failed\n"); - return err; -} - -static void voice_auddev_cb_function(u32 evt_id, - union auddev_evt_data *evt_payload, - void *private_data) -{ - struct voice_data *v = &voice; - int rc = 0, i; - - MM_INFO("auddev_cb_function, evt_id=%d, dev_state=%d, voc_state=%d\n", - evt_id, v->dev_state, v->voc_state); - if ((evt_id != AUDDEV_EVT_START_VOICE) || - (evt_id != AUDDEV_EVT_END_VOICE)) { - if (evt_payload == NULL) { - MM_ERR(" evt_payload is NULL pointer\n"); - return; - } - } - switch (evt_id) { - case AUDDEV_EVT_START_VOICE: - if ((v->dev_state == DEV_INIT) || - (v->dev_state == DEV_REL_DONE)) { - v->v_call_status = VOICE_CALL_START; - if ((v->dev_rx.enabled == VOICE_DEV_ENABLED) - && (v->dev_tx.enabled == VOICE_DEV_ENABLED)) { - v->dev_state = DEV_READY; - MM_DBG("dev_state into ready\n"); - wake_up(&v->dev_wait); - } - if (v->voc_state == VOICE_CHANGE) { - MM_DBG("voc_state is in VOICE_CHANGE\n"); - v->voc_state = VOICE_ACQUIRE; - } - } - break; - case AUDDEV_EVT_DEV_CHG_VOICE: - if (v->dev_state == DEV_READY) { - v->dev_rx.enabled = VOICE_DEV_DISABLED; - v->dev_tx.enabled = VOICE_DEV_DISABLED; - v->dev_state = DEV_CHANGE; - mutex_lock(&voice.voc_lock); - if (v->voc_state == VOICE_ACQUIRE) { - /* send device change to modem */ - voice_cmd_change(); - mutex_unlock(&voice.voc_lock); - msm_snddev_enable_sidetone(v->dev_rx.dev_id, - 0); - /* block to wait for CHANGE_START */ - rc = wait_event_interruptible( - v->voc_wait, (v->voc_state == VOICE_CHANGE) - || (atomic_read(&v->chg_start_flag) == 1) - || (atomic_read(&v->rel_start_flag) == 1)); - } else { - mutex_unlock(&voice.voc_lock); - MM_ERR(" Voice is not at ACQUIRE state\n"); - } - } else if ((v->dev_state == DEV_INIT) || - (v->dev_state == DEV_REL_DONE)) { - v->dev_rx.enabled = VOICE_DEV_DISABLED; - v->dev_tx.enabled = VOICE_DEV_DISABLED; - } else - MM_ERR(" device is not at proper state\n"); - break; - case AUDDEV_EVT_DEV_RDY: - /* update the dev info */ - if (evt_payload->voc_devinfo.dev_type == DIR_RX) { - for (i = 0; i < VOC_RX_VOL_ARRAY_NUM; i++) { - v->max_rx_vol[i] = - evt_payload->voc_devinfo.max_rx_vol[i]; - v->min_rx_vol[i] = - evt_payload->voc_devinfo.min_rx_vol[i]; - } - } - if (v->dev_state == DEV_CHANGE) { - if (evt_payload->voc_devinfo.dev_type == DIR_RX) { - v->dev_rx.dev_acdb_id = - evt_payload->voc_devinfo.acdb_dev_id; - v->dev_rx.sample = - evt_payload->voc_devinfo.dev_sample; - v->dev_rx.dev_id = - evt_payload->voc_devinfo.dev_id; - v->dev_rx.enabled = VOICE_DEV_ENABLED; - } else { - v->dev_tx.dev_acdb_id = - evt_payload->voc_devinfo.acdb_dev_id; - v->dev_tx.sample = - evt_payload->voc_devinfo.dev_sample; - v->dev_tx.enabled = VOICE_DEV_ENABLED; - v->dev_tx.dev_id = - evt_payload->voc_devinfo.dev_id; - } - if ((v->dev_rx.enabled == VOICE_DEV_ENABLED) && - (v->dev_tx.enabled == VOICE_DEV_ENABLED)) { - v->dev_state = DEV_READY; - MM_DBG("dev state into ready\n"); - voice_cmd_device_info(v); - wake_up(&v->dev_wait); - mutex_lock(&voice.voc_lock); - if (v->voc_state == VOICE_CHANGE) { - v->dev_event = DEV_CHANGE_READY; - complete(&v->complete); - } - mutex_unlock(&voice.voc_lock); - } - } else if ((v->dev_state == DEV_INIT) || - (v->dev_state == DEV_REL_DONE)) { - if (evt_payload->voc_devinfo.dev_type == DIR_RX) { - v->dev_rx.dev_acdb_id = - evt_payload->voc_devinfo.acdb_dev_id; - v->dev_rx.sample = - evt_payload->voc_devinfo.dev_sample; - v->dev_rx.dev_id = - evt_payload->voc_devinfo.dev_id; - v->dev_rx.enabled = VOICE_DEV_ENABLED; - } else { - v->dev_tx.dev_acdb_id = - evt_payload->voc_devinfo.acdb_dev_id; - v->dev_tx.sample = - evt_payload->voc_devinfo.dev_sample; - v->dev_tx.dev_id = - evt_payload->voc_devinfo.dev_id; - v->dev_tx.enabled = VOICE_DEV_ENABLED; - } - if ((v->dev_rx.enabled == VOICE_DEV_ENABLED) && - (v->dev_tx.enabled == VOICE_DEV_ENABLED) && - (v->v_call_status == VOICE_CALL_START)) { - v->dev_state = DEV_READY; - MM_DBG("dev state into ready\n"); - voice_cmd_device_info(v); - wake_up(&v->dev_wait); - mutex_lock(&voice.voc_lock); - if (v->voc_state == VOICE_CHANGE) { - v->dev_event = DEV_CHANGE_READY; - complete(&v->complete); - } - mutex_unlock(&voice.voc_lock); - } - } else - MM_ERR("Receive READY not at the proper state =%d\n", - v->dev_state); - break; - case AUDDEV_EVT_DEVICE_VOL_MUTE_CHG: - if (evt_payload->voc_devinfo.dev_type == DIR_TX) - v->dev_tx.mute = - evt_payload->voc_vm_info.dev_vm_val.mute; - else - v->dev_rx.volume = evt_payload-> - voc_vm_info.dev_vm_val.vol; - /* send device info */ - voice_cmd_device_info(v); - break; - case AUDDEV_EVT_REL_PENDING: - /* recover the tx mute and rx volume to the default values */ - if (v->dev_state == DEV_READY) { - if (atomic_read(&v->rel_start_flag)) { - atomic_dec(&v->rel_start_flag); - if (evt_payload->voc_devinfo.dev_type == DIR_RX) - v->dev_rx.enabled = VOICE_DEV_DISABLED; - else - v->dev_tx.enabled = VOICE_DEV_DISABLED; - v->dev_state = DEV_REL_DONE; - wake_up(&v->dev_wait); - break; - } - mutex_lock(&voice.voc_lock); - if ((v->voc_state == VOICE_RELEASE) || - (v->voc_state == VOICE_INIT)) { - if (evt_payload->voc_devinfo.dev_type - == DIR_RX) { - v->dev_rx.enabled = VOICE_DEV_DISABLED; - } else { - v->dev_tx.enabled = VOICE_DEV_DISABLED; - } - v->dev_state = DEV_REL_DONE; - mutex_unlock(&voice.voc_lock); - wake_up(&v->dev_wait); - } else { - /* send device change to modem */ - voice_cmd_change(); - mutex_unlock(&voice.voc_lock); - rc = wait_event_interruptible( - v->voc_wait, (v->voc_state == VOICE_CHANGE) - || (atomic_read(&v->chg_start_flag) == 1) - || (atomic_read(&v->rel_start_flag) == 1)); - if (atomic_read(&v->rel_start_flag) == 1) - atomic_dec(&v->rel_start_flag); - /* clear Rx/Tx to Disable */ - if (evt_payload->voc_devinfo.dev_type == DIR_RX) - v->dev_rx.enabled = VOICE_DEV_DISABLED; - else - v->dev_tx.enabled = VOICE_DEV_DISABLED; - v->dev_state = DEV_REL_DONE; - wake_up(&v->dev_wait); - } - } else if ((v->dev_state == DEV_INIT) || - (v->dev_state == DEV_REL_DONE)) { - if (evt_payload->voc_devinfo.dev_type == DIR_RX) - v->dev_rx.enabled = VOICE_DEV_DISABLED; - else - v->dev_tx.enabled = VOICE_DEV_DISABLED; - } - break; - case AUDDEV_EVT_END_VOICE: - /* recover the tx mute and rx volume to the default values */ - v->dev_tx.mute = v->default_mute_val; - v->dev_rx.volume = v->default_vol_val; - - if (v->dev_rx.enabled == VOICE_DEV_ENABLED) - msm_snddev_enable_sidetone(v->dev_rx.dev_id, 0); - - if ((v->dev_state == DEV_READY) || - (v->dev_state == DEV_CHANGE)) { - if (atomic_read(&v->rel_start_flag)) { - atomic_dec(&v->rel_start_flag); - v->v_call_status = VOICE_CALL_END; - v->dev_state = DEV_REL_DONE; - wake_up(&v->dev_wait); - break; - } - mutex_lock(&voice.voc_lock); - if ((v->voc_state == VOICE_RELEASE) || - (v->voc_state == VOICE_INIT)) { - v->v_call_status = VOICE_CALL_END; - v->dev_state = DEV_REL_DONE; - mutex_unlock(&voice.voc_lock); - wake_up(&v->dev_wait); - } else { - /* send mute and default volume value to MCAD */ - voice_cmd_device_info(v); - /* send device change to modem */ - voice_cmd_change(); - mutex_unlock(&voice.voc_lock); - /* block to wait for RELEASE_START - or CHANGE_START */ - rc = wait_event_interruptible( - v->voc_wait, (v->voc_state == VOICE_CHANGE) - || (atomic_read(&v->chg_start_flag) == 1) - || (atomic_read(&v->rel_start_flag) == 1)); - if (atomic_read(&v->rel_start_flag) == 1) - atomic_dec(&v->rel_start_flag); - /* set voice call to END state */ - v->v_call_status = VOICE_CALL_END; - v->dev_state = DEV_REL_DONE; - wake_up(&v->dev_wait); - } - } else - v->v_call_status = VOICE_CALL_END; - break; - case AUDDEV_EVT_FREQ_CHG: - MM_DBG("Voice Driver got sample rate change Event\n"); - MM_DBG("sample rate %d\n", evt_payload->freq_info.sample_rate); - MM_DBG("dev_type %d\n", evt_payload->freq_info.dev_type); - MM_DBG("acdb_dev_id %d\n", evt_payload->freq_info.acdb_dev_id); - if (v->dev_state == DEV_READY) { - v->dev_tx.enabled = VOICE_DEV_DISABLED; - v->dev_state = DEV_CHANGE; - mutex_lock(&voice.voc_lock); - if (v->voc_state == VOICE_ACQUIRE) { - msm_snddev_enable_sidetone(v->dev_rx.dev_id, - 0); - /* send device change to modem */ - voice_cmd_change(); - mutex_unlock(&voice.voc_lock); - /* block to wait for CHANGE_START */ - rc = wait_event_interruptible( - v->voc_wait, (v->voc_state == VOICE_CHANGE) - || (atomic_read(&v->chg_start_flag) == 1) - || (atomic_read(&v->rel_start_flag) == 1)); - } else { - mutex_unlock(&voice.voc_lock); - MM_ERR(" Voice is not at ACQUIRE state\n"); - } - } else if ((v->dev_state == DEV_INIT) || - (v->dev_state == DEV_REL_DONE)) { - v->dev_tx.enabled = VOICE_DEV_DISABLED; - } else - MM_ERR("Event not at the proper state =%d\n", - v->dev_state); - break; - default: - MM_ERR("UNKNOWN EVENT\n"); - } - return; -} -EXPORT_SYMBOL(voice_auddev_cb_function); - -static void remote_cb_function(void *context, u32 param, - void *evt_buf, u32 len) -{ - struct voice_header *hdr; - struct voice_data *v = context; - - hdr = (struct voice_header *)evt_buf; - - MM_INFO("len=%d id=%d\n", len, hdr->id); - - if (len <= 0) { - MM_ERR("unexpected event with length %d \n", len); - return; - } - - switch (hdr->id) { - case EVENT_ACQUIRE_START: - atomic_inc(&v->acq_start_flag); - wake_up(&v->dev_wait); - v->voc_event = VOICE_ACQUIRE_START; - v->network = ((struct voice_network *)evt_buf)->network_info; - complete(&v->complete); - break; - case EVENT_RELEASE_START: - /* If ACQUIRED come in before the RELEASE, - * will only services the RELEASE */ - atomic_inc(&v->rel_start_flag); - wake_up(&v->voc_wait); - wake_up(&v->dev_wait); - v->voc_event = VOICE_RELEASE_START; - complete(&v->complete); - break; - case EVENT_CHANGE_START: - atomic_inc(&v->chg_start_flag); - wake_up(&v->voc_wait); - v->voc_event = VOICE_CHANGE_START; - complete(&v->complete); - break; - case EVENT_NETWORK_RECONFIG: - /* send network change to audio_dev, - if sample rate is less than 16k, - otherwise, send acquire done */ - v->voc_event = VOICE_NETWORK_RECONFIG; - v->network = ((struct voice_network *)evt_buf)->network_info; - complete(&v->complete); - break; - default: - MM_ERR("Undefined event %d \n", hdr->id); - } - -} - -static int voice_cmd_init(struct voice_data *v) -{ - - struct voice_init cmd; - int err; - - MM_DBG("\n"); /* Macro prints the file name and function */ - - cmd.hdr.id = CMD_VOICE_INIT; - cmd.hdr.data_len = sizeof(struct voice_init) - - sizeof(struct voice_header); - cmd.cb_handle = v->cb_handle; - - err = dalrpc_fcn_5(VOICE_DALRPC_CMD, v->handle, &cmd, - sizeof(struct voice_init)); - - if (err) - MM_ERR("Voice init command failed\n"); - return err; -} - -static int voice_cmd_acquire_done(struct voice_data *v) -{ - struct voice_header hdr; - int err; - - hdr.id = CMD_ACQUIRE_DONE; - hdr.data_len = 0; - - MM_INFO("\n"); /* Macro prints the file name and function */ - - /* Enable HW sidetone if device supports it */ - msm_snddev_enable_sidetone(v->dev_rx.dev_id, 1); - - err = dalrpc_fcn_5(VOICE_DALRPC_CMD, v->handle, &hdr, - sizeof(struct voice_header)); - - if (err) - MM_ERR("Voice acquire done command failed\n"); - return err; -} - -static int voice_cmd_device_info(struct voice_data *v) -{ - struct voice_device cmd; - int err, vol; - - MM_INFO("tx_dev=%d, rx_dev=%d, tx_sample=%d, tx_mute=%d\n", - v->dev_tx.dev_acdb_id, v->dev_rx.dev_acdb_id, - v->dev_tx.sample, v->dev_tx.mute); - - mutex_lock(&voice.vol_lock); - - cmd.hdr.id = CMD_DEVICE_INFO; - cmd.hdr.data_len = sizeof(struct voice_device) - - sizeof(struct voice_header); - cmd.tx_device = v->dev_tx.dev_acdb_id; - cmd.rx_device = v->dev_rx.dev_acdb_id; - if (v->network == NETWORK_WCDMA_WB) - vol = v->min_rx_vol[VOC_WB_INDEX] + - ((v->max_rx_vol[VOC_WB_INDEX] - - v->min_rx_vol[VOC_WB_INDEX]) * v->dev_rx.volume)/100; - else - vol = v->min_rx_vol[VOC_NB_INDEX] + - ((v->max_rx_vol[VOC_NB_INDEX] - - v->min_rx_vol[VOC_NB_INDEX]) * v->dev_rx.volume)/100; - cmd.rx_volume = (u32)vol; /* in mb */ - cmd.rx_mute = 0; - cmd.tx_mute = v->dev_tx.mute; - cmd.rx_sample = v->dev_rx.sample/1000; - cmd.tx_sample = v->dev_tx.sample/1000; - - MM_DBG("rx_vol=%d, rx_sample=%d\n", cmd.rx_volume, v->dev_rx.sample); - - err = dalrpc_fcn_5(VOICE_DALRPC_CMD, v->handle, &cmd, - sizeof(struct voice_device)); - - mutex_unlock(&voice.vol_lock); - - if (err) - MM_ERR("Voice device command failed\n"); - return err; -} -EXPORT_SYMBOL(voice_cmd_device_info); - -void voice_change_sample_rate(struct voice_data *v) -{ - int freq = 48000; - int rc = 0; - - MM_DBG("network =%d, vote freq=%d\n", v->network, freq); - if (freq != v->dev_tx.sample) { - rc = msm_snddev_request_freq(&freq, 0, - SNDDEV_CAP_TX, AUDDEV_CLNT_VOC); - if (rc >= 0) { - v->dev_tx.sample = freq; - MM_DBG(" vote for freq=%d successfully \n", freq); - } else - MM_ERR(" voting for freq=%d failed.\n", freq); - } -} - -static int voice_thread(void *data) -{ - struct voice_data *v = (struct voice_data *)data; - int rc = 0; - - MM_INFO("voice_thread() start\n"); - - while (!kthread_should_stop()) { - wait_for_completion(&v->complete); - init_completion(&v->complete); - - MM_DBG(" voc_event=%d, voice state =%d, dev_event=%d\n", - v->voc_event, v->voc_state, v->dev_event); - switch (v->voc_event) { - case VOICE_ACQUIRE_START: - /* check if dev_state = READY */ - /* if ready, send device_info and acquire_done */ - /* if not ready, block to wait the dev_state = READY */ - if ((v->voc_state == VOICE_INIT) || - (v->voc_state == VOICE_RELEASE)) { - if (v->dev_state == DEV_READY) { - mutex_lock(&voice.voc_lock); - voice_change_sample_rate(v); - rc = voice_cmd_device_info(v); - rc = voice_cmd_acquire_done(v); - v->voc_state = VOICE_ACQUIRE; - mutex_unlock(&voice.voc_lock); - broadcast_event( - AUDDEV_EVT_VOICE_STATE_CHG, - VOICE_STATE_INCALL, SESSION_IGNORE); - } else { - rc = wait_event_interruptible( - v->dev_wait, - (v->dev_state == DEV_READY) - || (atomic_read(&v->rel_start_flag) - == 1)); - if (atomic_read(&v->rel_start_flag) - == 1) { - v->voc_state = VOICE_RELEASE; - atomic_dec(&v->rel_start_flag); - msm_snddev_withdraw_freq(0, - SNDDEV_CAP_TX, AUDDEV_CLNT_VOC); - broadcast_event( - AUDDEV_EVT_VOICE_STATE_CHG, - VOICE_STATE_OFFCALL, - SESSION_IGNORE); - } else { - mutex_lock(&voice.voc_lock); - voice_change_sample_rate(v); - rc = voice_cmd_device_info(v); - rc = voice_cmd_acquire_done(v); - v->voc_state = VOICE_ACQUIRE; - mutex_unlock(&voice.voc_lock); - broadcast_event( - AUDDEV_EVT_VOICE_STATE_CHG, - VOICE_STATE_INCALL, - SESSION_IGNORE); - } - } - } else - MM_ERR("Get this event at the wrong state\n"); - if (atomic_read(&v->acq_start_flag)) - atomic_dec(&v->acq_start_flag); - break; - case VOICE_RELEASE_START: - MM_DBG("broadcast voice call end\n"); - broadcast_event(AUDDEV_EVT_VOICE_STATE_CHG, - VOICE_STATE_OFFCALL, SESSION_IGNORE); - if ((v->dev_state == DEV_REL_DONE) || - (v->dev_state == DEV_INIT)) { - v->voc_state = VOICE_RELEASE; - msm_snddev_withdraw_freq(0, SNDDEV_CAP_TX, - AUDDEV_CLNT_VOC); - } else { - /* wait for the dev_state = RELEASE */ - rc = wait_event_interruptible(v->dev_wait, - (v->dev_state == DEV_REL_DONE) - || (atomic_read(&v->acq_start_flag) == 1)); - if (atomic_read(&v->acq_start_flag) == 1) - atomic_dec(&v->acq_start_flag); - v->voc_state = VOICE_RELEASE; - msm_snddev_withdraw_freq(0, SNDDEV_CAP_TX, - AUDDEV_CLNT_VOC); - } - if (atomic_read(&v->rel_start_flag)) - atomic_dec(&v->rel_start_flag); - break; - case VOICE_CHANGE_START: - if (v->voc_state == VOICE_ACQUIRE) - v->voc_state = VOICE_CHANGE; - else - MM_ERR("Get this event at the wrong state\n"); - wake_up(&v->voc_wait); - if (atomic_read(&v->chg_start_flag)) - atomic_dec(&v->chg_start_flag); - break; - case VOICE_NETWORK_RECONFIG: - if ((v->voc_state == VOICE_ACQUIRE) - || (v->voc_state == VOICE_CHANGE)) { - voice_change_sample_rate(v); - rc = voice_cmd_device_info(v); - rc = voice_cmd_acquire_done(v); - } - break; - default: - break; - } - - switch (v->dev_event) { - case DEV_CHANGE_READY: - if (v->voc_state == VOICE_CHANGE) { - mutex_lock(&voice.voc_lock); - msm_snddev_enable_sidetone(v->dev_rx.dev_id, - 1); - /* update voice state */ - v->voc_state = VOICE_ACQUIRE; - v->dev_event = 0; - mutex_unlock(&voice.voc_lock); - broadcast_event(AUDDEV_EVT_VOICE_STATE_CHG, - VOICE_STATE_INCALL, SESSION_IGNORE); - } else { - mutex_lock(&voice.voc_lock); - v->dev_event = 0; - mutex_unlock(&voice.voc_lock); - MM_ERR("Get this event at the wrong state\n"); - } - break; - default: - mutex_lock(&voice.voc_lock); - v->dev_event = 0; - mutex_unlock(&voice.voc_lock); - break; - } - } - return 0; -} - -static int __init voice_init(void) -{ - int rc, i; - struct voice_data *v = &voice; - MM_INFO("\n"); /* Macro prints the file name and function */ - - mutex_init(&voice.voc_lock); - mutex_init(&voice.vol_lock); - v->handle = NULL; - v->cb_handle = NULL; - - /* set default value */ - v->default_mute_val = 1; /* default is mute */ - v->default_vol_val = 0; - v->default_sample_val = 8000; - for (i = 0; i < VOC_RX_VOL_ARRAY_NUM; i++) { - v->max_rx_vol[i] = 0; - v->min_rx_vol[i] = 0; - } - v->network = NETWORK_GSM; - - /* initialize dev_rx and dev_tx */ - memset(&v->dev_tx, 0, sizeof(struct device_data)); - memset(&v->dev_rx, 0, sizeof(struct device_data)); - v->dev_rx.volume = v->default_vol_val; - v->dev_tx.mute = v->default_mute_val; - - v->dev_state = DEV_INIT; - v->voc_state = VOICE_INIT; - atomic_set(&v->rel_start_flag, 0); - atomic_set(&v->acq_start_flag, 0); - v->dev_event = 0; - v->voc_event = 0; - init_completion(&voice.complete); - init_waitqueue_head(&v->dev_wait); - init_waitqueue_head(&v->voc_wait); - - /* get device handle */ - rc = daldevice_attach(VOICE_DALRPC_DEVICEID, - VOICE_DALRPC_PORT_NAME, - VOICE_DALRPC_CPU, - &v->handle); - if (rc) { - MM_ERR("Voc DALRPC call to Modem attach failed\n"); - goto done; - } - - /* Allocate the callback handle */ - v->cb_handle = dalrpc_alloc_cb(v->handle, remote_cb_function, v); - if (v->cb_handle == NULL) { - MM_ERR("Allocate Callback failure\n"); - goto err; - } - - /* setup the callback */ - rc = voice_cmd_init(v); - if (rc) - goto err1; - - v->device_events = AUDDEV_EVT_DEV_CHG_VOICE | - AUDDEV_EVT_DEV_RDY | - AUDDEV_EVT_REL_PENDING | - AUDDEV_EVT_START_VOICE | - AUDDEV_EVT_END_VOICE | - AUDDEV_EVT_DEVICE_VOL_MUTE_CHG | - AUDDEV_EVT_FREQ_CHG; - - MM_DBG(" to register call back \n"); - /* register callback to auddev */ - auddev_register_evt_listner(v->device_events, AUDDEV_CLNT_VOC, - 0, voice_auddev_cb_function, v); - - /* create and start thread */ - v->task = kthread_run(voice_thread, v, "voice"); - if (IS_ERR(v->task)) { - rc = PTR_ERR(v->task); - v->task = NULL; - } else - goto done; - -err1: dalrpc_dealloc_cb(v->handle, v->cb_handle); -err: - daldevice_detach(v->handle); - v->handle = NULL; -done: - return rc; -} - -late_initcall(voice_init); diff --git a/arch/arm/mach-msm/qdsp6/Makefile b/arch/arm/mach-msm/qdsp6/Makefile deleted file mode 100644 index 9a5561261bfc57a051e83c34e6187a5c32618c44..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -obj-y += dal.o -obj-y += q6audio.o -obj-y += analog_audio.o -obj-y += pcm_out.o -obj-y += pcm_in.o -obj-y += auxpcm_lb_out.o -obj-y += auxpcm_lb_in.o -obj-y += aac_in.o -obj-y += qcelp_in.o -obj-y += evrc_in.o -obj-y += amrnb_in.o -obj-y += mp3.o -obj-y += dtmf.o -obj-y += routing.o -obj-y += audio_ctl.o -obj-y += msm_q6vdec.o -obj-y += msm_q6venc.o -obj-y += dsp_debug.o -obj-$(CONFIG_QSD_AUDIO) += audiov2/ diff --git a/arch/arm/mach-msm/qdsp6/aac_in.c b/arch/arm/mach-msm/qdsp6/aac_in.c deleted file mode 100644 index 6e3bf94a8a3cbfca9aaf9f08f63e0a409586b354..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/aac_in.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * Copyright (C) 2009 Google, Inc. - * Copyright (C) 2009 HTC Corporation - * Copyright (c) 2010, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#define AAC_FC_BUFF_CNT 10 -#define AAC_READ_TIMEOUT 2000 -struct aac_fc_buff { - struct mutex lock; - int empty; - void *data; - int size; - int actual_size; -}; - -struct aac_fc { - struct task_struct *task; - wait_queue_head_t fc_wq; - struct aac_fc_buff fc_buff[AAC_FC_BUFF_CNT]; - int buff_index; -}; -struct aac { - struct mutex lock; - struct msm_audio_aac_enc_config cfg; - struct msm_audio_stream_config str_cfg; - struct audio_client *audio_client; - struct msm_voicerec_mode voicerec_mode; - struct aac_fc *aac_fc; -}; - -static int q6_aac_flowcontrol(void *data) -{ - struct audio_client *ac; - struct audio_buffer *ab; - struct aac *aac = data; - int buff_index = 0; - int xfer = 0; - struct aac_fc *fc; - - - ac = aac->audio_client; - fc = aac->aac_fc; - if (!ac) { - pr_err("[%s:%s] audio_client is NULL\n", __MM_FILE__, __func__); - return 0; - } - - while (!kthread_should_stop()) { - ab = ac->buf + ac->cpu_buf; - if (ab->used) - wait_event(ac->wait, (ab->used == 0)); - pr_debug("[%s:%s] ab->data = %p, cpu_buf = %d\n", __MM_FILE__, - __func__, ab->data, ac->cpu_buf); - xfer = ab->actual_size; - - mutex_lock(&(fc->fc_buff[buff_index].lock)); - if (!fc->fc_buff[buff_index].empty) { - pr_err("[%s:%s] flow control buffer[%d] not read!\n", - __MM_FILE__, __func__, buff_index); - } - - if (fc->fc_buff[buff_index].size < xfer) { - pr_err("[%s:%s] buffer %d too small\n", __MM_FILE__, - __func__, buff_index); - memcpy(fc->fc_buff[buff_index].data, - ab->data, fc->fc_buff[buff_index].size); - fc->fc_buff[buff_index].empty = 0; - fc->fc_buff[buff_index].actual_size = - fc->fc_buff[buff_index].size; - } else { - memcpy(fc->fc_buff[buff_index].data, ab->data, xfer); - fc->fc_buff[buff_index].empty = 0; - fc->fc_buff[buff_index].actual_size = xfer; - } - mutex_unlock(&(fc->fc_buff[buff_index].lock)); - /*wake up client, if any*/ - wake_up(&fc->fc_wq); - - buff_index++; - if (buff_index >= AAC_FC_BUFF_CNT) - buff_index = 0; - - ab->used = 1; - - q6audio_read(ac, ab); - ac->cpu_buf ^= 1; - } - - return 0; -} -static long q6_aac_in_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct aac *aac = file->private_data; - int rc = 0; - int i = 0; - struct aac_fc *fc; - int size = 0; - - mutex_lock(&aac->lock); - switch (cmd) { - case AUDIO_SET_VOLUME: - break; - case AUDIO_GET_STATS: - { - struct msm_audio_stats stats; - pr_debug("[%s:%s] GET_STATS\n", __MM_FILE__, __func__); - memset(&stats, 0, sizeof(stats)); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - case AUDIO_START: - { - uint32_t acdb_id; - pr_debug("[%s:%s] AUDIO_START\n", __MM_FILE__, __func__); - if (arg == 0) { - acdb_id = 0; - } else { - if (copy_from_user(&acdb_id, (void *) arg, - sizeof(acdb_id))) { - rc = -EFAULT; - break; - } - } - if (aac->audio_client) { - rc = -EBUSY; - pr_err("[%s:%s] active session already existing\n", - __MM_FILE__, __func__); - break; - } else { - aac->audio_client = q6audio_open_aac( - aac->str_cfg.buffer_size, - aac->cfg.sample_rate, - aac->cfg.channels, - aac->cfg.bit_rate, - aac->cfg.stream_format, - aac->voicerec_mode.rec_mode, acdb_id); - - if (aac->audio_client < 0) { - pr_err("[%s:%s] aac open session failed\n", - __MM_FILE__, __func__); - rc = -ENOMEM; - break; - } - } - - /*allocate flow control buffers*/ - fc = aac->aac_fc; - size = ((aac->str_cfg.buffer_size < 1543) ? 1543 : - aac->str_cfg.buffer_size); - for (i = 0; i < AAC_FC_BUFF_CNT; ++i) { - mutex_init(&(fc->fc_buff[i].lock)); - fc->fc_buff[i].empty = 1; - fc->fc_buff[i].data = kmalloc(size, GFP_KERNEL); - if (fc->fc_buff[i].data == NULL) { - pr_err("[%s:%s] No memory for FC buffers\n", - __MM_FILE__, __func__); - rc = -ENOMEM; - goto fc_fail; - } - fc->fc_buff[i].size = size; - fc->fc_buff[i].actual_size = 0; - } - - /*create flow control thread*/ - fc->task = kthread_run(q6_aac_flowcontrol, - aac, "aac_flowcontrol"); - if (IS_ERR(fc->task)) { - rc = PTR_ERR(fc->task); - pr_err("[%s:%s] error creating flow control thread\n", - __MM_FILE__, __func__); - goto fc_fail; - } - break; -fc_fail: - /*free flow control buffers*/ - --i; - for (; i >= 0; i--) { - kfree(fc->fc_buff[i].data); - fc->fc_buff[i].data = NULL; - } - break; - } - case AUDIO_STOP: - pr_debug("[%s:%s] AUDIO_STOP\n", __MM_FILE__, __func__); - break; - case AUDIO_FLUSH: - break; - case AUDIO_SET_INCALL: { - pr_debug("[%s:%s] SET_INCALL\n", __MM_FILE__, __func__); - if (copy_from_user(&aac->voicerec_mode, - (void *)arg, sizeof(struct msm_voicerec_mode))) - rc = -EFAULT; - - if (aac->voicerec_mode.rec_mode != AUDIO_FLAG_READ - && aac->voicerec_mode.rec_mode != - AUDIO_FLAG_INCALL_MIXED) { - aac->voicerec_mode.rec_mode = AUDIO_FLAG_READ; - pr_err("[%s:%s] Invalid rec_mode\n", __MM_FILE__, - __func__); - rc = -EINVAL; - } - break; - } - case AUDIO_GET_STREAM_CONFIG: - if (copy_to_user((void *)arg, &aac->str_cfg, - sizeof(struct msm_audio_stream_config))) - rc = -EFAULT; - pr_debug("[%s:%s] GET_STREAM_CONFIG: buffsz=%d, buffcnt=%d\n", - __MM_FILE__, __func__, aac->str_cfg.buffer_size, - aac->str_cfg.buffer_count); - break; - case AUDIO_SET_STREAM_CONFIG: - if (copy_from_user(&aac->str_cfg, (void *)arg, - sizeof(struct msm_audio_stream_config))) { - rc = -EFAULT; - break; - } - pr_debug("[%s:%s] SET_STREAM_CONFIG: buffsz=%d, buffcnt=%d\n", - __MM_FILE__, __func__, aac->str_cfg.buffer_size, - aac->str_cfg.buffer_count); - if (aac->str_cfg.buffer_size < 1543) { - pr_err("[%s:%s] Buffer size too small\n", __MM_FILE__, - __func__); - rc = -EINVAL; - break; - } - if (aac->str_cfg.buffer_count != 2) - pr_info("[%s:%s] Buffer count set to 2\n", __MM_FILE__, - __func__); - - break; - case AUDIO_SET_AAC_ENC_CONFIG: - if (copy_from_user(&aac->cfg, (void *) arg, - sizeof(struct msm_audio_aac_enc_config))) { - rc = -EFAULT; - } - pr_debug("[%s:%s] SET_AAC_ENC_CONFIG: channels=%d, rate=%d\n", - __MM_FILE__, __func__, aac->cfg.channels, - aac->cfg.sample_rate); - if (aac->cfg.channels < 1 || aac->cfg.channels > 2) { - pr_err("[%s:%s]invalid number of channels\n", - __MM_FILE__, __func__); - rc = -EINVAL; - } - if (aac->cfg.sample_rate != 48000) { - pr_err("[%s:%s] only 48KHz is supported\n", - __MM_FILE__, __func__); - rc = -EINVAL; - } - if (aac->cfg.stream_format != AUDIO_AAC_FORMAT_RAW && - aac->cfg.stream_format != AUDIO_AAC_FORMAT_ADTS) { - pr_err("[%s:%s] unsupported AAC format\n", __MM_FILE__, - __func__); - rc = -EINVAL; - } - break; - case AUDIO_GET_AAC_ENC_CONFIG: - if (copy_to_user((void *) arg, &aac->cfg, - sizeof(struct msm_audio_aac_enc_config))) { - rc = -EFAULT; - } - pr_debug("[%s:%s] GET_AAC_ENC_CONFIG: channels=%d, rate=%d\n", - __MM_FILE__, __func__, aac->cfg.channels, - aac->cfg.sample_rate); - break; - default: - rc = -EINVAL; - } - - mutex_unlock(&aac->lock); - pr_debug("[%s:%s] rc = %d\n", __MM_FILE__, __func__, rc); - return rc; -} - -static int q6_aac_in_open(struct inode *inode, struct file *file) -{ - - struct aac *aac; - struct aac_fc *fc; - int i; - pr_info("[%s:%s] open\n", __MM_FILE__, __func__); - aac = kmalloc(sizeof(struct aac), GFP_KERNEL); - if (aac == NULL) { - pr_err("[%s:%s] Could not allocate memory for aac driver\n", - __MM_FILE__, __func__); - return -ENOMEM; - } - - mutex_init(&aac->lock); - file->private_data = aac; - aac->audio_client = NULL; - aac->str_cfg.buffer_size = 1543; - aac->str_cfg.buffer_count = 2; - aac->cfg.channels = 1; - aac->cfg.bit_rate = 192000; - aac->cfg.stream_format = AUDIO_AAC_FORMAT_ADTS; - aac->cfg.sample_rate = 48000; - aac->voicerec_mode.rec_mode = AUDIO_FLAG_READ; - - aac->aac_fc = kmalloc(sizeof(struct aac_fc), GFP_KERNEL); - if (aac->aac_fc == NULL) { - pr_err("[%s:%s] Could not allocate memory for aac_fc\n", - __MM_FILE__, __func__); - kfree(aac); - return -ENOMEM; - } - fc = aac->aac_fc; - fc->task = NULL; - fc->buff_index = 0; - for (i = 0; i < AAC_FC_BUFF_CNT; ++i) { - fc->fc_buff[i].data = NULL; - fc->fc_buff[i].size = 0; - fc->fc_buff[i].actual_size = 0; - } - /*initialize wait queue head*/ - init_waitqueue_head(&fc->fc_wq); - return 0; -} - -static ssize_t q6_aac_in_read(struct file *file, char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_client *ac; - const char __user *start = buf; - struct aac *aac = file->private_data; - struct aac_fc *fc; - int xfer = 0; - int res = 0; - - pr_debug("[%s:%s] count = %d\n", __MM_FILE__, __func__, count); - mutex_lock(&aac->lock); - ac = aac->audio_client; - - if (!ac) { - res = -ENODEV; - goto fail; - } - fc = aac->aac_fc; - - /*wait for buffer to full*/ - if (fc->fc_buff[fc->buff_index].empty != 0) { - res = wait_event_interruptible_timeout(fc->fc_wq, - (fc->fc_buff[fc->buff_index].empty == 0), - msecs_to_jiffies(AAC_READ_TIMEOUT)); - - pr_debug("[%s:%s] buff_index = %d\n", __MM_FILE__, - __func__, fc->buff_index); - if (res == 0) { - pr_err("[%s:%s] Timeout!\n", __MM_FILE__, __func__); - res = -ETIMEDOUT; - goto fail; - } else if (res < 0) { - pr_err("[%s:%s] Returning on Interrupt\n", __MM_FILE__, - __func__); - goto fail; - } - } - /*lock the buffer*/ - mutex_lock(&(fc->fc_buff[fc->buff_index].lock)); - xfer = fc->fc_buff[fc->buff_index].actual_size; - - if (xfer > count) { - mutex_unlock(&(fc->fc_buff[fc->buff_index].lock)); - pr_err("[%s:%s] read failed! byte count too small\n", - __MM_FILE__, __func__); - res = -EINVAL; - goto fail; - } - - if (copy_to_user(buf, fc->fc_buff[fc->buff_index].data, xfer)) { - mutex_unlock(&(fc->fc_buff[fc->buff_index].lock)); - pr_err("[%s:%s] copy_to_user failed at index %d\n", - __MM_FILE__, __func__, fc->buff_index); - res = -EFAULT; - goto fail; - } - - buf += xfer; - - fc->fc_buff[fc->buff_index].empty = 1; - fc->fc_buff[fc->buff_index].actual_size = 0; - - mutex_unlock(&(fc->fc_buff[fc->buff_index].lock)); - ++(fc->buff_index); - if (fc->buff_index >= AAC_FC_BUFF_CNT) - fc->buff_index = 0; - - res = buf - start; -fail: - mutex_unlock(&aac->lock); - - return res; -} - -static int q6_aac_in_release(struct inode *inode, struct file *file) -{ - int rc = 0; - struct aac *aac = file->private_data; - int i = 0; - struct aac_fc *fc; - - mutex_lock(&aac->lock); - fc = aac->aac_fc; - kthread_stop(fc->task); - fc->task = NULL; - - /*free flow control buffers*/ - for (i = 0; i < AAC_FC_BUFF_CNT; ++i) { - kfree(fc->fc_buff[i].data); - fc->fc_buff[i].data = NULL; - } - kfree(fc); - if (aac->audio_client) - rc = q6audio_close(aac->audio_client); - mutex_unlock(&aac->lock); - kfree(aac); - pr_info("[%s:%s] release\n", __MM_FILE__, __func__); - return rc; -} - -static const struct file_operations q6_aac_in_fops = { - .owner = THIS_MODULE, - .open = q6_aac_in_open, - .read = q6_aac_in_read, - .release = q6_aac_in_release, - .unlocked_ioctl = q6_aac_in_ioctl, -}; - -struct miscdevice q6_aac_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_aac_in", - .fops = &q6_aac_in_fops, -}; - -static int __init q6_aac_in_init(void) -{ - return misc_register(&q6_aac_in_misc); -} - -device_initcall(q6_aac_in_init); diff --git a/arch/arm/mach-msm/qdsp6/amrnb_in.c b/arch/arm/mach-msm/qdsp6/amrnb_in.c deleted file mode 100644 index e20bf5beb355078d92a13f93ae99adce43f12c3a..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/amrnb_in.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (C) 2009 Google, Inc. - * Copyright (C) 2009 HTC Corporation - * Copyright (c) 2010, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "dal_audio_format.h" -#include - -struct amrnb { - struct mutex lock; - struct msm_audio_amrnb_enc_config_v2 cfg; - struct msm_audio_stream_config str_cfg; - struct audio_client *audio_client; - struct msm_voicerec_mode voicerec_mode; -}; - - -static long q6_amrnb_in_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct amrnb *amrnb = file->private_data; - int rc = 0; - - mutex_lock(&amrnb->lock); - switch (cmd) { - case AUDIO_SET_VOLUME: - pr_debug("[%s:%s] SET_VOLUME\n", __MM_FILE__, __func__); - break; - case AUDIO_GET_STATS: - { - struct msm_audio_stats stats; - pr_debug("[%s:%s] GET_STATS\n", __MM_FILE__, __func__); - memset(&stats, 0, sizeof(stats)); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - case AUDIO_START: - { - uint32_t acdb_id; - pr_debug("[%s:%s] AUDIO_START\n", __MM_FILE__, __func__); - if (arg == 0) { - acdb_id = 0; - } else { - if (copy_from_user(&acdb_id, (void *) arg, - sizeof(acdb_id))) { - rc = -EFAULT; - break; - } - } - if (amrnb->audio_client) { - rc = -EBUSY; - pr_err("[%s:%s] active session already existing\n", - __MM_FILE__, __func__); - break; - } else { - amrnb->audio_client = q6audio_open_amrnb( - amrnb->str_cfg.buffer_size, - amrnb->cfg.band_mode, - amrnb->cfg.dtx_enable, - amrnb->voicerec_mode.rec_mode, - acdb_id); - if (!amrnb->audio_client) { - pr_err("[%s:%s] amrnb open session failed\n", - __MM_FILE__, __func__); - kfree(amrnb); - rc = -ENOMEM; - break; - } - } - break; - } - case AUDIO_STOP: - pr_debug("[%s:%s] AUDIO_STOP\n", __MM_FILE__, __func__); - break; - case AUDIO_FLUSH: - break; - case AUDIO_SET_INCALL: { - pr_debug("[%s:%s] SET_INCALL\n", __MM_FILE__, __func__); - if (copy_from_user(&amrnb->voicerec_mode, - (void *)arg, sizeof(struct msm_voicerec_mode))) - rc = -EFAULT; - - if (amrnb->voicerec_mode.rec_mode != AUDIO_FLAG_READ - && amrnb->voicerec_mode.rec_mode != - AUDIO_FLAG_INCALL_MIXED) { - amrnb->voicerec_mode.rec_mode = AUDIO_FLAG_READ; - pr_err("[%s:%s] Invalid rec_mode\n", __MM_FILE__, - __func__); - rc = -EINVAL; - } - break; - } - case AUDIO_GET_STREAM_CONFIG: - if (copy_to_user((void *)arg, &amrnb->str_cfg, - sizeof(struct msm_audio_stream_config))) - rc = -EFAULT; - pr_debug("[%s:%s] GET_STREAM_CONFIG: buffsz=%d, buffcnt = %d\n", - __MM_FILE__, __func__, amrnb->str_cfg.buffer_size, - amrnb->str_cfg.buffer_count); - break; - case AUDIO_SET_STREAM_CONFIG: - if (copy_from_user(&amrnb->str_cfg, (void *)arg, - sizeof(struct msm_audio_stream_config))) { - rc = -EFAULT; - break; - } - pr_debug("[%s:%s] SET_STREAM_CONFIG: buffsz=%d, buffcnt = %d\n", - __MM_FILE__, __func__, amrnb->str_cfg.buffer_size, - amrnb->str_cfg.buffer_count); - - if (amrnb->str_cfg.buffer_size < 768) { - pr_err("[%s:%s] Buffer size too small\n", __MM_FILE__, - __func__); - rc = -EINVAL; - break; - } - - if (amrnb->str_cfg.buffer_count != 2) - pr_info("[%s:%s] Buffer count set to 2\n", __MM_FILE__, - __func__); - break; - case AUDIO_SET_AMRNB_ENC_CONFIG: - if (copy_from_user(&amrnb->cfg, (void *) arg, - sizeof(struct msm_audio_amrnb_enc_config_v2))) - rc = -EFAULT; - pr_debug("[%s:%s] SET_AMRNB_ENC_CONFIG\n", __MM_FILE__, - __func__); - break; - case AUDIO_GET_AMRNB_ENC_CONFIG: - if (copy_to_user((void *) arg, &amrnb->cfg, - sizeof(struct msm_audio_amrnb_enc_config_v2))) - rc = -EFAULT; - pr_debug("[%s:%s] GET_AMRNB_ENC_CONFIG\n", __MM_FILE__, - __func__); - break; - - default: - rc = -EINVAL; - } - - mutex_unlock(&amrnb->lock); - pr_debug("[%s:%s] rc= %d\n", __MM_FILE__, __func__, rc); - return rc; -} - -static int q6_amrnb_in_open(struct inode *inode, struct file *file) -{ - struct amrnb *amrnb; - - pr_info("[%s:%s] open\n", __MM_FILE__, __func__); - amrnb = kmalloc(sizeof(struct amrnb), GFP_KERNEL); - if (amrnb == NULL) { - pr_err("[%s:%s] Could not allocate memory for amrnb driver\n", - __MM_FILE__, __func__); - return -ENOMEM; - } - - mutex_init(&amrnb->lock); - file->private_data = amrnb; - amrnb->audio_client = NULL; - amrnb->str_cfg.buffer_size = 768; - amrnb->str_cfg.buffer_count = 2; - amrnb->cfg.band_mode = 7; - amrnb->cfg.dtx_enable = 3; - amrnb->cfg.frame_format = ADSP_AUDIO_FORMAT_AMRNB_FS; - amrnb->voicerec_mode.rec_mode = AUDIO_FLAG_READ; - - return 0; -} - -static ssize_t q6_amrnb_in_read(struct file *file, char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_client *ac; - struct audio_buffer *ab; - const char __user *start = buf; - struct amrnb *amrnb = file->private_data; - int xfer = 0; - int res; - - pr_debug("[%s:%s] count = %d\n", __MM_FILE__, __func__, count); - mutex_lock(&amrnb->lock); - ac = amrnb->audio_client; - if (!ac) { - res = -ENODEV; - goto fail; - } - while (count > xfer) { - ab = ac->buf + ac->cpu_buf; - - if (ab->used) - wait_event(ac->wait, (ab->used == 0)); - - pr_debug("[%s:%s] ab->data = %p, cpu_buf = %d\n", __MM_FILE__, - __func__, ab->data, ac->cpu_buf); - xfer = ab->actual_size; - - if (copy_to_user(buf, ab->data, xfer)) { - pr_err("[%s:%s] copy_to_user failed\n", - __MM_FILE__, __func__); - res = -EFAULT; - goto fail; - } - - buf += xfer; - count -= xfer; - - ab->used = 1; - q6audio_read(ac, ab); - ac->cpu_buf ^= 1; - } - - res = buf - start; -fail: - mutex_unlock(&amrnb->lock); - - return res; -} - -static int q6_amrnb_in_release(struct inode *inode, struct file *file) -{ - int rc = 0; - struct amrnb *amrnb = file->private_data; - - mutex_lock(&amrnb->lock); - if (amrnb->audio_client) - rc = q6audio_close(amrnb->audio_client); - mutex_unlock(&amrnb->lock); - kfree(amrnb); - pr_info("[%s:%s] release\n", __MM_FILE__, __func__); - return rc; -} - -static const struct file_operations q6_amrnb_in_fops = { - .owner = THIS_MODULE, - .open = q6_amrnb_in_open, - .read = q6_amrnb_in_read, - .release = q6_amrnb_in_release, - .unlocked_ioctl = q6_amrnb_in_ioctl, -}; - -struct miscdevice q6_amrnb_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_amr_in", - .fops = &q6_amrnb_in_fops, -}; - -static int __init q6_amrnb_in_init(void) -{ - return misc_register(&q6_amrnb_in_misc); -} - -device_initcall(q6_amrnb_in_init); diff --git a/arch/arm/mach-msm/qdsp6/analog_audio.c b/arch/arm/mach-msm/qdsp6/analog_audio.c deleted file mode 100644 index d3a6baa5409c7f8f91d937dbcc1c1dcafe16921e..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/analog_audio.c +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright (c) 2010, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define GPIO_HEADSET_AMP 157 -#define GPIO_SPEAKER_AMP 39 -#define GPIO_HEADSET_SHDN_N 48 - -void analog_init(void) -{ - /* stereo pmic init */ - pmic_spkr_set_gain(LEFT_SPKR, SPKR_GAIN_PLUS12DB); - pmic_spkr_set_gain(RIGHT_SPKR, SPKR_GAIN_PLUS12DB); - pmic_mic_set_volt(MIC_VOLT_1_80V); - gpio_direction_output(GPIO_HEADSET_AMP, 1); - gpio_set_value(GPIO_HEADSET_AMP, 0); -} - -void analog_headset_enable(int en) -{ - pr_debug("[%s:%s] en = %d\n", __MM_FILE__, __func__, en); - /* enable audio amp */ - gpio_set_value(GPIO_HEADSET_AMP, !!en); -} - -void analog_speaker_enable(int en) -{ - struct spkr_config_mode scm; - memset(&scm, 0, sizeof(scm)); - - pr_debug("[%s:%s] en = %d\n", __MM_FILE__, __func__, en); - if (en) { - scm.is_right_chan_en = 1; - scm.is_left_chan_en = 1; - scm.is_stereo_en = 1; - scm.is_hpf_en = 1; - pmic_spkr_en_mute(LEFT_SPKR, 0); - pmic_spkr_en_mute(RIGHT_SPKR, 0); - pmic_set_spkr_configuration(&scm); - pmic_spkr_en(LEFT_SPKR, 1); - pmic_spkr_en(RIGHT_SPKR, 1); - - /* unmute */ - pmic_spkr_en_mute(LEFT_SPKR, 1); - pmic_spkr_en_mute(RIGHT_SPKR, 1); - } else { - pmic_spkr_en_mute(LEFT_SPKR, 0); - pmic_spkr_en_mute(RIGHT_SPKR, 0); - - pmic_spkr_en(LEFT_SPKR, 0); - pmic_spkr_en(RIGHT_SPKR, 0); - - pmic_set_spkr_configuration(&scm); - } -} - -void analog_mic_enable(int en) -{ - pr_debug("[%s:%s] en = %d\n", __MM_FILE__, __func__, en); - pmic_mic_en(en); -} - -static struct q6audio_analog_ops ops = { - .init = analog_init, - .speaker_enable = analog_speaker_enable, - .headset_enable = analog_headset_enable, - .int_mic_enable = analog_mic_enable, - .ext_mic_enable = analog_mic_enable, -}; - -static int __init init(void) -{ - q6audio_register_analog_ops(&ops); - return 0; -} - -device_initcall(init); diff --git a/arch/arm/mach-msm/qdsp6/audio_ctl.c b/arch/arm/mach-msm/qdsp6/audio_ctl.c deleted file mode 100644 index ab1df3992e4a15fef2e80d561751b5b70c6bd50a..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/audio_ctl.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 2009 Google, Inc. - * Copyright (C) 2009 HTC Corporation - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include - -#include -#include - -#define BUFSZ (0) - -static DEFINE_MUTEX(voice_lock); -static int voice_started; - -static struct audio_client *voc_tx_clnt; -static struct audio_client *voc_rx_clnt; - -static int q6_voice_start(void) -{ - int rc = 0; - - mutex_lock(&voice_lock); - - if (voice_started) { - pr_err("[%s:%s] busy\n", __MM_FILE__, __func__); - rc = -EBUSY; - goto done; - } - - voc_tx_clnt = q6voice_open(AUDIO_FLAG_WRITE); - if (!voc_tx_clnt) { - pr_err("[%s:%s] open voice tx failed.\n", __MM_FILE__, - __func__); - rc = -ENOMEM; - goto done; - } - - voc_rx_clnt = q6voice_open(AUDIO_FLAG_READ); - if (!voc_rx_clnt) { - pr_err("[%s:%s] open voice rx failed.\n", __MM_FILE__, - __func__); - q6voice_close(voc_tx_clnt); - rc = -ENOMEM; - } - - voice_started = 1; -done: - mutex_unlock(&voice_lock); - return rc; -} - -static int q6_voice_stop(void) -{ - mutex_lock(&voice_lock); - if (voice_started) { - q6voice_close(voc_tx_clnt); - q6voice_close(voc_rx_clnt); - voice_started = 0; - } - mutex_unlock(&voice_lock); - return 0; -} - -static int q6_open(struct inode *inode, struct file *file) -{ - pr_debug("[%s:%s]\n", __MM_FILE__, __func__); - return 0; -} - -static long q6_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - int rc; - uint32_t n; - uint32_t id[2]; - uint32_t mute_status; - - switch (cmd) { - case AUDIO_SWITCH_DEVICE: - rc = copy_from_user(&id, (void *)arg, sizeof(id)); - pr_info("[%s:%s] SWITCH_DEV: id[0] = 0x%x, id[1] = 0x%x", - __MM_FILE__, __func__, id[0], id[1]); - if (!rc) - rc = q6audio_do_routing(id[0], id[1]); - break; - case AUDIO_SET_VOLUME: - rc = copy_from_user(&n, (void *)arg, sizeof(n)); - pr_debug("[%s:%s] SET_VOLUME: vol = %d\n", __MM_FILE__, - __func__, n); - if (!rc) - rc = q6audio_set_rx_volume(n); - break; - case AUDIO_SET_MUTE: - rc = copy_from_user(&n, (void *)arg, sizeof(n)); - if (!rc) { - if (voice_started) { - if (n == 1) - mute_status = STREAM_MUTE; - else - mute_status = STREAM_UNMUTE; - } else { - if (n == 1) - mute_status = DEVICE_MUTE; - else - mute_status = DEVICE_UNMUTE; - } - - pr_debug("[%s:%s] SET_MUTE: mute_status = %d\n", - __MM_FILE__, __func__, mute_status); - rc = q6audio_set_tx_mute(mute_status); - } - break; - case AUDIO_UPDATE_ACDB: - rc = copy_from_user(&id, (void *)arg, sizeof(id)); - pr_debug("[%s:%s] UPDATE_ACDB: id[0] = 0x%x, id[1] = 0x%x\n", - __MM_FILE__, __func__, id[0], id[1]); - if (!rc) - rc = q6audio_update_acdb(id[0], 0); - break; - case AUDIO_START_VOICE: - pr_debug("[%s:%s] START_VOICE\n", __MM_FILE__, __func__); - rc = q6_voice_start(); - break; - case AUDIO_STOP_VOICE: - pr_debug("[%s:%s] STOP_VOICE\n", __MM_FILE__, __func__); - rc = q6_voice_stop(); - break; - case AUDIO_REINIT_ACDB: - pr_debug("[%s:%s] REINIT_ACDB\n", __MM_FILE__, __func__); - rc = 0; - break; - default: - rc = -EINVAL; - } - - return rc; -} - - -static int q6_release(struct inode *inode, struct file *file) -{ - pr_debug("[%s:%s]\n", __MM_FILE__, __func__); - return 0; -} - -static struct file_operations q6_dev_fops = { - .owner = THIS_MODULE, - .open = q6_open, - .unlocked_ioctl = q6_ioctl, - .release = q6_release, -}; - -struct miscdevice q6_control_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_audio_ctl", - .fops = &q6_dev_fops, -}; - - -static int __init q6_audio_ctl_init(void) { - return misc_register(&q6_control_device); -} - -device_initcall(q6_audio_ctl_init); diff --git a/arch/arm/mach-msm/qdsp6/audiov2/Makefile b/arch/arm/mach-msm/qdsp6/audiov2/Makefile deleted file mode 100644 index 86ab9aeab713d50442ecf12163daed9728e50cb8..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/audiov2/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -obj-y += q6audio.o -obj-y += aac_in.o -obj-y += voice.o -obj-y += pcm_out.o -obj-y += pcm_in.o -obj-y += mp3.o -obj-y += audio_ctl.o -obj-y += analog_audio.o -obj-y += routing.o -obj-y += evrc_in.o -obj-y += qcelp_in.o -obj-y += amrnb_in.o diff --git a/arch/arm/mach-msm/qdsp6/audiov2/aac_in.c b/arch/arm/mach-msm/qdsp6/audiov2/aac_in.c deleted file mode 100644 index ef566c97cf2991202a359d5afd9197df8a0fcf6c..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/audiov2/aac_in.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (C) 2009 Google, Inc. - * Copyright (C) 2009 HTC Corporation - * Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include "dal_audio.h" -#include "dal_audio_format.h" - -struct aac { - struct mutex lock; - struct msm_audio_aac_enc_config cfg; - struct msm_audio_stream_config str_cfg; - struct audio_client *audio_client; -}; - -static long q6_aac_in_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct aac *aac = file->private_data; - struct adsp_open_command rpc; - - int sample_rate; - int audio_object_type; - int index = sizeof(u32); - int rc = 0; - u32 *aac_type = NULL; - - - mutex_lock(&aac->lock); - switch (cmd) { - - case AUDIO_START: - if (aac->audio_client) { - rc = -EBUSY; - break; - } else { - tx_clk_freq = 48000; - aac->audio_client = q6audio_open(AUDIO_FLAG_READ, - aac->str_cfg.buffer_size); - - if (aac->audio_client < 0) { - - tx_clk_freq = 8000; - rc = -ENOMEM; - break; - } - } - memset(&rpc, 0, sizeof(rpc)); - - rpc.format_block.binary.format = ADSP_AUDIO_FORMAT_MPEG4_AAC; - /* only 48k sample rate is supported */ - sample_rate = 3; - - /* AAC OBJECT LC */ - audio_object_type = 2; - - aac_type = (u32 *)rpc.format_block.binary.data; - switch (aac->cfg.stream_format) { - - case AUDIO_AAC_FORMAT_ADTS: - /* AAC Encoder expect MPEG4_ADTS media type */ - *aac_type = ADSP_AUDIO_AAC_MPEG4_ADTS; - break; - case AUDIO_AAC_FORMAT_RAW: - /* for ADIF recording */ - *aac_type = ADSP_AUDIO_AAC_RAW; - break; - } - - rpc.format_block.binary.data[index++] = (u8)( - ((audio_object_type & 0x1F) << 3) | - ((sample_rate >> 1) & 0x7)); - rpc.format_block.binary.data[index] = (u8)( - ((sample_rate & 0x1) << 7) | - ((aac->cfg.channels & 0x7) << 3)); - - rpc.format_block.binary.num_bytes = index + 1; - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_READ; - rpc.device = ADSP_AUDIO_DEVICE_ID_DEFAULT; - rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_RECORD; - rpc.buf_max_size = aac->str_cfg.buffer_size; - rpc.config.aac.bit_rate = aac->cfg.bit_rate; - rpc.config.aac.encoder_mode = ADSP_AUDIO_ENC_AAC_LC_ONLY_MODE; - q6audio_start(aac->audio_client, &rpc, sizeof(rpc)); - break; - case AUDIO_STOP: - break; - case AUDIO_FLUSH: - break; - case AUDIO_SET_VOLUME: - break; - case AUDIO_GET_STREAM_CONFIG: - if (copy_to_user((void *)arg, &aac->str_cfg, - sizeof(struct msm_audio_stream_config))) - rc = -EFAULT; - break; - case AUDIO_SET_STREAM_CONFIG: - if (copy_from_user(&aac->str_cfg, (void *)arg, - sizeof(struct msm_audio_stream_config))) { - rc = -EFAULT; - break; - } - if (aac->str_cfg.buffer_size < 519) { - pr_err("Buffer size too small\n"); - rc = -EINVAL; - break; - } - if (aac->str_cfg.buffer_count != 2) - pr_info("Buffer count set to 2\n"); - - break; - case AUDIO_SET_AAC_ENC_CONFIG: - if (copy_from_user(&aac->cfg, (void *) arg, - sizeof(struct msm_audio_aac_enc_config))) { - rc = -EFAULT; - } - if (aac->cfg.channels != 1) { - pr_err("only mono is supported\n"); - rc = -EINVAL; - } - if (aac->cfg.sample_rate != 48000) { - pr_err("only 48KHz is supported\n"); - rc = -EINVAL; - } - if (aac->cfg.stream_format != AUDIO_AAC_FORMAT_RAW && - aac->cfg.stream_format != AUDIO_AAC_FORMAT_ADTS) { - pr_err("unsupported AAC format\n"); - rc = -EINVAL; - } - break; - case AUDIO_GET_AAC_ENC_CONFIG: - if (copy_to_user((void *) arg, &aac->cfg, - sizeof(struct msm_audio_aac_enc_config))) { - rc = -EFAULT; - } - break; - default: - rc = -EINVAL; - } - - mutex_unlock(&aac->lock); - return rc; -} - -static int q6_aac_in_open(struct inode *inode, struct file *file) -{ - - struct aac *aac; - aac = kmalloc(sizeof(struct aac), GFP_KERNEL); - if (aac == NULL) { - pr_err("Could not allocate memory for aac driver\n"); - return -ENOMEM; - } - - mutex_init(&aac->lock); - file->private_data = aac; - aac->audio_client = NULL; - aac->str_cfg.buffer_size = 519; - aac->str_cfg.buffer_count = 2; - aac->cfg.channels = 1; - aac->cfg.bit_rate = 192000; - aac->cfg.stream_format = AUDIO_AAC_FORMAT_ADTS; - aac->cfg.sample_rate = 48000; - - return 0; -} - -static ssize_t q6_aac_in_read(struct file *file, char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_client *ac; - struct audio_buffer *ab; - const char __user *start = buf; - struct aac *aac = file->private_data; - int xfer = 0; - int res; - - mutex_lock(&aac->lock); - ac = aac->audio_client; - if (!ac) { - res = -ENODEV; - goto fail; - } - while (count > xfer) { - ab = ac->buf + ac->cpu_buf; - - if (ab->used) - wait_event(ac->wait, (ab->used == 0)); - - xfer = ab->actual_size; - - if (copy_to_user(buf, ab->data, xfer)) { - res = -EFAULT; - goto fail; - } - - buf += xfer; - count -= xfer; - - ab->used = 1; - q6audio_read(ac, ab); - ac->cpu_buf ^= 1; - } - res = buf - start; -fail: - mutex_unlock(&aac->lock); - - return res; -} - -static int q6_aac_in_release(struct inode *inode, struct file *file) -{ - int rc = 0; - struct aac *aac = file->private_data; - - mutex_lock(&aac->lock); - if (aac->audio_client) - rc = q6audio_close(aac->audio_client); - mutex_unlock(&aac->lock); - kfree(aac); - tx_clk_freq = 8000; - return rc; -} - -static const struct file_operations q6_aac_in_fops = { - .owner = THIS_MODULE, - .open = q6_aac_in_open, - .read = q6_aac_in_read, - .release = q6_aac_in_release, - .unlocked_ioctl = q6_aac_in_ioctl, -}; - -struct miscdevice q6_aac_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_aac_in", - .fops = &q6_aac_in_fops, -}; - -static int __init q6_aac_in_init(void) -{ - return misc_register(&q6_aac_in_misc); -} - -device_initcall(q6_aac_in_init); diff --git a/arch/arm/mach-msm/qdsp6/audiov2/amrnb_in.c b/arch/arm/mach-msm/qdsp6/audiov2/amrnb_in.c deleted file mode 100644 index e552ada2ce0c812ce9e4886bf6d164ceb0b9e4b3..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/audiov2/amrnb_in.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (C) 2009 Google, Inc. - * Copyright (C) 2009 HTC Corporation - * Copyright (c) 2010, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "dal_audio.h" -#include "dal_audio_format.h" -#include - - -struct amrnb { - struct mutex lock; - struct msm_audio_amrnb_enc_config_v2 cfg; - struct msm_audio_stream_config str_cfg; - struct audio_client *audio_client; -}; - - -static long q6_amrnb_in_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct amrnb *amrnb = file->private_data; - struct adsp_open_command rpc; - int rc = 0; - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - memset(&stats, 0, sizeof(stats)); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - mutex_lock(&amrnb->lock); - switch (cmd) { - case AUDIO_START: - if (amrnb->audio_client) { - rc = -EBUSY; - break; - } else { - amrnb->audio_client = q6audio_open(AUDIO_FLAG_READ, - amrnb->str_cfg.buffer_size); - - if (!amrnb->audio_client) { - kfree(amrnb); - rc = -ENOMEM; - break; - } - } - - tx_clk_freq = 8000; - - memset(&rpc, 0, sizeof(rpc)); - - rpc.format_block.standard.format = ADSP_AUDIO_FORMAT_AMRNB_FS; - rpc.format_block.standard.channels = 1; - rpc.format_block.standard.bits_per_sample = 16; - rpc.format_block.standard.sampling_rate = 8000; - rpc.format_block.standard.is_signed = 1; - rpc.format_block.standard.is_interleaved = 0; - - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_READ; - rpc.device = ADSP_AUDIO_DEVICE_ID_DEFAULT; - rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_RECORD; - rpc.buf_max_size = amrnb->str_cfg.buffer_size; - rpc.config.amr.mode = amrnb->cfg.band_mode; - rpc.config.amr.dtx_mode = amrnb->cfg.dtx_enable; - rpc.config.amr.enable = 1; - q6audio_start(amrnb->audio_client, &rpc, sizeof(rpc)); - break; - case AUDIO_STOP: - break; - case AUDIO_FLUSH: - break; - case AUDIO_SET_VOLUME: - break; - case AUDIO_GET_STREAM_CONFIG: - if (copy_to_user((void *)arg, &amrnb->str_cfg, - sizeof(struct msm_audio_stream_config))) - rc = -EFAULT; - break; - case AUDIO_SET_STREAM_CONFIG: - if (copy_from_user(&amrnb->str_cfg, (void *)arg, - sizeof(struct msm_audio_stream_config))) { - rc = -EFAULT; - break; - } - - if (amrnb->str_cfg.buffer_size < 768) { - pr_err("[%s:%s] Buffer size too small\n", __MM_FILE__, - __func__); - rc = -EINVAL; - break; - } - - if (amrnb->str_cfg.buffer_count != 2) - pr_info("[%s:%s] Buffer count set to 2\n", __MM_FILE__, - __func__); - break; - case AUDIO_SET_AMRNB_ENC_CONFIG: - if (copy_from_user(&amrnb->cfg, (void *) arg, - sizeof(struct msm_audio_amrnb_enc_config_v2))) - rc = -EFAULT; - break; - case AUDIO_GET_AMRNB_ENC_CONFIG: - if (copy_to_user((void *) arg, &amrnb->cfg, - sizeof(struct msm_audio_amrnb_enc_config_v2))) - rc = -EFAULT; - break; - - default: - rc = -EINVAL; - } - - mutex_unlock(&amrnb->lock); - return rc; -} - -static int q6_amrnb_in_open(struct inode *inode, struct file *file) -{ - struct amrnb *amrnb; - amrnb = kmalloc(sizeof(struct amrnb), GFP_KERNEL); - if (amrnb == NULL) { - pr_err("[%s:%s] Could not allocate memory for amrnb driver\n", - __MM_FILE__, __func__); - return -ENOMEM; - } - - mutex_init(&amrnb->lock); - file->private_data = amrnb; - amrnb->audio_client = NULL; - amrnb->str_cfg.buffer_size = 768; - amrnb->str_cfg.buffer_count = 2; - amrnb->cfg.band_mode = ADSP_AUDIO_AMR_MR475; - amrnb->cfg.dtx_enable = ADSP_AUDIO_AMR_DTX_MODE_ON_AUTO; - amrnb->cfg.frame_format = ADSP_AUDIO_FORMAT_AMRNB_FS; - return 0; -} - -static ssize_t q6_amrnb_in_read(struct file *file, char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_client *ac; - struct audio_buffer *ab; - const char __user *start = buf; - struct amrnb *amrnb = file->private_data; - int xfer = 0; - int res; - - mutex_lock(&amrnb->lock); - ac = amrnb->audio_client; - if (!ac) { - res = -ENODEV; - goto fail; - } - while (count > xfer) { - ab = ac->buf + ac->cpu_buf; - - if (ab->used) - wait_event(ac->wait, (ab->used == 0)); - - xfer = ab->actual_size; - - if (copy_to_user(buf, ab->data, xfer)) { - res = -EFAULT; - goto fail; - } - - buf += xfer; - count -= xfer; - - ab->used = 1; - q6audio_read(ac, ab); - ac->cpu_buf ^= 1; - } - - res = buf - start; -fail: - mutex_unlock(&amrnb->lock); - - return res; -} - -static int q6_amrnb_in_release(struct inode *inode, struct file *file) -{ - int rc = 0; - struct amrnb *amrnb = file->private_data; - - mutex_lock(&amrnb->lock); - if (amrnb->audio_client) - rc = q6audio_close(amrnb->audio_client); - mutex_unlock(&amrnb->lock); - kfree(amrnb); - return rc; -} - -static const struct file_operations q6_amrnb_in_fops = { - .owner = THIS_MODULE, - .open = q6_amrnb_in_open, - .read = q6_amrnb_in_read, - .release = q6_amrnb_in_release, - .unlocked_ioctl = q6_amrnb_in_ioctl, -}; - -struct miscdevice q6_amrnb_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_amr_in", - .fops = &q6_amrnb_in_fops, -}; - -static int __init q6_amrnb_in_init(void) -{ - return misc_register(&q6_amrnb_in_misc); -} - -device_initcall(q6_amrnb_in_init); diff --git a/arch/arm/mach-msm/qdsp6/audiov2/analog_audio.c b/arch/arm/mach-msm/qdsp6/audiov2/analog_audio.c deleted file mode 100644 index 5bf2cead86d4bb627abe6ef50751f27fd853f9c0..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/audiov2/analog_audio.c +++ /dev/null @@ -1,85 +0,0 @@ -/* Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include - -#define GPIO_HEADSET_AMP 157 - -void analog_init(void) -{ - /* stereo pmic init */ - pmic_spkr_set_gain(LEFT_SPKR, SPKR_GAIN_PLUS12DB); - pmic_spkr_set_gain(RIGHT_SPKR, SPKR_GAIN_PLUS12DB); - pmic_mic_set_volt(MIC_VOLT_1_80V); - - gpio_direction_output(GPIO_HEADSET_AMP, 1); - gpio_set_value(GPIO_HEADSET_AMP, 0); -} - -void analog_headset_enable(int en) -{ - /* enable audio amp */ - gpio_set_value(GPIO_HEADSET_AMP, !!en); -} - -void analog_speaker_enable(int en) -{ - struct spkr_config_mode scm; - memset(&scm, 0, sizeof(scm)); - - if (en) { - scm.is_right_chan_en = 1; - scm.is_left_chan_en = 1; - scm.is_stereo_en = 1; - scm.is_hpf_en = 1; - pmic_spkr_en_mute(LEFT_SPKR, 0); - pmic_spkr_en_mute(RIGHT_SPKR, 0); - pmic_set_spkr_configuration(&scm); - pmic_spkr_en(LEFT_SPKR, 1); - pmic_spkr_en(RIGHT_SPKR, 1); - - /* unmute */ - pmic_spkr_en_mute(LEFT_SPKR, 1); - pmic_spkr_en_mute(RIGHT_SPKR, 1); - } else { - pmic_spkr_en_mute(LEFT_SPKR, 0); - pmic_spkr_en_mute(RIGHT_SPKR, 0); - - pmic_spkr_en(LEFT_SPKR, 0); - pmic_spkr_en(RIGHT_SPKR, 0); - - pmic_set_spkr_configuration(&scm); - } -} - -void analog_mic_enable(int en) -{ - pmic_mic_en(en); -} - -static struct q6audio_analog_ops ops = { - .init = analog_init, - .speaker_enable = analog_speaker_enable, - .headset_enable = analog_headset_enable, - .int_mic_enable = analog_mic_enable, -}; - -static int __init init(void) -{ - q6audio_register_analog_ops(&ops); - return 0; -} - -device_initcall(init); diff --git a/arch/arm/mach-msm/qdsp6/audiov2/audio_ctl.c b/arch/arm/mach-msm/qdsp6/audiov2/audio_ctl.c deleted file mode 100644 index 4ebfc022fb453e3e73cb7290c5609b0295e41500..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/audiov2/audio_ctl.c +++ /dev/null @@ -1,140 +0,0 @@ -/* arch/arm/mach-msm/qdsp6/audiov2/audio_ctrl.c - * - * Copyright (C) 2009 Google, Inc. - * Copyright (C) 2009 HTC Corporation - * Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include - -#include - -#define BUFSZ (0) - -static DEFINE_MUTEX(voice_lock); -static int voice_started; - -static struct audio_client *voc_clnt; - -static int q6_voice_start(void) -{ - int rc = 0; - - mutex_lock(&voice_lock); - - if (voice_started) { - pr_err("voice: busy\n"); - rc = -EBUSY; - goto done; - } - - voc_clnt = q6voice_open(); - if (!voc_clnt) { - pr_err("voice: open voice failed.\n"); - rc = -ENOMEM; - goto done; - } - - voice_started = 1; -done: - mutex_unlock(&voice_lock); - return rc; -} - -static int q6_voice_stop(void) -{ - mutex_lock(&voice_lock); - if (voice_started) { - q6voice_close(voc_clnt); - voice_started = 0; - } - mutex_unlock(&voice_lock); - return 0; -} - -static int q6_open(struct inode *inode, struct file *file) -{ - return 0; -} - -static int q6_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - int rc; - uint32_t n; - uint32_t id[2]; - - switch (cmd) { - case AUDIO_SWITCH_DEVICE: - rc = copy_from_user(&n, (void *)arg, sizeof(n)); - if (!rc) - rc = q6audio_do_routing(n); - break; - case AUDIO_SET_VOLUME: - rc = copy_from_user(&n, (void *)arg, sizeof(n)); - if (!rc) - rc = q6audio_set_rx_volume(n); - break; - case AUDIO_SET_MUTE: - rc = copy_from_user(&n, (void *)arg, sizeof(n)); - if (!rc) - rc = q6audio_set_tx_mute(n); - break; - case AUDIO_UPDATE_ACDB: - rc = copy_from_user(&id, (void *)arg, sizeof(id)); - if (!rc) - rc = q6audio_update_acdb(id[0], id[1]); - break; - case AUDIO_START_VOICE: - rc = q6_voice_start(); - break; - case AUDIO_STOP_VOICE: - rc = q6_voice_stop(); - break; - default: - rc = -EINVAL; - } - - return rc; -} - - -static int q6_release(struct inode *inode, struct file *file) -{ - return 0; -} - -static const struct file_operations q6_dev_fops = { - .owner = THIS_MODULE, - .open = q6_open, - .ioctl = q6_ioctl, - .release = q6_release, -}; - -struct miscdevice q6_control_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_audio_ctl", - .fops = &q6_dev_fops, -}; - - -static int __init q6_audio_ctl_init(void) -{ - return misc_register(&q6_control_device); -} - -device_initcall(q6_audio_ctl_init); diff --git a/arch/arm/mach-msm/qdsp6/audiov2/dal_acdb.h b/arch/arm/mach-msm/qdsp6/audiov2/dal_acdb.h deleted file mode 100644 index b4949f9b16f77e69cf9fc4a28166c96701f5fe6d..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/audiov2/dal_acdb.h +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#define ACDB_DAL_DEVICE 0x02000069 -#define ACDB_DAL_PORT "DAL_AM_AUD" -#define ACDB_DAL_VERSION 0x00010000 - -#define ACDB_OP_IOCTL DAL_OP_FIRST_DEVICE_API - -/* ioctls */ -#define ACDB_GET_DEVICE 0x0108bb92 -#define ACDB_SET_DEVICE 0x0108bb93 -#define ACDB_GET_STREAM 0x0108bb95 -#define ACDB_SET_STREAM 0x0108bb96 -#define ACDB_GET_DEVICE_TABLE 0x0108bb97 -#define ACDB_GET_STREAM_TABLE 0x0108bb98 - -#define ACDB_RES_SUCCESS 0 -#define ACDB_RES_FAILURE -1 -#define ACDB_RES_BADPARM -2 -#define ACDB_RES_BADSTATE -3 - -struct acdb_cmd_device { - uint32_t size; - - uint32_t command_id; - uint32_t device_id; - uint32_t network_id; - uint32_t sample_rate_id; - uint32_t interface_id; - uint32_t algorithm_block_id; - - /* physical page aligned buffer */ - uint32_t total_bytes; - uint32_t unmapped_buf; -} __attribute__((packed)); - -struct acdb_cmd_device_table { - uint32_t size; - - uint32_t command_id; - uint32_t device_id; - uint32_t network_id; - uint32_t sample_rate_id; - - /* physical page aligned buffer */ - uint32_t total_bytes; - uint32_t unmapped_buf; - - uint32_t res_size; -} __attribute__((packed)); - -struct acdb_result { - uint32_t dal_status; - uint32_t size; - - uint32_t total_devices; - uint32_t unmapped_buf; - uint32_t used_bytes; - uint32_t result; -} __attribute__((packed)); diff --git a/arch/arm/mach-msm/qdsp6/audiov2/dal_adie.h b/arch/arm/mach-msm/qdsp6/audiov2/dal_adie.h deleted file mode 100644 index aac484c5732f9e11fa23a9e24b8e7387bc08c0da..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/audiov2/dal_adie.h +++ /dev/null @@ -1,89 +0,0 @@ -/* Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _MACH_MSM_QDSP6_ADIE_ -#define _MACH_MSM_QDSP6_ADIE_ - -#include "../dal.h" - -#define ADIE_DAL_DEVICE 0x02000029 -#define ADIE_DAL_PORT "DAL_AM_AUD" -#define ADIE_DAL_VERSION 0x00010000 - -enum { - ADIE_OP_SET_PATH = DAL_OP_FIRST_DEVICE_API, - ADIE_OP_PROCEED_TO_STAGE, - ADIE_OP_IOCTL -}; - -/* Path IDs for normal operation. */ -#define ADIE_PATH_HANDSET_TX 0x010740f6 -#define ADIE_PATH_HANDSET_RX 0x010740f7 -#define ADIE_PATH_HEADSET_MONO_TX 0x010740f8 -#define ADIE_PATH_HEADSET_STEREO_TX 0x010740f9 -#define ADIE_PATH_HEADSET_MONO_RX 0x010740fa -#define ADIE_PATH_HEADSET_STEREO_RX 0x010740fb -#define ADIE_PATH_SPEAKER_TX 0x010740fc -#define ADIE_PATH_SPEAKER_RX 0x010740fd -#define ADIE_PATH_SPEAKER_STEREO_RX 0x01074101 - -/* Path IDs used for TTY */ -#define ADIE_PATH_TTY_HEADSET_TX 0x010740fe -#define ADIE_PATH_TTY_HEADSET_RX 0x010740ff - -/* Path IDs used by Factory Test Mode. */ -#define ADIE_PATH_FTM_MIC1_TX 0x01074108 -#define ADIE_PATH_FTM_MIC2_TX 0x01074107 -#define ADIE_PATH_FTM_HPH_L_RX 0x01074106 -#define ADIE_PATH_FTM_HPH_R_RX 0x01074104 -#define ADIE_PATH_FTM_EAR_RX 0x01074103 -#define ADIE_PATH_FTM_SPKR_RX 0x01074102 - -/* Path IDs for Loopback */ -/* Path IDs used for Line in -> AuxPGA -> Line Out Stereo Mode*/ -#define ADIE_PATH_AUXPGA_LINEOUT_STEREO_LB 0x01074100 -/* Line in -> AuxPGA -> LineOut Mono */ -#define ADIE_PATH_AUXPGA_LINEOUT_MONO_LB 0x01073d82 -/* Line in -> AuxPGA -> Stereo Headphone */ -#define ADIE_PATH_AUXPGA_HDPH_STEREO_LB 0x01074109 -/* Line in -> AuxPGA -> Mono Headphone */ -#define ADIE_PATH_AUXPGA_HDPH_MONO_LB 0x01073d85 -/* Line in -> AuxPGA -> Earpiece */ -#define ADIE_PATH_AUXPGA_EAP_LB 0x01073d81 -/* Line in -> AuxPGA -> AuxOut */ -#define ADIE_PATH_AUXPGA_AUXOUT_LB 0x01073d86 - -/* Concurrency Profiles */ -#define ADIE_PATH_SPKR_STEREO_HDPH_MONO_RX 0x01073d83 -#define ADIE_PATH_SPKR_MONO_HDPH_MONO_RX 0x01073d84 -#define ADIE_PATH_SPKR_MONO_HDPH_STEREO_RX 0x01073d88 -#define ADIE_PATH_SPKR_STEREO_HDPH_STEREO_RX 0x01073d89 - -/* stages */ -#define ADIE_STAGE_PATH_OFF 0x0050 -#define ADIE_STAGE_DIGITAL_READY 0x0100 -#define ADIE_STAGE_DIGITAL_ANALOG_READY 0x1000 -#define ADIE_STAGE_ANALOG_OFF 0x0750 -#define ADIE_STAGE_DIGITAL_OFF 0x0600 - -/* path types */ -#define ADIE_PATH_RX 0 -#define ADIE_PATH_TX 1 -#define ADIE_PATH_LOOPBACK 2 - -/* mute states */ -#define ADIE_MUTE_OFF 0 -#define ADIE_MUTE_ON 1 - - -#endif diff --git a/arch/arm/mach-msm/qdsp6/audiov2/dal_audio.h b/arch/arm/mach-msm/qdsp6/audiov2/dal_audio.h deleted file mode 100644 index 2f9510bc9e334788e84803e80b4a36a164ca89ae..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/audiov2/dal_audio.h +++ /dev/null @@ -1,546 +0,0 @@ -/* Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __DAL_AUDIO_H__ -#define __DAL_AUDIO_H__ - -#include "../dal.h" -#include "dal_audio_format.h" - -#define AUDIO_DAL_DEVICE 0x02000028 -#define AUDIO_DAL_PORT "DAL_AQ_AUD" -#define AUDIO_DAL_VERSION 0x00030001 - -enum { - AUDIO_OP_CONTROL = DAL_OP_FIRST_DEVICE_API, - AUDIO_OP_DATA, - AUDIO_OP_INIT, -}; - -/* ---- common audio structures ---- */ - -/* This flag, if set, indicates that the beginning of the data in the*/ -/* buffer is a synchronization point or key frame, meaning no data */ -/* before it in the stream is required in order to render the stream */ -/* from this point onward. */ -#define ADSP_AUDIO_BUFFER_FLAG_SYNC_POINT 0x01 - -/* This flag, if set, indicates that the buffer object is using valid */ -/* physical address used to store the media data */ -#define ADSP_AUDIO_BUFFER_FLAG_PHYS_ADDR 0x04 - -/* This flag, if set, indicates that a media start timestamp has been */ -/* set for a buffer. */ -#define ADSP_AUDIO_BUFFER_FLAG_START_SET 0x08 - -/* This flag, if set, indicates that a media stop timestamp has been set */ -/* for a buffer. */ -#define ADSP_AUDIO_BUFFER_FLAG_STOP_SET 0x10 - -/* This flag, if set, indicates that a preroll timestamp has been set */ -/* for a buffer. */ -#define ADSP_AUDIO_BUFFER_FLAG_PREROLL_SET 0x20 - -/* This flag, if set, indicates that the data in the buffer is a fragment of */ -/* a larger block of data, and will be continued by the data in the next */ -/* buffer to be delivered. */ -#define ADSP_AUDIO_BUFFER_FLAG_CONTINUATION 0x40 - -struct adsp_audio_buffer { - u32 addr; /* Physical Address of buffer */ - u32 max_size; /* Maximum size of buffer */ - u32 actual_size; /* Actual size of valid data in the buffer */ - u32 offset; /* Offset to the first valid byte */ - u32 flags; /* ADSP_AUDIO_BUFFER_FLAGs that has been set */ - s64 start; /* Start timestamp, if any */ - s64 stop; /* Stop timestamp, if any */ - s64 preroll; /* Preroll timestamp, if any */ -} __attribute__ ((packed)); - - - -/* ---- audio commands ---- */ - -/* Command/event response types */ -#define ADSP_AUDIO_RESPONSE_COMMAND 0 -#define ADSP_AUDIO_RESPONSE_ASYNC 1 - -struct adsp_command_hdr { - u32 size; /* sizeof(cmd) - sizeof(u32) */ - - u32 dest; - u32 src; - u32 opcode; - u32 response_type; - u32 seq_number; - - u32 context; /* opaque to DSP */ - u32 data; - u32 padding; -} __attribute__ ((packed)); - - -#define DOMAIN_APP 0 -#define DOMAIN_MODEM 1 -#define DOMAIN_DSP 2 - - -/* adsp audio addresses are (byte order) major, minor, domain */ -#define AUDIO_ADDR(dmn, maj, min) (((maj & 0xff) << 16) \ - | ((min & 0xff) << 24) | (dmn & 0xff)) - -/* AAC Encoder modes */ -#define ADSP_AUDIO_ENC_AAC_LC_ONLY_MODE 0 -#define ADSP_AUDIO_ENC_AAC_PLUS_MODE 1 -#define ADSP_AUDIO_ENC_ENHANCED_AAC_PLUS_MODE 2 - -struct adsp_audio_aac_enc_cfg { - u32 bit_rate; /* bits per second */ - u32 encoder_mode; /* ADSP_AUDIO_ENC_* */ -} __attribute__ ((packed)); - -#define ADSP_AUDIO_ENC_SBC_ALLOCATION_METHOD_LOUNDNESS 0 -#define ADSP_AUDIO_ENC_SBC_ALLOCATION_METHOD_SNR 1 - -#define ADSP_AUDIO_ENC_SBC_CHANNEL_MODE_MONO 1 -#define ADSP_AUDIO_ENC_SBC_CHANNEL_MODE_STEREO 2 -#define ADSP_AUDIO_ENC_SBC_CHANNEL_MODE_DUAL 8 -#define ADSP_AUDIO_ENC_SBC_CHANNEL_MODE_JOINT_STEREO 9 - -struct adsp_audio_sbc_encoder_cfg { - u32 num_subbands; - u32 block_len; - u32 channel_mode; - u32 allocation_method; - u32 bit_rate; -} __attribute__ ((packed)); - -/* AMR NB encoder modes */ -#define ADSP_AUDIO_AMR_MR475 0 -#define ADSP_AUDIO_AMR_MR515 1 -#define ADSP_AUDIO_AMR_MMR59 2 -#define ADSP_AUDIO_AMR_MMR67 3 -#define ADSP_AUDIO_AMR_MMR74 4 -#define ADSP_AUDIO_AMR_MMR795 5 -#define ADSP_AUDIO_AMR_MMR102 6 -#define ADSP_AUDIO_AMR_MMR122 7 - -/* The following are valid AMR NB DTX modes */ -#define ADSP_AUDIO_AMR_DTX_MODE_OFF 0 -#define ADSP_AUDIO_AMR_DTX_MODE_ON_VAD1 1 -#define ADSP_AUDIO_AMR_DTX_MODE_ON_VAD2 2 -#define ADSP_AUDIO_AMR_DTX_MODE_ON_AUTO 3 - -/* AMR Encoder configuration */ -struct adsp_audio_amr_enc_cfg { - u32 mode; /* ADSP_AUDIO_AMR_MR* */ - u32 dtx_mode; /* ADSP_AUDIO_AMR_DTX_MODE* */ - u32 enable; /* 1 = enable, 0 = disable */ -} __attribute__ ((packed)); - -struct adsp_audio_qcelp13k_enc_cfg { - u16 min_rate; - u16 max_rate; -} __attribute__ ((packed)); - -struct adsp_audio_evrc_enc_cfg { - u16 min_rate; - u16 max_rate; -} __attribute__ ((packed)); - -union adsp_audio_codec_config { - struct adsp_audio_amr_enc_cfg amr; - struct adsp_audio_aac_enc_cfg aac; - struct adsp_audio_qcelp13k_enc_cfg qcelp13k; - struct adsp_audio_evrc_enc_cfg evrc; - struct adsp_audio_sbc_encoder_cfg sbc; -} __attribute__ ((packed)); - - -/* This is the default value. */ -#define ADSP_AUDIO_OPEN_STREAM_MODE_NONE 0x0000 - -/* This bit, if set, indicates that the AVSync mode is activated. */ -#define ADSP_AUDIO_OPEN_STREAM_MODE_AVSYNC 0x0001 - -/* This bit, if set, indicates that the Sample Rate/Channel Mode */ -/* Change Notification mode is activated. */ -#define ADSP_AUDIO_OPEN_STREAM_MODE_SR_CM_NOTIFY 0x0002 - -#define ADSP_AUDIO_OPEN_STREAM_MODE_ENABLE_SYNC_CLOCK 0x0004 - -#define ADSP_AUDIO_MAX_DEVICES 1 - -struct adsp_open_command { - struct adsp_command_hdr hdr; - u32 device; - u32 end_point; - u32 stream_context; - u32 mode; - u32 buf_max_size; - union adsp_audio_format format_block; - union adsp_audio_codec_config config; - -} __attribute__ ((packed)); - - -/* --- audio control and stream session ioctls ---- */ - -/* Opcode to open a device stream session to capture audio */ -#define ADSP_AUDIO_IOCTL_CMD_OPEN_READ 0x0108dd79 - -/* Opcode to open a device stream session to render audio */ -#define ADSP_AUDIO_IOCTL_CMD_OPEN_WRITE 0x0108dd7a - -/* Opcode to open a device session, must open a device */ -#define ADSP_AUDIO_IOCTL_CMD_OPEN_DEVICE 0x0108dd7b - -/* Close an existing stream or device */ -#define ADSP_AUDIO_IOCTL_CMD_CLOSE 0x0108d8bc - - - -/* A device switch requires three IOCTL */ -/* commands in the following sequence: PREPARE, STANDBY, COMMIT */ - -/* adsp_audio_device_switch_command structure is needed for */ -/* DEVICE_SWITCH_PREPARE */ - -/* Device switch protocol step #1. Pause old device and */ -/* generate silence for the old device. */ -#define ADSP_AUDIO_IOCTL_CMD_DEVICE_SWITCH_PREPARE 0x010815c4 - -/* Device switch protocol step #2. Release old device, */ -/* create new device and generate silence for the new device. */ - -/* When client receives ack for this IOCTL, the client can */ -/* start sending IOCTL commands to configure, calibrate and */ -/* change filter settings on the new device. */ -#define ADSP_AUDIO_IOCTL_CMD_DEVICE_SWITCH_STANDBY 0x010815c5 - -/* Device switch protocol step #3. Start normal operations on new device */ -#define ADSP_AUDIO_IOCTL_CMD_DEVICE_SWITCH_COMMIT 0x01075ee7 - -struct adsp_device_switch_command { - struct adsp_command_hdr hdr; - u32 old_device; - u32 new_device; - u8 device_class; /* 0 = i.rx, 1 = i.tx, 2 = e.rx, 3 = e.tx */ - u8 device_type; /* 0 = rx, 1 = tx, 2 = both */ -} __attribute__ ((packed)); - - - -/* --- audio control session ioctls ---- */ - -#define ADSP_PATH_RX 0 -#define ADSP_PATH_TX 1 -#define ADSP_PATH_BOTH 2 - -/* These commands will affect a logical device and all its associated */ -/* streams. */ - - -/* Set device volume. */ -#define ADSP_AUDIO_IOCTL_CMD_SET_DEVICE_VOL 0x0107605c - -struct adsp_set_dev_volume_command { - struct adsp_command_hdr hdr; - u32 device_id; - u32 path; /* 0 = rx, 1 = tx, 2 = both */ - s32 volume; -} __attribute__ ((packed)); - -/* Set Device stereo volume. This command has data payload, */ -/* struct adsp_audio_set_dev_stereo_volume_command. */ -#define ADSP_AUDIO_IOCTL_SET_DEVICE_STEREO_VOL 0x0108df3e - -/* Set L, R cross channel gain for a Device. This command has */ -/* data payload, struct adsp_audio_set_dev_x_chan_gain_command. */ -#define ADSP_AUDIO_IOCTL_SET_DEVICE_XCHAN_GAIN 0x0108df40 - -/* Set device mute state. */ -#define ADSP_AUDIO_IOCTL_CMD_SET_DEVICE_MUTE 0x0107605f - -struct adsp_set_dev_mute_command { - struct adsp_command_hdr hdr; - u32 device_id; - u32 path; /* 0 = rx, 1 = tx, 2 = both */ - u32 mute; /* 1 = mute */ -} __attribute__ ((packed)); - -/* Configure Equalizer for a device. */ -/* This command has payload struct adsp_audio_set_dev_equalizer_command. */ -#define ADSP_AUDIO_IOCTL_CMD_SET_DEVICE_EQ_CONFIG 0x0108b10e - -/* Set configuration data for an algorithm aspect of a device. */ -/* This command has payload struct adsp_audio_set_dev_cfg_command. */ -#define ADSP_AUDIO_IOCTL_SET_DEVICE_CONFIG 0x0108b6cb - -struct adsp_set_dev_cfg_command { - struct adsp_command_hdr hdr; - u32 device_id; - u32 block_id; - u32 interface_id; - u32 phys_addr; - u32 phys_size; - u32 phys_used; -} __attribute__ ((packed)); - -/* Set configuration data for all interfaces of a device. */ -#define ADSP_AUDIO_IOCTL_SET_DEVICE_CONFIG_TABLE 0x0108b6bf - -struct adsp_set_dev_cfg_table_command { - struct adsp_command_hdr hdr; - u32 device_id; - u32 phys_addr; - u32 phys_size; - u32 phys_used; -} __attribute__ ((packed)); - -/* ---- audio stream data commands ---- */ - -#define ADSP_AUDIO_IOCTL_CMD_DATA_TX 0x0108dd7f -#define ADSP_AUDIO_IOCTL_CMD_DATA_RX 0x0108dd80 - -struct adsp_buffer_command { - struct adsp_command_hdr hdr; - struct adsp_audio_buffer buffer; -} __attribute__ ((packed)); - - - -/* ---- audio stream ioctls (only affect a single stream in a session) ---- */ - -/* Stop stream for audio device. */ -#define ADSP_AUDIO_IOCTL_CMD_STREAM_STOP 0x01075c54 - -/* End of stream reached. Client will not send any more data. */ -#define ADSP_AUDIO_IOCTL_CMD_STREAM_EOS 0x0108b150 - -/* Do sample slipping/stuffing on AAC outputs. The payload of */ -/* this command is struct adsp_audio_slip_sample_command. */ -#define ADSP_AUDIO_IOCTL_CMD_STREAM_SLIPSAMPLE 0x0108d40e - -/* Set stream volume. */ -/* This command has data payload, struct adsp_audio_set_volume_command. */ -#define ADSP_AUDIO_IOCTL_CMD_SET_STREAM_VOL 0x0108c0de - -/* Set stream stereo volume. This command has data payload, */ -/* struct adsp_audio_set_stereo_volume_command. */ -#define ADSP_AUDIO_IOCTL_SET_STREAM_STEREO_VOL 0x0108dd7c - -/* Set L, R cross channel gain for a Stream. This command has */ -/* data payload, struct adsp_audio_set_x_chan_gain_command. */ -#define ADSP_AUDIO_IOCTL_SET_STREAM_XCHAN_GAIN 0x0108dd7d - -/* Set stream mute state. */ -/* This command has data payload, struct adsp_audio_set_stream_mute. */ -#define ADSP_AUDIO_IOCTL_CMD_SET_STREAM_MUTE 0x0108c0df - -/* Reconfigure bit rate information. This command has data */ -/* payload, struct adsp_audio_set_bit_rate_command */ -#define ADSP_AUDIO_IOCTL_SET_STREAM_BITRATE 0x0108ccf1 - -/* Set Channel Mapping. This command has data payload, struct */ -/* This command has data payload struct adsp_audio_set_channel_map_command. */ -#define ADSP_AUDIO_IOCTL_SET_STREAM_CHANNELMAP 0x0108d32a - -/* Enable/disable AACPlus SBR. */ -/* This command has data payload struct adsp_audio_set_sbr_command */ -#define ADSP_AUDIO_IOCTL_SET_STREAM_SBR 0x0108d416 - -/* Enable/disable WMA Pro Chex and Fex. This command has data payload */ -/* struct adsp_audio_stream_set_wma_command. */ -#define ADSP_AUDIO_IOCTL_SET_STREAM_WMAPRO 0x0108d417 - - -/* ---- audio session ioctls (affect all streams in a session) --- */ - -/* Start stream for audio device. */ -#define ADSP_AUDIO_IOCTL_CMD_SESSION_START 0x010815c6 - -/* Stop all stream(s) for audio session as indicated by major id. */ -#define ADSP_AUDIO_IOCTL_CMD_SESSION_STOP 0x0108dd7e - -/* Pause the data flow for a session as indicated by major id. */ -#define ADSP_AUDIO_IOCTL_CMD_SESSION_PAUSE 0x01075ee8 - -/* Resume the data flow for a session as indicated by major id. */ -#define ADSP_AUDIO_IOCTL_CMD_SESSION_RESUME 0x01075ee9 - -/* Drop any unprocessed data buffers for a session as indicated by major id. */ -#define ADSP_AUDIO_IOCTL_CMD_SESSION_FLUSH 0x01075eea - -/* Start Stream DTMF tone */ -#define ADSP_AUDIO_IOCTL_CMD_SESSION_DTMF_START 0x0108c0dd - -/* Stop Stream DTMF tone */ -#define ADSP_AUDIO_IOCTL_CMD_SESSION_DTMF_STOP 0x01087554 - -/* Set Session volume. */ -/* This command has data payload, struct adsp_audio_set_volume_command. */ -#define ADSP_AUDIO_IOCTL_SET_SESSION_VOL 0x0108d8bd - -/* Set session stereo volume. This command has data payload, */ -/* struct adsp_audio_set_stereo_volume_command. */ -#define ADSP_AUDIO_IOCTL_SET_SESSION_STEREO_VOL 0x0108df3d - -/* Set L, R cross channel gain for a session. This command has */ -/* data payload, struct adsp_audio_set_x_chan_gain_command. */ -#define ADSP_AUDIO_IOCTL_SET_SESSION_XCHAN_GAIN 0x0108df3f - -/* Set Session mute state. */ -/* This command has data payload, struct adsp_audio_set_mute_command. */ -#define ADSP_AUDIO_IOCTL_SET_SESSION_MUTE 0x0108d8be - -/* Configure Equalizer for a stream. */ -/* This command has payload struct adsp_audio_set_equalizer_command. */ -#define ADSP_AUDIO_IOCTL_SET_SESSION_EQ_CONFIG 0x0108c0e0 - -/* Set Audio Video sync information. */ -/* This command has data payload, struct adsp_audio_set_av_sync_command. */ -#define ADSP_AUDIO_IOCTL_SET_SESSION_AVSYNC 0x0108d1e2 - -/* Get Audio Media Session time. */ -/* This command returns the audioTime in adsp_audio_unsigned64_event */ -#define ADSP_AUDIO_IOCTL_CMD_GET_AUDIO_TIME 0x0108c26c - - -/* these command structures are used for both STREAM and SESSION ioctls */ - -struct adsp_set_volume_command { - struct adsp_command_hdr hdr; - s32 volume; -} __attribute__ ((packed)); - -struct adsp_set_mute_command { - struct adsp_command_hdr hdr; - u32 mute; /* 1 == mute */ -} __attribute__ ((packed)); - - - -/* ---- audio events ---- */ - -/* All IOCTL commands generate an event with the IOCTL opcode as the */ -/* event id after the IOCTL command has been executed. */ - -/* This event is generated after a media stream session is opened. */ -#define ADSP_AUDIO_EVT_STATUS_OPEN 0x0108c0d6 - -/* This event is generated after a media stream session is closed. */ -#define ADSP_AUDIO_EVT_STATUS_CLOSE 0x0108c0d7 - -/* Asyncronous buffer consumption. This event is generated after a */ -/* recived buffer is consumed during rendering or filled during */ -/* capture opeartion. */ -#define ADSP_AUDIO_EVT_STATUS_BUF_DONE 0x0108c0d8 - -/* This event is generated when rendering operation is starving for */ -/* data. In order to avoid audio loss at the end of a plauback, the */ -/* client should wait for this event before issuing the close command. */ -#define ADSP_AUDIO_EVT_STATUS_BUF_UNDERRUN 0x0108c0d9 - -/* This event is generated during capture operation when there are no */ -/* buffers available to copy the captured audio data */ -#define ADSP_AUDIO_EVT_STATUS_BUF_OVERFLOW 0x0108c0da - -/* This asynchronous event is generated as a result of an input */ -/* sample rate change and/or channel mode change detected by the */ -/* decoder. The event payload data is an array of 2 uint32 */ -/* values containing the sample rate in Hz and channel mode. */ -#define ADSP_AUDIO_EVT_SR_CM_CHANGE 0x0108d329 - -struct adsp_event_hdr { - u32 evt_handle; /* DAL common header */ - u32 evt_cookie; - u32 evt_length; - - u32 dest; - u32 src; - - u32 event_id; - u32 response_type; - u32 seq_number; - - u32 context; /* opaque to DSP */ - u32 data; - - u32 status; -} __attribute__ ((packed)); - -struct adsp_buffer_event { - struct adsp_event_hdr hdr; - struct adsp_audio_buffer buffer; -} __attribute__ ((packed)); - - -/* ---- audio device IDs ---- */ - -/* Device direction Rx/Tx flag */ -#define ADSP_AUDIO_RX_DEVICE 0x00 -#define ADSP_AUDIO_TX_DEVICE 0x01 - -#define ADSP_AUDIO_DEVICE_ID_DEFAULT 0x1081679 - -/* Default RX or TX device */ - -#define ADSP_AUDIO_DEVICE_ID_HANDSET_MIC 0x107ac8d -#define ADSP_AUDIO_DEVICE_ID_HANDSET_DUAL_MIC 0x108f9c3 -#define ADSP_AUDIO_DEVICE_ID_HEADSET_MIC 0x1081510 -#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MIC 0x1081512 -#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_DUAL_MIC 0x108f9c5 -#define ADSP_AUDIO_DEVICE_ID_BT_SCO_MIC 0x1081518 -#define ADSP_AUDIO_DEVICE_ID_TTY_HEADSET_MIC 0x108151b -#define ADSP_AUDIO_DEVICE_ID_I2S_MIC 0x1089bf3 - -/* Special loopback pseudo device to be paired with an RX device */ -/* with usage ADSP_AUDIO_DEVICE_USAGE_MIXED_PCM_LOOPBACK */ -#define ADSP_AUDIO_DEVICE_ID_MIXED_PCM_LOOPBACK_TX 0x1089bf2 - -/* Sink (RX) devices */ -#define ADSP_AUDIO_DEVICE_ID_HANDSET_SPKR 0x107ac88 -#define ADSP_AUDIO_DEVICE_ID_HEADSET_SPKR_MONO 0x1081511 -#define ADSP_AUDIO_DEVICE_ID_HEADSET_SPKR_STEREO 0x107ac8a -#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO 0x1081513 -#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO_W_MONO_HEADSET 0x108c508 -#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO_W_STEREO_HEADSET 0x108c894 -#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO 0x1081514 -#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO_W_MONO_HEADSET 0x108c895 -#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO_W_STEREO_HEADSET 0x108c509 -#define ADSP_AUDIO_DEVICE_ID_BT_SCO_SPKR 0x1081519 -#define ADSP_AUDIO_DEVICE_ID_TTY_HEADSET_SPKR 0x108151c -#define ADSP_AUDIO_DEVICE_ID_I2S_SPKR 0x1089bf4 -#define ADSP_AUDIO_DEVICE_ID_NULL_SINK 0x108e512 - -/* BT A2DP playback device. */ -/* This device must be paired with */ -/* ADSP_AUDIO_DEVICE_ID_MIXED_PCM_LOOPBACK_TX using */ -/* ADSP_AUDIO_DEVICE_USAGE_MIXED_PCM_LOOPBACK mode */ -#define ADSP_AUDIO_DEVICE_ID_BT_A2DP_SPKR 0x108151a - -/* Voice Destination identifier - specifically used for */ -/* controlling Voice module from the Device Control Session */ -#define ADSP_AUDIO_DEVICE_ID_VOICE 0x0108df3c - -/* Audio device usage types. */ -/* This is a bit mask to determine which topology to use in the */ -/* device session */ -#define ADSP_AUDIO_DEVICE_CONTEXT_VOICE 0x01 -#define ADSP_AUDIO_DEVICE_CONTEXT_PLAYBACK 0x02 -#define ADSP_AUDIO_DEVICE_CONTEXT_MIXED_RECORD 0x10 -#define ADSP_AUDIO_DEVICE_CONTEXT_RECORD 0x20 -#define ADSP_AUDIO_DEVICE_CONTEXT_PCM_LOOPBACK 0x40 - -#endif diff --git a/arch/arm/mach-msm/qdsp6/audiov2/dal_audio_format.h b/arch/arm/mach-msm/qdsp6/audiov2/dal_audio_format.h deleted file mode 100644 index 218fa535b6c2918558de5e329b19cfbff223009f..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/audiov2/dal_audio_format.h +++ /dev/null @@ -1,284 +0,0 @@ -/* Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __ADSP_AUDIO_MEDIA_FORMAT_H -#define __ADSP_AUDIO_MEDIA_FORMAT_H - -/* Supported audio media formats */ - -/* format block in shmem */ -#define ADSP_AUDIO_FORMAT_SHAREDMEMORY 0x01091a78 - -/* adsp_audio_format_raw_pcm type */ -#define ADSP_AUDIO_FORMAT_PCM 0x0103d2fd - -/* adsp_audio_format_raw_pcm type */ -#define ADSP_AUDIO_FORMAT_DTMF 0x01087725 - -/* adsp_audio_format_adpcm type */ -#define ADSP_AUDIO_FORMAT_ADPCM 0x0103d2ff - -/* Yamaha PCM format */ -#define ADSP_AUDIO_FORMAT_YADPCM 0x0108dc07 - -/* ISO/IEC 11172 */ -#define ADSP_AUDIO_FORMAT_MP3 0x0103d308 - -/* ISO/IEC 14496 */ -#define ADSP_AUDIO_FORMAT_MPEG4_AAC 0x010422f1 - -/* AMR-NB audio in FS format */ -#define ADSP_AUDIO_FORMAT_AMRNB_FS 0x0105c16c - -/* AMR-WB audio in FS format */ -#define ADSP_AUDIO_FORMAT_AMRWB_FS 0x0105c16e - -/* QCELP 13k, IS733 */ -#define ADSP_AUDIO_FORMAT_V13K_FS 0x01080b8a - -/* EVRC 8k, IS127 */ -#define ADSP_AUDIO_FORMAT_EVRC_FS 0x01080b89 - -/* EVRC-B 8k, 4GV */ -#define ADSP_AUDIO_FORMAT_EVRCB_FS 0x0108f2a3 - -/* MIDI command stream */ -#define ADSP_AUDIO_FORMAT_MIDI 0x0103d300 - -/* A2DP SBC stream */ -#define ADSP_AUDIO_FORMAT_SBC 0x0108c4d8 - -/* Version 10 Professional */ -#define ADSP_AUDIO_FORMAT_WMA_V10PRO 0x0108aa92 - -/* Version 9 Starndard */ -#define ADSP_AUDIO_FORMAT_WMA_V9 0x0108d430 - -/* AMR WideBand Plus */ -#define ADSP_AUDIO_FORMAT_AMR_WB_PLUS 0x0108f3da - -/* AC3 Decoder */ -#define ADSP_AUDIO_FORMAT_AC3_DECODER 0x0108d5f9 - -/* Not yet supported audio media formats */ - -/* ISO/IEC 13818 */ -#define ADSP_AUDIO_FORMAT_MPEG2_AAC 0x0103d309 - -/* 3GPP TS 26.101 Sec 4.0 */ -#define ADSP_AUDIO_FORMAT_AMRNB_IF1 0x0103d305 - -/* 3GPP TS 26.101 Annex A */ -#define ADSP_AUDIO_FORMAT_AMRNB_IF2 0x01057b31 - -/* 3GPP TS 26.201 */ -#define ADSP_AUDIO_FORMAT_AMRWB_IF1 0x0103d306 - -/* 3GPP TS 26.201 */ -#define ADSP_AUDIO_FORMAT_AMRWB_IF2 0x0105c16d - -/* G.711 */ -#define ADSP_AUDIO_FORMAT_G711 0x0106201d - -/* QCELP 8k, IS96A */ -#define ADSP_AUDIO_FORMAT_V8K_FS 0x01081d29 - -/* Version 1 codec */ -#define ADSP_AUDIO_FORMAT_WMA_V1 0x01055b2b - -/* Version 2, 7 & 8 codec */ -#define ADSP_AUDIO_FORMAT_WMA_V8 0x01055b2c - -/* Version 9 Professional codec */ -#define ADSP_AUDIO_FORMAT_WMA_V9PRO 0x01055b2d - -/* Version 9 Voice codec */ -#define ADSP_AUDIO_FORMAT_WMA_SP1 0x01055b2e - -/* Version 9 Lossless codec */ -#define ADSP_AUDIO_FORMAT_WMA_LOSSLESS 0x01055b2f - -/* Real Media content, low-bitrate */ -#define ADSP_AUDIO_FORMAT_RA_SIPR 0x01042a0f - -/* Real Media content */ -#define ADSP_AUDIO_FORMAT_RA_COOK 0x01042a0e - - -/* For all of the audio formats, unless specified otherwise, */ -/* the following apply: */ -/* Format block bits are arranged in bytes and words in little-endian */ -/* order, i.e., least-significant bit first and least-significant */ -/* byte first. */ - - -/* AAC Format Block. */ - -/* AAC format block consist of a format identifier followed by */ -/* AudioSpecificConfig formatted according to ISO/IEC 14496-3 */ - -/* The following AAC format identifiers are supported */ -#define ADSP_AUDIO_AAC_ADTS 0x010619cf -#define ADSP_AUDIO_AAC_MPEG4_ADTS 0x010619d0 -#define ADSP_AUDIO_AAC_LOAS 0x010619d1 -#define ADSP_AUDIO_AAC_ADIF 0x010619d2 -#define ADSP_AUDIO_AAC_RAW 0x010619d3 -#define ADSP_AUDIO_AAC_FRAMED_RAW 0x0108c1fb - -struct adsp_audio_no_payload_format { - /* Media Format Code (must always be first element) */ - u32 format; - /* no payload for this format type */ -} __attribute__ ((packed)); - -/* Maxmum number of bytes allowed in a format block */ -#define ADSP_AUDIO_FORMAT_DATA_MAX 16 - -/* For convenience, to be used as a standard format block */ -/* for various media types that don't need a unique format block */ -/* ie. PCM, DTMF, etc. */ -struct adsp_audio_standard_format { - /* Media Format Code (must always be first element) */ - u32 format; - - /* payload */ - u16 channels; - u16 bits_per_sample; - u32 sampling_rate; - u8 is_signed; - u8 is_interleaved; -} __attribute__ ((packed)); - -/* ADPCM format block */ -struct adsp_audio_adpcm_format { - /* Media Format Code (must always be first element) */ - u32 format; - - /* payload */ - u16 channels; - u16 bits_per_sample; - u32 sampling_rate; - u8 is_signed; - u8 is_interleaved; - u32 block_size; -} __attribute__ ((packed)); - -/* MIDI format block */ -struct adsp_audio_midi_format { - /* Media Format Code (must always be first element) */ - u32 format; - - /* payload */ - u32 sampling_rate; - u16 channels; - u16 mode; -} __attribute__ ((packed)); - -#define ADSP_AUDIO_COMPANDING_ALAW 0x10619cd -#define ADSP_AUDIO_COMPANDING_MLAW 0x10619ce - -/* G711 format block */ -struct adsp_audio_g711_format { - /* Media Format Code (must always be first element) */ - u32 format; - - /* payload */ - u32 companding; -} __attribute__ ((packed)); - - -struct adsp_audio_wma_pro_format { - /* Media Format Code (must always be first element) */ - u32 format; - - /* payload */ - u16 format_tag; - u16 channels; - u32 samples_per_sec; - u32 avg_bytes_per_sec; - u16 block_align; - u16 valid_bits_per_sample; - u32 channel_mask; - u16 encode_opt; - u16 advanced_encode_opt; - u32 advanced_encode_opt2; - u32 drc_peak_reference; - u32 drc_peak_target; - u32 drc_average_reference; - u32 drc_average_target; -} __attribute__ ((packed)); - -struct adsp_audio_amrwb_plus_format { - /* Media Format Code (must always be first element) */ - u32 format; - - /* payload */ - u32 size; - u32 version; - u32 channels; - u32 amr_band_mode; - u32 amr_dtx_mode; - u32 amr_frame_format; - u32 amr_isf_index; -} __attribute__ ((packed)); - -/* Binary Byte Stream Format */ -/* Binary format type that defines a byte stream, */ -/* can be used to specify any format (ie. AAC) */ -struct adsp_audio_binary_format { - /* Media Format Code (must always be first element) */ - u32 format; - - /* payload */ - /* number of bytes set in byte stream */ - u32 num_bytes; - /* Byte stream binary data */ - u8 data[ADSP_AUDIO_FORMAT_DATA_MAX]; -} __attribute__ ((packed)); - -struct adsp_audio_shared_memory_format { - /* Media Format Code (must always be first element) */ - u32 format; - - /* Number of bytes in shared memory */ - u32 len; - /* Phyisical address to data in shared memory */ - u32 address; -} __attribute__ ((packed)); - - -/* Union of all format types */ -union adsp_audio_format { - /* Basic format block with no payload */ - struct adsp_audio_no_payload_format no_payload; - /* Generic format block PCM, DTMF */ - struct adsp_audio_standard_format standard; - /* ADPCM format block */ - struct adsp_audio_adpcm_format adpcm; - /* MIDI format block */ - struct adsp_audio_midi_format midi; - /* G711 format block */ - struct adsp_audio_g711_format g711; - /* WmaPro format block */ - struct adsp_audio_wma_pro_format wma_pro; - /* WmaPro format block */ - struct adsp_audio_amrwb_plus_format amrwb_plus; - /* binary (byte stream) format block, used for AAC */ - struct adsp_audio_binary_format binary; - /* format block in shared memory */ - struct adsp_audio_shared_memory_format shared_mem; -}; - -#endif - - diff --git a/arch/arm/mach-msm/qdsp6/audiov2/dal_voice.h b/arch/arm/mach-msm/qdsp6/audiov2/dal_voice.h deleted file mode 100644 index 6836de4b3e928d6dfaae2208832347985b003311..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/audiov2/dal_voice.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __DAL_VOICE_H__ -#define __DAL_VOICE_H__ - -#define VOICE_DAL_DEVICE 0x02000075 -#define VOICE_DAL_PORT "DAL_AM_AUD" -#define VOICE_DAL_VERSION 0x00010000 - -#define APR_PKTV1_TYPE_EVENT_V 0 -#define APR_UNDEFINED -1 -#define APR_PKTV1_TYPE_MASK 0x00000010 -#define APR_PKTV1_TYPE_SHFT 4 - -#define APR_SET_BITMASK(mask, shift, value) \ - (((value) << (shift)) & (mask)) - -#define APR_SET_FIELD(field, value) \ - APR_SET_BITMASK((field##_MASK), (field##_SHFT), (value)) - - -enum { - VOICE_OP_INIT = DAL_OP_FIRST_DEVICE_API, - VOICE_OP_CONTROL, -}; - -struct apr_command_pkt { - uint32_t size; - uint32_t header; - uint16_t reserved1; - uint16_t src_addr; - uint16_t dst_addr; - uint16_t ret_addr; - uint32_t src_token; - uint32_t dst_token; - uint32_t ret_token; - uint32_t context; - uint32_t opcode; -} __attribute__ ((packed)); - - -#define APR_IBASIC_RSP_RESULT 0x00010000 - -#define APR_OP_CMD_CREATE 0x0001001B - -#define APR_OP_CMD_DESTROY 0x0001001C - -#define VOICE_OP_CMD_BRINGUP 0x0001001E - -#define VOICE_OP_CMD_TEARDOWN 0x0001001F - -#define VOICE_OP_CMD_SET_NETWORK 0x0001001D - -#define VOICE_OP_CMD_STREAM_SETUP 0x00010027 - -#define VOICE_OP_CMD_STREAM_TEARDOWN 0x00010028 - -#endif diff --git a/arch/arm/mach-msm/qdsp6/audiov2/evrc_in.c b/arch/arm/mach-msm/qdsp6/audiov2/evrc_in.c deleted file mode 100644 index 9c544552382e9dff38fa951df85a2911a63e82ac..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/audiov2/evrc_in.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright (C) 2009 Google, Inc. - * Copyright (C) 2009 HTC Corporation - * Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "dal_audio.h" -#include "dal_audio_format.h" -#include - - -struct evrc { - struct mutex lock; - struct msm_audio_evrc_enc_config cfg; - struct msm_audio_stream_config str_cfg; - struct audio_client *audio_client; -}; - - -static long q6_evrc_in_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct evrc *evrc = file->private_data; - struct adsp_open_command rpc; - int rc = 0; - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - memset(&stats, 0, sizeof(stats)); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - mutex_lock(&evrc->lock); - switch (cmd) { - case AUDIO_START: - if (evrc->audio_client) { - rc = -EBUSY; - break; - } else { - evrc->audio_client = q6audio_open(AUDIO_FLAG_READ, - evrc->str_cfg.buffer_size); - - if (!evrc->audio_client) { - kfree(evrc); - rc = -ENOMEM; - break; - } - } - - tx_clk_freq = 8000; - - memset(&rpc, 0, sizeof(rpc)); - - rpc.format_block.standard.format = ADSP_AUDIO_FORMAT_EVRC_FS; - rpc.format_block.standard.channels = 1; - rpc.format_block.standard.bits_per_sample = 16; - rpc.format_block.standard.sampling_rate = 8000; - rpc.format_block.standard.is_signed = 1; - rpc.format_block.standard.is_interleaved = 0; - - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_READ; - rpc.device = ADSP_AUDIO_DEVICE_ID_DEFAULT; - rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_RECORD; - rpc.buf_max_size = evrc->str_cfg.buffer_size; - rpc.config.evrc.min_rate = evrc->cfg.min_bit_rate; - rpc.config.evrc.max_rate = evrc->cfg.max_bit_rate; - - q6audio_start(evrc->audio_client, &rpc, sizeof(rpc)); - break; - case AUDIO_STOP: - break; - case AUDIO_FLUSH: - break; - case AUDIO_SET_VOLUME: - break; - case AUDIO_GET_STREAM_CONFIG: - if (copy_to_user((void *)arg, &evrc->str_cfg, - sizeof(struct msm_audio_stream_config))) - rc = -EFAULT; - break; - case AUDIO_SET_STREAM_CONFIG: - if (copy_from_user(&evrc->str_cfg, (void *)arg, - sizeof(struct msm_audio_stream_config))) { - rc = -EFAULT; - break; - } - - if (evrc->str_cfg.buffer_size < 23) { - pr_err("[%s:%s] Buffer size too small\n", __MM_FILE__, - __func__); - rc = -EINVAL; - break; - } - - if (evrc->str_cfg.buffer_count != 2) - pr_info("[%s:%s] Buffer count set to 2\n", __MM_FILE__, - __func__); - break; - case AUDIO_SET_EVRC_ENC_CONFIG: - if (copy_from_user(&evrc->cfg, (void *) arg, - sizeof(struct msm_audio_evrc_enc_config))) - rc = -EFAULT; - - if (evrc->cfg.min_bit_rate > 4 || evrc->cfg.min_bit_rate < 1) { - pr_err("[%s:%s] invalid min bitrate\n", __MM_FILE__, - __func__); - rc = -EINVAL; - } - if (evrc->cfg.max_bit_rate > 4 || evrc->cfg.max_bit_rate < 1) { - pr_err("[%s:%s] invalid max bitrate\n", __MM_FILE__, - __func__); - rc = -EINVAL; - } - break; - case AUDIO_GET_EVRC_ENC_CONFIG: - if (copy_to_user((void *) arg, &evrc->cfg, - sizeof(struct msm_audio_evrc_enc_config))) - rc = -EFAULT; - break; - - default: - rc = -EINVAL; - } - - mutex_unlock(&evrc->lock); - return rc; -} - -static int q6_evrc_in_open(struct inode *inode, struct file *file) -{ - struct evrc *evrc; - evrc = kmalloc(sizeof(struct evrc), GFP_KERNEL); - if (evrc == NULL) { - pr_err("[%s:%s] Could not allocate memory for evrc driver\n", - __MM_FILE__, __func__); - return -ENOMEM; - } - - mutex_init(&evrc->lock); - file->private_data = evrc; - evrc->audio_client = NULL; - evrc->str_cfg.buffer_size = 23; - evrc->str_cfg.buffer_count = 2; - evrc->cfg.cdma_rate = CDMA_RATE_FULL; - evrc->cfg.min_bit_rate = 1; - evrc->cfg.max_bit_rate = 4; - - return 0; -} - -static ssize_t q6_evrc_in_read(struct file *file, char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_client *ac; - struct audio_buffer *ab; - const char __user *start = buf; - struct evrc *evrc = file->private_data; - int xfer = 0; - int res; - - mutex_lock(&evrc->lock); - ac = evrc->audio_client; - if (!ac) { - res = -ENODEV; - goto fail; - } - while (count > xfer) { - ab = ac->buf + ac->cpu_buf; - - if (ab->used) - wait_event(ac->wait, (ab->used == 0)); - - xfer = ab->actual_size; - - if (copy_to_user(buf, ab->data, xfer)) { - res = -EFAULT; - goto fail; - } - - buf += xfer; - count -= xfer; - - ab->used = 1; - q6audio_read(ac, ab); - ac->cpu_buf ^= 1; - } - - res = buf - start; - -fail: - mutex_unlock(&evrc->lock); - - return res; -} - -static int q6_evrc_in_release(struct inode *inode, struct file *file) -{ - int rc = 0; - struct evrc *evrc = file->private_data; - - mutex_lock(&evrc->lock); - if (evrc->audio_client) - rc = q6audio_close(evrc->audio_client); - mutex_unlock(&evrc->lock); - kfree(evrc); - return rc; -} - -static const struct file_operations q6_evrc_in_fops = { - .owner = THIS_MODULE, - .open = q6_evrc_in_open, - .read = q6_evrc_in_read, - .release = q6_evrc_in_release, - .unlocked_ioctl = q6_evrc_in_ioctl, -}; - -struct miscdevice q6_evrc_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_evrc_in", - .fops = &q6_evrc_in_fops, -}; - -static int __init q6_evrc_in_init(void) -{ - return misc_register(&q6_evrc_in_misc); -} - -device_initcall(q6_evrc_in_init); diff --git a/arch/arm/mach-msm/qdsp6/audiov2/mp3.c b/arch/arm/mach-msm/qdsp6/audiov2/mp3.c deleted file mode 100644 index 7d9cfa2c6ca3f18e927b3cd2206800fd308d2144..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/audiov2/mp3.c +++ /dev/null @@ -1,205 +0,0 @@ -/* arch/arm/mach-msm/qdsp6/audiov2/mp3.c - * - * Copyright (C) 2009 Google, Inc. - * Copyright (C) 2009 HTC Corporation - * Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include "dal_audio.h" -#include "dal_audio_format.h" - -#define BUFSZ (8192) -#define DMASZ (BUFSZ * 2) - -struct mp3 { - struct mutex lock; - struct audio_client *ac; - struct msm_audio_config cfg; -}; - -static long mp3_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct mp3 *mp3 = file->private_data; - struct adsp_open_command rpc; - int rc = 0; - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - memset(&stats, 0, sizeof(stats)); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - mutex_lock(&mp3->lock); - switch (cmd) { - case AUDIO_SET_VOLUME: - break; - case AUDIO_START: - memset(&rpc, 0, sizeof(rpc)); - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_WRITE; - rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_PLAYBACK; - rpc.device = ADSP_AUDIO_DEVICE_ID_DEFAULT; - rpc.format_block.standard.format = ADSP_AUDIO_FORMAT_MP3; - rpc.format_block.standard.channels = mp3->cfg.channel_count; - rpc.format_block.standard.bits_per_sample = 16; - rpc.format_block.standard.sampling_rate = mp3->cfg.sample_rate; - rpc.format_block.standard.is_signed = 1; - rpc.format_block.standard.is_interleaved = 0; - rpc.buf_max_size = BUFSZ; - q6audio_start(mp3->ac, (void *) &rpc, sizeof(rpc)); - break; - case AUDIO_STOP: - break; - case AUDIO_FLUSH: - break; - case AUDIO_SET_CONFIG: - if (copy_from_user(&mp3->cfg, (void *) arg, - sizeof(struct msm_audio_config))) { - rc = -EFAULT; - break; - } - if (mp3->cfg.channel_count < 1 || mp3->cfg.channel_count > 2) { - rc = -EINVAL; - break; - } - break; - case AUDIO_GET_CONFIG: - if (copy_to_user((void *) arg, &mp3->cfg, - sizeof(struct msm_audio_config))) { - rc = -EFAULT; - } - break; - default: - rc = -EINVAL; - } - mutex_unlock(&mp3->lock); - return rc; -} - -static int mp3_open(struct inode *inode, struct file *file) -{ - - struct mp3 *mp3; - mp3 = kzalloc(sizeof(struct mp3), GFP_KERNEL); - - if (!mp3) - return -ENOMEM; - - mutex_init(&mp3->lock); - file->private_data = mp3; - mp3->ac = q6audio_open(AUDIO_FLAG_WRITE, BUFSZ); - if (!mp3->ac) { - kfree(mp3); - return -ENOMEM; - } - mp3->cfg.channel_count = 2; - mp3->cfg.buffer_count = 2; - mp3->cfg.buffer_size = BUFSZ; - mp3->cfg.unused[0] = 0; - mp3->cfg.unused[1] = 0; - mp3->cfg.unused[2] = 0; - mp3->cfg.sample_rate = 48000; - - return 0; -} - -static ssize_t mp3_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct mp3 *mp3 = file->private_data; - struct audio_client *ac; - struct audio_buffer *ab; - const char __user *start = buf; - int xfer; - - if (!mp3->ac) - mp3_ioctl(file, AUDIO_START, 0); - - ac = mp3->ac; - if (!ac) - return -ENODEV; - - while (count > 0) { - ab = ac->buf + ac->cpu_buf; - - if (ab->used) - wait_event(ac->wait, (ab->used == 0)); - - xfer = count; - if (xfer > ab->size) - xfer = ab->size; - - if (copy_from_user(ab->data, buf, xfer)) - return -EFAULT; - - buf += xfer; - count -= xfer; - - ab->used = xfer; - q6audio_write(ac, ab); - ac->cpu_buf ^= 1; - } - - return buf - start; -} - -static int mp3_fsync(struct file *f, int datasync) -{ - struct mp3 *mp3 = f->private_data; - if (mp3->ac) - return q6audio_async(mp3->ac); - return -ENODEV; -} - -static int mp3_release(struct inode *inode, struct file *file) -{ - struct mp3 *mp3 = file->private_data; - if (mp3->ac) - q6audio_close(mp3->ac); - kfree(mp3); - return 0; -} - -static const struct file_operations mp3_fops = { - .owner = THIS_MODULE, - .open = mp3_open, - .write = mp3_write, - .fsync = mp3_fsync, - .release = mp3_release, - .unlocked_ioctl = mp3_ioctl, -}; - -struct miscdevice mp3_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_mp3", - .fops = &mp3_fops, -}; - -static int __init mp3_init(void) -{ - return misc_register(&mp3_misc); -} - -device_initcall(mp3_init); diff --git a/arch/arm/mach-msm/qdsp6/audiov2/pcm_in.c b/arch/arm/mach-msm/qdsp6/audiov2/pcm_in.c deleted file mode 100644 index 4de21995a5f5f07eab33c1511ec12b70f7386207..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/audiov2/pcm_in.c +++ /dev/null @@ -1,208 +0,0 @@ -/* arch/arm/mach-msm/qdsp6/audiov2/pcm_in.c - * - * Copyright (C) 2009 Google, Inc. - * Copyright (C) 2009 HTC Corporation - * Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include "dal_audio.h" -#include "dal_audio_format.h" - -#define BUFSZ (4096) -#define DMASZ (BUFSZ * 2) - - -struct pcm { - struct mutex lock; - struct msm_audio_config cfg; - struct audio_client *audio_client; -}; - -static long q6_in_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct pcm *pcm = file->private_data; - struct adsp_open_command rpc; - int rc = 0; - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - memset(&stats, 0, sizeof(stats)); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - mutex_lock(&pcm->lock); - switch (cmd) { - - case AUDIO_START: - tx_clk_freq = pcm->cfg.sample_rate; - - memset(&rpc, 0, sizeof(rpc)); - - rpc.format_block.standard.format = ADSP_AUDIO_FORMAT_PCM; - rpc.format_block.standard.channels = pcm->cfg.channel_count; - rpc.format_block.standard.bits_per_sample = 16; - rpc.format_block.standard.sampling_rate = pcm->cfg.sample_rate; - rpc.format_block.standard.is_signed = 1; - rpc.format_block.standard.is_interleaved = 1; - - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_READ; - rpc.device = ADSP_AUDIO_DEVICE_ID_DEFAULT; - rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_RECORD; - rpc.buf_max_size = BUFSZ; - q6audio_start(pcm->audio_client, &rpc, sizeof(rpc)); - break; - case AUDIO_STOP: - break; - case AUDIO_FLUSH: - break; - case AUDIO_SET_VOLUME: - break; - case AUDIO_SET_CONFIG: - if (copy_from_user(&pcm->cfg, (void *) arg, - sizeof(struct msm_audio_config))) { - rc = -EFAULT; - break; - } - break; - case AUDIO_GET_CONFIG: - if (copy_to_user((void *) arg, &pcm->cfg, - sizeof(struct msm_audio_config))) { - rc = -EFAULT; - } - break; - default: - rc = -EINVAL; - } - - mutex_unlock(&pcm->lock); - return rc; -} - -static int q6_in_open(struct inode *inode, struct file *file) -{ - - struct pcm *pcm; - pcm = kmalloc(sizeof(struct pcm), GFP_KERNEL); - if (pcm == NULL) { - pr_err("Could not allocate memory for pcm driver\n"); - return -ENOMEM; - } - mutex_init(&pcm->lock); - file->private_data = pcm; - pcm->audio_client = q6audio_open(AUDIO_FLAG_READ, BUFSZ); - if (!pcm->audio_client) { - kfree(pcm); - return -ENOMEM; - } - pcm->cfg.channel_count = 1; - pcm->cfg.buffer_count = 2; - pcm->cfg.buffer_size = BUFSZ; - pcm->cfg.unused[0] = 0; - pcm->cfg.unused[1] = 0; - pcm->cfg.unused[2] = 0; - pcm->cfg.sample_rate = 8000; - - return 0; -} - -static ssize_t q6_in_read(struct file *file, char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_client *ac; - struct audio_buffer *ab; - const char __user *start = buf; - struct pcm *pcm = file->private_data; - int xfer; - int res; - - mutex_lock(&pcm->lock); - ac = pcm->audio_client; - if (!ac) { - res = -ENODEV; - goto fail; - } - while (count > 0) { - ab = ac->buf + ac->cpu_buf; - - if (ab->used) - wait_event(ac->wait, (ab->used == 0)); - - xfer = count; - if (xfer > ab->size) - xfer = ab->size; - - if (copy_to_user(buf, ab->data, xfer)) { - res = -EFAULT; - goto fail; - } - - buf += xfer; - count -= xfer; - - ab->used = 1; - q6audio_read(ac, ab); - ac->cpu_buf ^= 1; - } -fail: - res = buf - start; - mutex_unlock(&pcm->lock); - - return res; -} - -static int q6_in_release(struct inode *inode, struct file *file) -{ - int rc = 0; - struct pcm *pcm = file->private_data; - - mutex_lock(&pcm->lock); - if (pcm->audio_client) - rc = q6audio_close(pcm->audio_client); - mutex_unlock(&pcm->lock); - kfree(pcm); - return rc; -} - -static const struct file_operations q6_in_fops = { - .owner = THIS_MODULE, - .open = q6_in_open, - .read = q6_in_read, - .release = q6_in_release, - .unlocked_ioctl = q6_in_ioctl, -}; - -struct miscdevice q6_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_pcm_in", - .fops = &q6_in_fops, -}; - -static int __init q6_in_init(void) -{ - return misc_register(&q6_in_misc); -} - -device_initcall(q6_in_init); diff --git a/arch/arm/mach-msm/qdsp6/audiov2/pcm_out.c b/arch/arm/mach-msm/qdsp6/audiov2/pcm_out.c deleted file mode 100644 index effd11906dc17ff3b61087c8982a9c25b2a45ac4..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/audiov2/pcm_out.c +++ /dev/null @@ -1,196 +0,0 @@ -/* arch/arm/mach-msm/qdsp6/audiov2/pcm_out.c - * - * Copyright (C) 2009 Google, Inc. - * Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * Author: Brian Swetland - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include "dal_audio.h" -#include "dal_audio_format.h" - -#define BUFSZ (8192) -#define DMASZ (BUFSZ * 2) - -struct pcm { - struct mutex lock; - struct audio_client *ac; - struct msm_audio_config cfg; - -}; - -static long pcm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct pcm *pcm = file->private_data; - struct adsp_open_command rpc; - int rc = 0; - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - memset(&stats, 0, sizeof(stats)); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - mutex_lock(&pcm->lock); - switch (cmd) { - case AUDIO_START: - memset(&rpc, 0, sizeof(rpc)); - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_WRITE; - rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_PLAYBACK; - rpc.device = ADSP_AUDIO_DEVICE_ID_DEFAULT; - rpc.format_block.standard.format = ADSP_AUDIO_FORMAT_PCM; - rpc.format_block.standard.channels = pcm->cfg.channel_count; - rpc.format_block.standard.bits_per_sample = 16; - rpc.format_block.standard.sampling_rate = pcm->cfg.sample_rate; - rpc.format_block.standard.is_signed = 1; - rpc.format_block.standard.is_interleaved = 1; - rpc.buf_max_size = BUFSZ; - q6audio_start(pcm->ac, (void *) &rpc, sizeof(rpc)); - break; - case AUDIO_STOP: - break; - case AUDIO_FLUSH: - break; - case AUDIO_SET_CONFIG: - if (copy_from_user(&pcm->cfg, (void *) arg, - sizeof(struct msm_audio_config))) { - rc = -EFAULT; - break; - } - if (pcm->cfg.channel_count < 1 || pcm->cfg.channel_count > 2) { - rc = -EINVAL; - break; - } - - break; - case AUDIO_GET_CONFIG: - if (copy_to_user((void *) arg, &pcm->cfg, - sizeof(struct msm_audio_config))) { - rc = -EFAULT; - } - break; - - default: - rc = -EINVAL; - } - - mutex_unlock(&pcm->lock); - return rc; -} - -static int pcm_open(struct inode *inode, struct file *file) -{ - struct pcm *pcm; - pcm = kzalloc(sizeof(struct pcm), GFP_KERNEL); - - if (!pcm) - return -ENOMEM; - - mutex_init(&pcm->lock); - file->private_data = pcm; - pcm->ac = q6audio_open(AUDIO_FLAG_WRITE, BUFSZ); - if (!pcm->ac) { - kfree(pcm); - return -ENOMEM; - } - pcm->cfg.channel_count = 2; - pcm->cfg.buffer_count = 2; - pcm->cfg.buffer_size = BUFSZ; - pcm->cfg.unused[0] = 0; - pcm->cfg.unused[1] = 0; - pcm->cfg.unused[2] = 0; - pcm->cfg.sample_rate = 48000; - - return 0; -} - -static ssize_t pcm_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct pcm *pcm = file->private_data; - struct audio_client *ac; - struct audio_buffer *ab; - const char __user *start = buf; - int xfer; - - ac = pcm->ac; - if (!ac) - return -ENODEV; - - while (count > 0) { - ab = ac->buf + ac->cpu_buf; - - if (ab->used) - wait_event(ac->wait, (ab->used == 0)); - - xfer = count; - if (xfer > ab->size) - xfer = ab->size; - - if (copy_from_user(ab->data, buf, xfer)) - return -EFAULT; - - buf += xfer; - count -= xfer; - - ab->used = 1; - ab->actual_size = xfer; - q6audio_write(ac, ab); - ac->cpu_buf ^= 1; - } - - return buf - start; -} - -static int pcm_release(struct inode *inode, struct file *file) -{ - struct pcm *pcm = file->private_data; - if (pcm->ac) - q6audio_close(pcm->ac); - kfree(pcm); - return 0; -} - -static const struct file_operations pcm_fops = { - .owner = THIS_MODULE, - .open = pcm_open, - .write = pcm_write, - .release = pcm_release, - .unlocked_ioctl = pcm_ioctl, -}; - -struct miscdevice pcm_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_pcm_out", - .fops = &pcm_fops, -}; - -static int __init pcm_init(void) -{ - return misc_register(&pcm_misc); -} - -device_initcall(pcm_init); diff --git a/arch/arm/mach-msm/qdsp6/audiov2/q6audio.c b/arch/arm/mach-msm/qdsp6/audiov2/q6audio.c deleted file mode 100644 index 589586780110e895156b018fa939f3c8df7f3a5c..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/audiov2/q6audio.c +++ /dev/null @@ -1,1316 +0,0 @@ -/* arch/arm/mach-msm/qdsp6/audiov2/q6audio.c - * - * Copyright (C) 2009 Google, Inc. - * Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * Author: Brian Swetland - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "../dal.h" -#include "dal_audio.h" -#include "dal_audio_format.h" -#include "dal_acdb.h" -#include "dal_adie.h" -#include "q6audio_devices.h" - -struct q6_hw_info { - int min_gain; - int max_gain; -}; - -/* TODO: provide mechanism to configure from board file */ - -static struct q6_hw_info q6_audio_hw[Q6_HW_COUNT] = { - [Q6_HW_HANDSET] = { - .min_gain = -2000, - .max_gain = 0, - }, - [Q6_HW_HEADSET] = { - .min_gain = -2000, - .max_gain = 0, - }, - [Q6_HW_SPEAKER] = { - .min_gain = -1500, - .max_gain = 0, - }, - [Q6_HW_TTY] = { - .min_gain = -2000, - .max_gain = 0, - }, - [Q6_HW_BT_SCO] = { - .min_gain = -2000, - .max_gain = 0, - }, - [Q6_HW_BT_A2DP] = { - .min_gain = -2000, - .max_gain = 0, - }, -}; - -static struct pm_qos_request pm_qos_req; -static int idlecount; -static DEFINE_MUTEX(idlecount_lock); - -void audio_prevent_sleep(void) -{ - mutex_lock(&idlecount_lock); - if (++idlecount == 1) - pm_qos_update_request(&pm_qos_req, - msm_cpuidle_get_deep_idle_latency()); - mutex_unlock(&idlecount_lock); -} - -void audio_allow_sleep(void) -{ - mutex_lock(&idlecount_lock); - if (--idlecount == 0) - pm_qos_update_request(&pm_qos_req, PM_QOS_DEFAULT_VALUE); - mutex_unlock(&idlecount_lock); -} - -static struct clk *icodec_rx_clk; -static struct clk *icodec_tx_clk; -static struct clk *ecodec_clk; -static struct clk *sdac_clk; - -static struct q6audio_analog_ops default_analog_ops; -static struct q6audio_analog_ops *analog_ops = &default_analog_ops; -uint32_t tx_clk_freq = 8000; -static int tx_mute_status; - -void q6audio_register_analog_ops(struct q6audio_analog_ops *ops) -{ - analog_ops = ops; -} - -static struct q6_device_info *q6_lookup_device(uint32_t device_id) -{ - struct q6_device_info *di = q6_audio_devices; - for (;;) { - if (di->id == device_id) - return di; - if (di->id == 0) { - pr_err("q6_lookup_device: bogus id 0x%08x\n", - device_id); - return di; - } - di++; - } -} - -static uint32_t q6_device_to_codec(uint32_t device_id) -{ - struct q6_device_info *di = q6_lookup_device(device_id); - return di->codec; -} - -static uint32_t q6_device_to_dir(uint32_t device_id) -{ - struct q6_device_info *di = q6_lookup_device(device_id); - return di->dir; -} - -static uint32_t q6_device_to_cad_id(uint32_t device_id) -{ - struct q6_device_info *di = q6_lookup_device(device_id); - return di->cad_id; -} - -static uint32_t q6_device_to_path(uint32_t device_id) -{ - struct q6_device_info *di = q6_lookup_device(device_id); - return di->path; -} - -static uint32_t q6_device_to_rate(uint32_t device_id) -{ - struct q6_device_info *di = q6_lookup_device(device_id); - return di->rate; -} - -int q6_device_volume(uint32_t device_id, int level) -{ - struct q6_device_info *di = q6_lookup_device(device_id); - struct q6_hw_info *hw; - - hw = &q6_audio_hw[di->hw]; - - return hw->min_gain + ((hw->max_gain - hw->min_gain) * level) / 100; -} - -static inline int adie_open(struct dal_client *client) -{ - return dal_call_f0(client, DAL_OP_OPEN, 0); -} - -static inline int adie_close(struct dal_client *client) -{ - return dal_call_f0(client, DAL_OP_CLOSE, 0); -} - -static inline int adie_set_path(struct dal_client *client, - uint32_t *adie_params, uint32_t size) -{ - uint32_t tmp; - return dal_call(client, ADIE_OP_SET_PATH, 5, adie_params, size, - (void *)&tmp, sizeof(uint32_t)); - -} - -static inline int adie_proceed_to_stage(struct dal_client *client, - uint32_t path_type, uint32_t stage) -{ - return dal_call_f1(client, ADIE_OP_PROCEED_TO_STAGE, - path_type, stage); -} - -static int adie_refcount; - -static struct dal_client *adie; -static struct dal_client *adsp; -static struct dal_client *acdb; - -static int adie_enable(void) -{ - adie_refcount++; - if (adie_refcount == 1) - adie_open(adie); - return 0; -} - -static int adie_disable(void) -{ - adie_refcount--; - if (adie_refcount == 0) - adie_close(adie); - return 0; -} - -/* 4k DMA scratch page used for exchanging acdb device config tables - * and stream format descriptions with the DSP. - */ -char *audio_data; -int32_t audio_phys; - -#define SESSION_MIN 0 -#define SESSION_MAX 64 - -static DEFINE_MUTEX(session_lock); -static DEFINE_MUTEX(audio_lock); - -static struct audio_client *session[SESSION_MAX]; - -static int session_alloc(struct audio_client *ac) -{ - int n; - - mutex_lock(&session_lock); - for (n = SESSION_MIN; n < SESSION_MAX; n++) { - if (!session[n]) { - session[n] = ac; - mutex_unlock(&session_lock); - return n; - } - } - mutex_unlock(&session_lock); - return -ENOMEM; -} - -static void session_free(int n, struct audio_client *ac) -{ - mutex_lock(&session_lock); - if (session[n] == ac) - session[n] = 0; - mutex_unlock(&session_lock); -} - -static void audio_client_free(struct audio_client *ac) -{ - session_free(ac->session, ac); - - if (ac->buf[0].data) - pmem_kfree(ac->buf[0].phys); - if (ac->buf[1].data) - pmem_kfree(ac->buf[1].phys); - kfree(ac); -} - -static struct audio_client *audio_client_alloc(unsigned bufsz) -{ - struct audio_client *ac; - int n; - - ac = kzalloc(sizeof(*ac), GFP_KERNEL); - if (!ac) - return 0; - - n = session_alloc(ac); - if (n < 0) - goto fail_session; - ac->session = n; - - if (bufsz > 0) { - ac->buf[0].phys = pmem_kalloc(bufsz, - PMEM_MEMTYPE_EBI1|PMEM_ALIGNMENT_4K); - ac->buf[0].data = ioremap(ac->buf[0].phys, bufsz); - if (!ac->buf[0].data) - goto fail; - - ac->buf[1].phys = pmem_kalloc(bufsz, - PMEM_MEMTYPE_EBI1|PMEM_ALIGNMENT_4K); - ac->buf[1].data = ioremap(ac->buf[1].phys, bufsz); - if (!ac->buf[1].data) - goto fail; - - ac->buf[0].size = bufsz; - ac->buf[1].size = bufsz; - } - - init_waitqueue_head(&ac->wait); - ac->client = adsp; - - return ac; - -fail: - pr_err("pmem_kalloc failed\n"); - session_free(n, ac); -fail_session: - audio_client_free(ac); - return 0; -} - -static int audio_ioctl(struct audio_client *ac, void *ptr, uint32_t len) -{ - struct adsp_command_hdr *hdr = ptr; - uint32_t tmp; - int r; - - hdr->size = len - sizeof(u32); - hdr->dest = AUDIO_ADDR(DOMAIN_DSP, ac->session, 0); - hdr->src = AUDIO_ADDR(DOMAIN_APP, ac->session, 0); - hdr->context = ac->session; - ac->cb_status = -EBUSY; - r = dal_call(ac->client, AUDIO_OP_CONTROL, 5, ptr, len, - &tmp, sizeof(tmp)); - if (r != 4) - return -EIO; - wait_event(ac->wait, (ac->cb_status != -EBUSY)); - return tmp; -} - -static int audio_command(struct audio_client *ac, uint32_t cmd) -{ - struct adsp_command_hdr rpc; - memset(&rpc, 0, sizeof(rpc)); - rpc.opcode = cmd; - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -static int audio_open_control(struct audio_client *ac) -{ - struct adsp_open_command rpc; - - memset(&rpc, 0, sizeof(rpc)); - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_DEVICE; - rpc.hdr.dest = AUDIO_ADDR(DOMAIN_DSP, ac->session, 0); - rpc.hdr.src = AUDIO_ADDR(DOMAIN_APP, ac->session, 0); - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - - -static int audio_close(struct audio_client *ac) -{ - audio_command(ac, ADSP_AUDIO_IOCTL_CMD_STREAM_STOP); - audio_command(ac, ADSP_AUDIO_IOCTL_CMD_CLOSE); - return 0; -} - -static int audio_set_table(struct audio_client *ac, - uint32_t device_id, int size) -{ - struct adsp_set_dev_cfg_table_command rpc; - - memset(&rpc, 0, sizeof(rpc)); - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_SET_DEVICE_CONFIG_TABLE; - rpc.hdr.dest = AUDIO_ADDR(DOMAIN_DSP, ac->session, 0); - rpc.hdr.src = AUDIO_ADDR(DOMAIN_APP, ac->session, 0); - rpc.device_id = device_id; - rpc.phys_addr = audio_phys; - rpc.phys_size = size; - rpc.phys_used = size; - - if (q6_device_to_dir(device_id) == Q6_TX) - rpc.hdr.data = tx_clk_freq; - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -int q6audio_read(struct audio_client *ac, struct audio_buffer *ab) -{ - struct adsp_buffer_command rpc; - uint32_t res; - int r; - - memset(&rpc, 0, sizeof(rpc)); - rpc.hdr.size = sizeof(rpc) - sizeof(u32); - rpc.hdr.dest = AUDIO_ADDR(DOMAIN_DSP, ac->session, 0); - rpc.hdr.src = AUDIO_ADDR(DOMAIN_APP, ac->session, 0); - rpc.hdr.context = ac->session; - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_DATA_TX; - rpc.buffer.addr = ab->phys; - rpc.buffer.max_size = ab->size; - rpc.buffer.actual_size = ab->actual_size; - - r = dal_call(ac->client, AUDIO_OP_DATA, 5, &rpc, sizeof(rpc), - &res, sizeof(res)); - - if ((r == sizeof(res))) - return 0; - - return -EIO; - -} - -int q6audio_write(struct audio_client *ac, struct audio_buffer *ab) -{ - struct adsp_buffer_command rpc; - uint32_t res; - int r; - - memset(&rpc, 0, sizeof(rpc)); - rpc.hdr.size = sizeof(rpc) - sizeof(u32); - rpc.hdr.src = AUDIO_ADDR(DOMAIN_APP, ac->session, 0); - rpc.hdr.dest = AUDIO_ADDR(DOMAIN_DSP, ac->session, 0); - rpc.hdr.context = ac->session; - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_DATA_RX; - rpc.buffer.addr = ab->phys; - rpc.buffer.max_size = ab->size; - rpc.buffer.actual_size = ab->actual_size; - - r = dal_call(ac->client, AUDIO_OP_DATA, 5, &rpc, sizeof(rpc), - &res, sizeof(res)); - return 0; -} - -static int audio_rx_volume(struct audio_client *ac, uint32_t dev_id, - int32_t volume) -{ - struct adsp_set_dev_volume_command rpc; - - memset(&rpc, 0, sizeof(rpc)); - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_SET_DEVICE_VOL; - rpc.hdr.dest = AUDIO_ADDR(DOMAIN_DSP, ac->session, 0); - rpc.hdr.src = AUDIO_ADDR(DOMAIN_APP, ac->session, 0); - rpc.device_id = dev_id; - rpc.path = ADSP_PATH_RX; - rpc.volume = volume; - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -static int audio_rx_mute(struct audio_client *ac, uint32_t dev_id, int mute) -{ - struct adsp_set_dev_mute_command rpc; - - memset(&rpc, 0, sizeof(rpc)); - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_SET_DEVICE_MUTE; - rpc.hdr.dest = AUDIO_ADDR(DOMAIN_DSP, ac->session, 0); - rpc.hdr.src = AUDIO_ADDR(DOMAIN_APP, ac->session, 0); - rpc.device_id = dev_id; - rpc.path = ADSP_PATH_RX; - rpc.mute = !!mute; - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -static int audio_tx_volume(struct audio_client *ac, uint32_t dev_id, - int32_t volume) -{ - struct adsp_set_dev_volume_command rpc; - - memset(&rpc, 0, sizeof(rpc)); - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_SET_DEVICE_VOL; - rpc.hdr.dest = AUDIO_ADDR(DOMAIN_DSP, ac->session, 0); - rpc.hdr.src = AUDIO_ADDR(DOMAIN_APP, ac->session, 0); - rpc.device_id = dev_id; - rpc.path = ADSP_PATH_TX; - rpc.volume = volume; - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -static int audio_tx_mute(struct audio_client *ac, uint32_t dev_id, int mute) -{ - struct adsp_set_dev_mute_command rpc; - - memset(&rpc, 0, sizeof(rpc)); - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_SET_DEVICE_MUTE; - rpc.hdr.dest = AUDIO_ADDR(DOMAIN_DSP, ac->session, 0); - rpc.hdr.src = AUDIO_ADDR(DOMAIN_APP, ac->session, 0); - rpc.device_id = dev_id; - rpc.path = ADSP_PATH_TX; - rpc.mute = !!mute; - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -static void callback(void *data, int len, void *cookie) -{ - struct adsp_event_hdr *e = data; - struct audio_client *ac; - struct adsp_buffer_event *abe = data; - - if (e->context >= SESSION_MAX) { - pr_err("audio callback: bogus session %d\n", - e->context); - return; - } - ac = session[e->context]; - if (!ac) { - pr_err("audio callback: unknown session %d\n", - e->context); - return; - } - - if (e->event_id == ADSP_AUDIO_IOCTL_CMD_STREAM_EOS) { - pr_info("playback done\n"); - if (e->status) - pr_err("playback status %d\n", e->status); - if (ac->cb_status == -EBUSY) { - ac->cb_status = e->status; - wake_up(&ac->wait); - } - return; - } - - if (e->event_id == ADSP_AUDIO_EVT_STATUS_BUF_DONE) { - if (e->status) - pr_err("buffer status %d\n", e->status); - - ac->buf[ac->dsp_buf].actual_size = abe->buffer.actual_size; - ac->buf[ac->dsp_buf].used = 0; - ac->dsp_buf ^= 1; - wake_up(&ac->wait); - return; - } - - if (e->status) - pr_warning("audio_cb: s=%d e=%08x status=%d\n", - e->context, e->event_id, e->status); - - if (ac->cb_status == -EBUSY) { - ac->cb_status = e->status; - wake_up(&ac->wait); - } -} - -static void audio_init(struct dal_client *client) -{ - u32 tmp[3]; - - tmp[0] = 2 * sizeof(u32); - tmp[1] = 0; - tmp[2] = 0; - dal_call(client, AUDIO_OP_INIT, 5, tmp, sizeof(tmp), - tmp, sizeof(u32)); -} - -static struct audio_client *ac_control; - -static int q6audio_init(void) -{ - struct audio_client *ac = 0; - int res = -ENODEV; - - mutex_lock(&audio_lock); - if (ac_control) { - res = 0; - goto done; - } - - icodec_rx_clk = clk_get(0, "icodec_rx_clk"); - icodec_tx_clk = clk_get(0, "icodec_tx_clk"); - ecodec_clk = clk_get(0, "ecodec_clk"); - sdac_clk = clk_get(0, "sdac_clk"); - - tx_mute_status = 0; - audio_phys = pmem_kalloc(4096, PMEM_MEMTYPE_EBI1|PMEM_ALIGNMENT_4K); - audio_data = ioremap(audio_phys, 4096); - if (!audio_data) { - pr_err("pmem kalloc failed\n"); - res = -ENOMEM; - goto done; - } - - adsp = dal_attach(AUDIO_DAL_DEVICE, AUDIO_DAL_PORT, 1, - callback, 0); - if (!adsp) { - pr_err("audio_init: cannot attach to adsp\n"); - res = -ENODEV; - goto done; - } - if (check_version(adsp, AUDIO_DAL_VERSION) != 0) { - pr_err("Incompatible adsp version\n"); - res = -ENODEV; - goto done; - } - - audio_init(adsp); - - ac = audio_client_alloc(0); - if (!ac) { - pr_err("audio_init: cannot allocate client\n"); - res = -ENOMEM; - goto done; - } - - if (audio_open_control(ac)) { - pr_err("audio_init: cannot open control channel\n"); - res = -ENODEV; - goto done; - } - - acdb = dal_attach(ACDB_DAL_DEVICE, ACDB_DAL_PORT, 0, 0, 0); - if (!acdb) { - pr_err("audio_init: cannot attach to acdb channel\n"); - res = -ENODEV; - goto done; - } - if (check_version(acdb, ACDB_DAL_VERSION) != 0) { - pr_err("Incompatablie acdb version\n"); - res = -ENODEV; - goto done; - } - - - adie = dal_attach(ADIE_DAL_DEVICE, ADIE_DAL_PORT, 0, 0, 0); - if (!adie) { - pr_err("audio_init: cannot attach to adie\n"); - res = -ENODEV; - goto done; - } - if (check_version(adie, ADIE_DAL_VERSION) != 0) { - pr_err("Incompatablie adie version\n"); - res = -ENODEV; - goto done; - } - if (analog_ops->init) - analog_ops->init(); - - res = 0; - ac_control = ac; - - pm_qos_add_request(&pm_qos_req, PM_QOS_CPU_DMA_LATENCY, - PM_QOS_DEFAULT_VALUE); -done: - if ((res < 0) && ac) - audio_client_free(ac); - mutex_unlock(&audio_lock); - - return res; -} - -static int acdb_get_config_table(uint32_t device_id, uint32_t sample_rate) -{ - struct acdb_cmd_device_table rpc; - struct acdb_result res; - int r; - - if (q6audio_init()) - return 0; - - memset(audio_data, 0, 4096); - memset(&rpc, 0, sizeof(rpc)); - - rpc.size = sizeof(rpc) - (2 * sizeof(uint32_t)); - rpc.command_id = ACDB_GET_DEVICE_TABLE; - rpc.device_id = q6_device_to_cad_id(device_id); - rpc.network_id = 0x00010023; - rpc.sample_rate_id = sample_rate; - rpc.total_bytes = 4096; - rpc.unmapped_buf = audio_phys; - rpc.res_size = sizeof(res) - (2 * sizeof(uint32_t)); - - r = dal_call(acdb, ACDB_OP_IOCTL, 8, &rpc, sizeof(rpc), - &res, sizeof(res)); - - if ((r == sizeof(res)) && (res.dal_status == 0)) - return res.used_bytes; - - return -EIO; -} - -static uint32_t audio_rx_path_id = ADIE_PATH_HANDSET_RX; -static uint32_t audio_rx_device_id = ADSP_AUDIO_DEVICE_ID_HANDSET_SPKR; -static uint32_t audio_rx_device_group = -1; -static uint32_t audio_tx_path_id = ADIE_PATH_HANDSET_TX; -static uint32_t audio_tx_device_id = ADSP_AUDIO_DEVICE_ID_HANDSET_MIC; -static uint32_t audio_tx_device_group = -1; - -static int qdsp6_devchg_notify(struct audio_client *ac, - uint32_t dev_type, uint32_t dev_id) -{ - struct adsp_device_switch_command rpc; - - if (dev_type != ADSP_AUDIO_RX_DEVICE && - dev_type != ADSP_AUDIO_TX_DEVICE) - return -EINVAL; - - memset(&rpc, 0, sizeof(rpc)); - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_DEVICE_SWITCH_PREPARE; - rpc.hdr.dest = AUDIO_ADDR(DOMAIN_DSP, ac->session, 0); - rpc.hdr.src = AUDIO_ADDR(DOMAIN_APP, ac->session, 0); - - if (dev_type == ADSP_AUDIO_RX_DEVICE) { - rpc.old_device = audio_rx_device_id; - rpc.new_device = dev_id; - } else { - rpc.old_device = audio_tx_device_id; - rpc.new_device = dev_id; - } - rpc.device_class = 0; - rpc.device_type = dev_type; - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -static int qdsp6_standby(struct audio_client *ac) -{ - return audio_command(ac, ADSP_AUDIO_IOCTL_CMD_DEVICE_SWITCH_STANDBY); -} - -static int qdsp6_start(struct audio_client *ac) -{ - return audio_command(ac, ADSP_AUDIO_IOCTL_CMD_DEVICE_SWITCH_COMMIT); -} - -static void audio_rx_analog_enable(int en) -{ - switch (audio_rx_device_id) { - case ADSP_AUDIO_DEVICE_ID_HEADSET_SPKR_MONO: - case ADSP_AUDIO_DEVICE_ID_HEADSET_SPKR_STEREO: - case ADSP_AUDIO_DEVICE_ID_TTY_HEADSET_SPKR: - if (analog_ops->headset_enable) - analog_ops->headset_enable(en); - break; - case ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO_W_MONO_HEADSET: - case ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO_W_STEREO_HEADSET: - case ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO_W_MONO_HEADSET: - case ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO_W_STEREO_HEADSET: - if (analog_ops->headset_enable) - analog_ops->headset_enable(en); - if (analog_ops->speaker_enable) - analog_ops->speaker_enable(en); - break; - case ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO: - case ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO: - if (analog_ops->speaker_enable) - analog_ops->speaker_enable(en); - break; - case ADSP_AUDIO_DEVICE_ID_BT_SCO_SPKR: - if (analog_ops->bt_sco_enable) - analog_ops->bt_sco_enable(en); - break; - } -} - -static void audio_tx_analog_enable(int en) -{ - switch (audio_tx_device_id) { - case ADSP_AUDIO_DEVICE_ID_HANDSET_MIC: - case ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MIC: - if (analog_ops->int_mic_enable) - analog_ops->int_mic_enable(en); - break; - case ADSP_AUDIO_DEVICE_ID_HEADSET_MIC: - case ADSP_AUDIO_DEVICE_ID_TTY_HEADSET_MIC: - if (analog_ops->ext_mic_enable) - analog_ops->ext_mic_enable(en); - break; - case ADSP_AUDIO_DEVICE_ID_BT_SCO_MIC: - if (analog_ops->bt_sco_enable) - analog_ops->bt_sco_enable(en); - break; - } -} - -static void _audio_rx_path_enable(void) -{ - uint32_t adev, sample_rate; - int sz; - uint32_t adie_params[5]; - - adev = audio_rx_device_id; - sample_rate = q6_device_to_rate(adev); - - sz = acdb_get_config_table(adev, sample_rate); - audio_set_table(ac_control, adev, sz); - - adie_params[0] = 4*sizeof(uint32_t); - adie_params[1] = audio_rx_path_id; - adie_params[2] = ADIE_PATH_RX; - adie_params[3] = 48000; - adie_params[4] = 256; - /*check for errors here*/ - if (!adie_set_path(adie, adie_params, sizeof(adie_params))) - pr_err("adie set rx path failed\n"); - - adie_proceed_to_stage(adie, ADIE_PATH_RX, - ADIE_STAGE_DIGITAL_READY); - adie_proceed_to_stage(adie, ADIE_PATH_RX, - ADIE_STAGE_DIGITAL_ANALOG_READY); - - audio_rx_analog_enable(1); - - audio_rx_mute(ac_control, adev, 0); - - audio_rx_volume(ac_control, adev, q6_device_volume(adev, 100)); -} - -static void _audio_tx_path_enable(void) -{ - uint32_t adev; - int sz; - uint32_t adie_params[5]; - - adev = audio_tx_device_id; - - pr_info("audiolib: load %08x cfg table\n", adev); - - if (tx_clk_freq > 16000) { - adie_params[3] = 48000; - sz = acdb_get_config_table(adev, 48000); - - } else if (tx_clk_freq > 8000) { - adie_params[3] = 16000; - sz = acdb_get_config_table(adev, 16000); - } else { - - adie_params[3] = 8000; - sz = acdb_get_config_table(adev, 8000); - } - - pr_info("cfg table is %d bytes\n", sz); - audio_set_table(ac_control, adev, sz); - - pr_info("audiolib: set adie tx path\n"); - - adie_params[0] = 4*sizeof(uint32_t); - adie_params[1] = audio_tx_path_id; - adie_params[2] = ADIE_PATH_TX; - adie_params[4] = 256; - - if (!adie_set_path(adie, adie_params, sizeof(adie_params))) - pr_err("adie set tx path failed\n"); - - adie_proceed_to_stage(adie, ADIE_PATH_TX, - ADIE_STAGE_DIGITAL_READY); - adie_proceed_to_stage(adie, ADIE_PATH_TX, - ADIE_STAGE_DIGITAL_ANALOG_READY); - - audio_tx_analog_enable(1); - audio_tx_mute(ac_control, adev, tx_mute_status); - - if (!tx_mute_status) - audio_tx_volume(ac_control, adev, q6_device_volume(adev, 100)); -} - -static void _audio_rx_path_disable(void) -{ - audio_rx_analog_enable(0); - - adie_proceed_to_stage(adie, ADIE_PATH_RX, ADIE_STAGE_ANALOG_OFF); - adie_proceed_to_stage(adie, ADIE_PATH_RX, ADIE_STAGE_DIGITAL_OFF); -} - -static void _audio_tx_path_disable(void) -{ - audio_tx_analog_enable(0); - - adie_proceed_to_stage(adie, ADIE_PATH_TX, ADIE_STAGE_ANALOG_OFF); - adie_proceed_to_stage(adie, ADIE_PATH_TX, ADIE_STAGE_DIGITAL_OFF); -} - -static int icodec_rx_clk_refcount; -static int icodec_tx_clk_refcount; -static int ecodec_clk_refcount; -static int sdac_clk_refcount; - -static void _audio_rx_clk_enable(void) -{ - uint32_t device_group = q6_device_to_codec(audio_rx_device_id); - - switch (device_group) { - case Q6_ICODEC_RX: - icodec_rx_clk_refcount++; - if (icodec_rx_clk_refcount == 1) { - clk_set_rate(icodec_rx_clk, 12288000); - clk_enable(icodec_rx_clk); - } - break; - case Q6_ECODEC_RX: - ecodec_clk_refcount++; - if (ecodec_clk_refcount == 1) { - clk_set_rate(ecodec_clk, 2048000); - clk_enable(ecodec_clk); - } - break; - case Q6_SDAC_RX: - sdac_clk_refcount++; - if (sdac_clk_refcount == 1) { - clk_set_rate(sdac_clk, 12288000); - clk_enable(sdac_clk); - } - break; - default: - return; - } - audio_rx_device_group = device_group; -} - -static void _audio_tx_clk_enable(void) -{ - uint32_t device_group = q6_device_to_codec(audio_tx_device_id); - - switch (device_group) { - case Q6_ICODEC_TX: - icodec_tx_clk_refcount++; - if (icodec_tx_clk_refcount == 1) { - clk_set_rate(icodec_tx_clk, tx_clk_freq * 256); - clk_enable(icodec_tx_clk); - } - break; - case Q6_ECODEC_TX: - ecodec_clk_refcount++; - if (ecodec_clk_refcount == 1) { - clk_set_rate(ecodec_clk, 2048000); - clk_enable(ecodec_clk); - } - break; - case Q6_SDAC_TX: - /* TODO: In QCT BSP, clk rate was set to 20480000 */ - sdac_clk_refcount++; - if (sdac_clk_refcount == 1) { - clk_set_rate(sdac_clk, 12288000); - clk_enable(sdac_clk); - } - break; - default: - return; - } - audio_tx_device_group = device_group; -} - -static void _audio_rx_clk_disable(void) -{ - switch (audio_rx_device_group) { - case Q6_ICODEC_RX: - icodec_rx_clk_refcount--; - if (icodec_rx_clk_refcount == 0) { - clk_disable(icodec_rx_clk); - audio_rx_device_group = -1; - } - break; - case Q6_ECODEC_RX: - ecodec_clk_refcount--; - if (ecodec_clk_refcount == 0) { - clk_disable(ecodec_clk); - audio_rx_device_group = -1; - } - break; - case Q6_SDAC_RX: - sdac_clk_refcount--; - if (sdac_clk_refcount == 0) { - clk_disable(sdac_clk); - audio_rx_device_group = -1; - } - break; - default: - pr_err("audiolib: invalid rx device group %d\n", - audio_rx_device_group); - break; - } -} - -static void _audio_tx_clk_disable(void) -{ - switch (audio_tx_device_group) { - case Q6_ICODEC_TX: - icodec_tx_clk_refcount--; - if (icodec_tx_clk_refcount == 0) { - clk_disable(icodec_tx_clk); - audio_tx_device_group = -1; - } - break; - case Q6_ECODEC_TX: - ecodec_clk_refcount--; - if (ecodec_clk_refcount == 0) { - clk_disable(ecodec_clk); - audio_tx_device_group = -1; - } - break; - case Q6_SDAC_TX: - sdac_clk_refcount--; - if (sdac_clk_refcount == 0) { - clk_disable(sdac_clk); - audio_tx_device_group = -1; - } - break; - default: - pr_err("audiolib: invalid tx device group %d\n", - audio_tx_device_group); - break; - } -} - -static void _audio_rx_clk_reinit(uint32_t rx_device) -{ - uint32_t device_group = q6_device_to_codec(rx_device); - - if (device_group != audio_rx_device_group) - _audio_rx_clk_disable(); - - audio_rx_device_id = rx_device; - audio_rx_path_id = q6_device_to_path(rx_device); - - if (device_group != audio_rx_device_group) - _audio_rx_clk_enable(); - -} - -static void _audio_tx_clk_reinit(uint32_t tx_device) -{ - uint32_t device_group = q6_device_to_codec(tx_device); - - if (device_group != audio_tx_device_group) - _audio_tx_clk_disable(); - - audio_tx_device_id = tx_device; - audio_tx_path_id = q6_device_to_path(tx_device); - - if (device_group != audio_tx_device_group) - _audio_tx_clk_enable(); -} - -static DEFINE_MUTEX(audio_path_lock); -static int audio_rx_path_refcount; -static int audio_tx_path_refcount; - -static int audio_rx_path_enable(int en) -{ - mutex_lock(&audio_path_lock); - if (en) { - audio_rx_path_refcount++; - if (audio_rx_path_refcount == 1) { - adie_enable(); - _audio_rx_clk_enable(); - _audio_rx_path_enable(); - } - } else { - audio_rx_path_refcount--; - if (audio_rx_path_refcount == 0) { - _audio_rx_path_disable(); - _audio_rx_clk_disable(); - adie_disable(); - } - } - mutex_unlock(&audio_path_lock); - return 0; -} - -static int audio_tx_path_enable(int en) -{ - mutex_lock(&audio_path_lock); - if (en) { - audio_tx_path_refcount++; - if (audio_tx_path_refcount == 1) { - adie_enable(); - _audio_tx_clk_enable(); - _audio_tx_path_enable(); - } - } else { - audio_tx_path_refcount--; - if (audio_tx_path_refcount == 0) { - _audio_tx_path_disable(); - _audio_tx_clk_disable(); - adie_disable(); - } - } - mutex_unlock(&audio_path_lock); - return 0; -} - -int q6audio_update_acdb(uint32_t id_src, uint32_t id_dst) -{ - mutex_lock(&audio_path_lock); - mutex_unlock(&audio_path_lock); - return 0; -} - -int q6audio_set_tx_mute(int mute) -{ - uint32_t adev; - int rc; - - if (q6audio_init()) - return 0; - - mutex_lock(&audio_path_lock); - - if (mute == tx_mute_status) { - mutex_unlock(&audio_path_lock); - return 0; - } - - adev = audio_tx_device_id; - rc = audio_tx_mute(ac_control, adev, mute); - if (!rc) - tx_mute_status = mute; - mutex_unlock(&audio_path_lock); - return 0; -} - -int q6audio_set_rx_volume(int level) -{ - uint32_t adev; - int vol; - - if (q6audio_init()) - return 0; - - if (level < 0 || level > 100) - return -EINVAL; - - mutex_lock(&audio_path_lock); - adev = audio_rx_device_id; - vol = q6_device_volume(adev, level); - audio_rx_mute(ac_control, adev, 0); - audio_rx_volume(ac_control, adev, vol); - mutex_unlock(&audio_path_lock); - return 0; -} - -static void do_rx_routing(uint32_t device_id) -{ - int sz; - uint32_t sample_rate; - - if (device_id == audio_rx_device_id) - return; - - if (audio_rx_path_refcount > 0) { - qdsp6_devchg_notify(ac_control, ADSP_AUDIO_RX_DEVICE, - device_id); - _audio_rx_path_disable(); - _audio_rx_clk_reinit(device_id); - _audio_rx_path_enable(); - } else { - sample_rate = q6_device_to_rate(device_id); - sz = acdb_get_config_table(device_id, sample_rate); - if (sz < 0) - pr_err("could not get ACDB config table\n"); - - audio_set_table(ac_control, device_id, sz); - qdsp6_devchg_notify(ac_control, ADSP_AUDIO_RX_DEVICE, - device_id); - qdsp6_standby(ac_control); - qdsp6_start(ac_control); - audio_rx_device_id = device_id; - audio_rx_path_id = q6_device_to_path(device_id); - } -} - -static void do_tx_routing(uint32_t device_id) -{ - int sz; - uint32_t sample_rate; - - if (device_id == audio_tx_device_id) - return; - - if (audio_tx_path_refcount > 0) { - qdsp6_devchg_notify(ac_control, ADSP_AUDIO_TX_DEVICE, - device_id); - _audio_tx_path_disable(); - _audio_tx_clk_reinit(device_id); - _audio_tx_path_enable(); - } else { - sample_rate = q6_device_to_rate(device_id); - sz = acdb_get_config_table(device_id, sample_rate); - audio_set_table(ac_control, device_id, sz); - qdsp6_devchg_notify(ac_control, ADSP_AUDIO_TX_DEVICE, - device_id); - qdsp6_standby(ac_control); - qdsp6_start(ac_control); - audio_tx_device_id = device_id; - audio_tx_path_id = q6_device_to_path(device_id); - } -} - -int q6audio_do_routing(uint32_t device_id) -{ - if (q6audio_init()) - return 0; - - mutex_lock(&audio_path_lock); - - switch (q6_device_to_dir(device_id)) { - case Q6_RX: - do_rx_routing(device_id); - break; - case Q6_TX: - do_tx_routing(device_id); - break; - } - - mutex_unlock(&audio_path_lock); - return 0; -} - -int q6audio_set_route(const char *name) -{ - uint32_t route; - if (!strcmp(name, "speaker")) - route = ADIE_PATH_SPEAKER_STEREO_RX; - else if (!strcmp(name, "headphones")) - route = ADIE_PATH_HEADSET_STEREO_RX; - else if (!strcmp(name, "handset")) - route = ADIE_PATH_HANDSET_RX; - else - return -EINVAL; - - mutex_lock(&audio_path_lock); - if (route == audio_rx_path_id) - goto done; - - audio_rx_path_id = route; - - if (audio_rx_path_refcount > 0) { - _audio_rx_path_disable(); - _audio_rx_path_enable(); - } - if (audio_tx_path_refcount > 0) { - _audio_tx_path_disable(); - _audio_tx_path_enable(); - } -done: - mutex_unlock(&audio_path_lock); - return 0; -} - -struct audio_client *q6audio_open(uint32_t flags, uint32_t bufsz) -{ - struct audio_client *ac; - - if (q6audio_init()) - return 0; - - ac = audio_client_alloc(bufsz); - if (!ac) - return 0; - - ac->flags = flags; - if (ac->flags & AUDIO_FLAG_WRITE) - audio_rx_path_enable(1); - else - audio_tx_path_enable(1); - - return ac; -} - -int q6audio_start(struct audio_client *ac, void *rpc, - uint32_t len) -{ - - audio_ioctl(ac, rpc, len); - - audio_command(ac, ADSP_AUDIO_IOCTL_CMD_SESSION_START); - - if (!(ac->flags & AUDIO_FLAG_WRITE)) { - ac->buf[0].used = 1; - ac->buf[1].used = 1; - q6audio_read(ac, &ac->buf[0]); - q6audio_read(ac, &ac->buf[1]); - } - - audio_prevent_sleep(); - return 0; -} - -int q6audio_close(struct audio_client *ac) -{ - audio_close(ac); - - if (ac->flags & AUDIO_FLAG_WRITE) - audio_rx_path_enable(0); - else - audio_tx_path_enable(0); - - audio_client_free(ac); - audio_allow_sleep(); - return 0; -} - -struct audio_client *q6voice_open(void) -{ - struct audio_client *ac; - - if (q6audio_init()) - return 0; - - ac = audio_client_alloc(0); - if (!ac) - return 0; - - return ac; -} - -int q6voice_setup(void) -{ - audio_rx_path_enable(1); - tx_clk_freq = 8000; - audio_tx_path_enable(1); - - return 0; -} - -int q6voice_teardown(void) -{ - audio_rx_path_enable(0); - audio_tx_path_enable(0); - return 0; -} - - -int q6voice_close(struct audio_client *ac) -{ - audio_client_free(ac); - return 0; -} - -int q6audio_async(struct audio_client *ac) -{ - struct adsp_command_hdr rpc; - memset(&rpc, 0, sizeof(rpc)); - rpc.opcode = ADSP_AUDIO_IOCTL_CMD_STREAM_EOS; - rpc.response_type = ADSP_AUDIO_RESPONSE_ASYNC; - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} diff --git a/arch/arm/mach-msm/qdsp6/audiov2/q6audio_devices.h b/arch/arm/mach-msm/qdsp6/audiov2/q6audio_devices.h deleted file mode 100644 index 3786ccad16cb3e40646aeb257dbd40873534d733..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/audiov2/q6audio_devices.h +++ /dev/null @@ -1,276 +0,0 @@ -/* arch/arm/mach-msm/qdsp6/audiov2/q6audio_devices.h - * - * Copyright (C) 2009 Google, Inc. - * Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * Author: Brian Swetland - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -struct q6_device_info { - uint32_t id; - uint32_t cad_id; - uint32_t path; - uint32_t rate; - uint8_t dir; - uint8_t codec; - uint8_t hw; -}; - -#define Q6_ICODEC_RX 0 -#define Q6_ICODEC_TX 1 -#define Q6_ECODEC_RX 2 -#define Q6_ECODEC_TX 3 -#define Q6_SDAC_RX 6 -#define Q6_SDAC_TX 7 -#define Q6_CODEC_NONE 255 - -#define Q6_TX 1 -#define Q6_RX 2 -#define Q6_TX_RX 3 - -#define Q6_HW_HANDSET 0 -#define Q6_HW_HEADSET 1 -#define Q6_HW_SPEAKER 2 -#define Q6_HW_TTY 3 -#define Q6_HW_BT_SCO 4 -#define Q6_HW_BT_A2DP 5 - -#define Q6_HW_COUNT 6 - -#define CAD_HW_DEVICE_ID_HANDSET_MIC 0x01 -#define CAD_HW_DEVICE_ID_HANDSET_SPKR 0x02 -#define CAD_HW_DEVICE_ID_HEADSET_MIC 0x03 -#define CAD_HW_DEVICE_ID_HEADSET_SPKR_MONO 0x04 -#define CAD_HW_DEVICE_ID_HEADSET_SPKR_STEREO 0x05 -#define CAD_HW_DEVICE_ID_SPKR_PHONE_MIC 0x06 -#define CAD_HW_DEVICE_ID_SPKR_PHONE_MONO 0x07 -#define CAD_HW_DEVICE_ID_SPKR_PHONE_STEREO 0x08 -#define CAD_HW_DEVICE_ID_BT_SCO_MIC 0x09 -#define CAD_HW_DEVICE_ID_BT_SCO_SPKR 0x0A -#define CAD_HW_DEVICE_ID_BT_A2DP_SPKR 0x0B -#define CAD_HW_DEVICE_ID_TTY_HEADSET_MIC 0x0C -#define CAD_HW_DEVICE_ID_TTY_HEADSET_SPKR 0x0D - -#define CAD_HW_DEVICE_ID_DEFAULT_TX 0x0E -#define CAD_HW_DEVICE_ID_DEFAULT_RX 0x0F - -/* Logical Device to indicate A2DP routing */ -#define CAD_HW_DEVICE_ID_BT_A2DP_TX 0x10 -#define CAD_HW_DEVICE_ID_HEADSET_MONO_PLUS_SPKR_MONO_RX 0x11 -#define CAD_HW_DEVICE_ID_HEADSET_MONO_PLUS_SPKR_STEREO_RX 0x12 -#define CAD_HW_DEVICE_ID_HEADSET_STEREO_PLUS_SPKR_MONO_RX 0x13 -#define CAD_HW_DEVICE_ID_HEADSET_STEREO_PLUS_SPKR_STEREO_RX 0x14 - -#define CAD_HW_DEVICE_ID_VOICE 0x15 - -#define CAD_HW_DEVICE_ID_I2S_RX 0x20 -#define CAD_HW_DEVICE_ID_I2S_TX 0x21 - -/* AUXPGA */ -#define CAD_HW_DEVICE_ID_HEADSET_SPKR_STEREO_LB 0x22 -#define CAD_HW_DEVICE_ID_HEADSET_SPKR_MONO_LB 0x23 -#define CAD_HW_DEVICE_ID_SPEAKER_SPKR_STEREO_LB 0x24 -#define CAD_HW_DEVICE_ID_SPEAKER_SPKR_MONO_LB 0x25 - -#define CAD_HW_DEVICE_ID_NULL_RX 0x2A - -#define CAD_HW_DEVICE_ID_MAX_NUM 0x2F - -#define CAD_HW_DEVICE_ID_INVALID 0xFF - -#define CAD_RX_DEVICE 0x00 -#define CAD_TX_DEVICE 0x01 - -static struct q6_device_info q6_audio_devices[] = { - { - .id = ADSP_AUDIO_DEVICE_ID_HANDSET_SPKR, - .cad_id = CAD_HW_DEVICE_ID_HANDSET_SPKR, - .path = ADIE_PATH_HANDSET_RX, - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ICODEC_RX, - .hw = Q6_HW_HANDSET, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_HEADSET_SPKR_MONO, - .cad_id = CAD_HW_DEVICE_ID_HEADSET_SPKR_MONO, - .path = ADIE_PATH_HEADSET_MONO_RX, - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ICODEC_RX, - .hw = Q6_HW_HEADSET, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_HEADSET_SPKR_STEREO, - .cad_id = CAD_HW_DEVICE_ID_HEADSET_SPKR_STEREO, - .path = ADIE_PATH_HEADSET_STEREO_RX, - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ICODEC_RX, - .hw = Q6_HW_HEADSET, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO, - .cad_id = CAD_HW_DEVICE_ID_SPKR_PHONE_MONO, - .path = ADIE_PATH_SPEAKER_RX, - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ICODEC_RX, - .hw = Q6_HW_HEADSET, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO, - .cad_id = CAD_HW_DEVICE_ID_SPKR_PHONE_STEREO, - .path = ADIE_PATH_SPEAKER_STEREO_RX, - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ICODEC_RX, - .hw = Q6_HW_SPEAKER, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO_W_MONO_HEADSET, - .cad_id = CAD_HW_DEVICE_ID_HEADSET_MONO_PLUS_SPKR_MONO_RX, - .path = ADIE_PATH_SPKR_MONO_HDPH_MONO_RX, - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ICODEC_RX, - .hw = Q6_HW_SPEAKER, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO_W_STEREO_HEADSET, - .cad_id = CAD_HW_DEVICE_ID_HEADSET_MONO_PLUS_SPKR_STEREO_RX, - .path = ADIE_PATH_SPKR_MONO_HDPH_STEREO_RX, - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ICODEC_RX, - .hw = Q6_HW_SPEAKER, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO_W_MONO_HEADSET, - .cad_id = CAD_HW_DEVICE_ID_HEADSET_STEREO_PLUS_SPKR_MONO_RX, - .path = ADIE_PATH_SPKR_STEREO_HDPH_MONO_RX, - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ICODEC_RX, - .hw = Q6_HW_SPEAKER, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO_W_STEREO_HEADSET, - .cad_id = CAD_HW_DEVICE_ID_HEADSET_STEREO_PLUS_SPKR_STEREO_RX, - .path = ADIE_PATH_SPKR_STEREO_HDPH_STEREO_RX, - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ICODEC_RX, - .hw = Q6_HW_SPEAKER, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_TTY_HEADSET_SPKR, - .cad_id = CAD_HW_DEVICE_ID_TTY_HEADSET_SPKR, - .path = ADIE_PATH_TTY_HEADSET_RX, - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ICODEC_RX, - .hw = Q6_HW_TTY, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_HANDSET_MIC, - .cad_id = CAD_HW_DEVICE_ID_HANDSET_MIC, - .path = ADIE_PATH_HANDSET_TX, - .rate = 8000, - .dir = Q6_TX, - .codec = Q6_ICODEC_TX, - .hw = Q6_HW_HANDSET, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_HEADSET_MIC, - .cad_id = CAD_HW_DEVICE_ID_HEADSET_MIC, - .path = ADIE_PATH_HEADSET_MONO_TX, - .rate = 8000, - .dir = Q6_TX, - .codec = Q6_ICODEC_TX, - .hw = Q6_HW_HEADSET, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MIC, - .cad_id = CAD_HW_DEVICE_ID_SPKR_PHONE_MIC, - .path = ADIE_PATH_SPEAKER_TX, - .rate = 8000, - .dir = Q6_TX, - .codec = Q6_ICODEC_TX, - .hw = Q6_HW_SPEAKER, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_TTY_HEADSET_MIC, - .cad_id = CAD_HW_DEVICE_ID_TTY_HEADSET_MIC, - .path = ADIE_PATH_TTY_HEADSET_TX, - .rate = 8000, - .dir = Q6_TX, - .codec = Q6_ICODEC_TX, - .hw = Q6_HW_HEADSET, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_BT_SCO_SPKR, - .cad_id = CAD_HW_DEVICE_ID_BT_SCO_SPKR, - .path = 0, /* XXX */ - .rate = 8000, - .dir = Q6_RX, - .codec = Q6_ECODEC_RX, - .hw = Q6_HW_BT_SCO, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_BT_A2DP_SPKR, - .cad_id = CAD_HW_DEVICE_ID_BT_A2DP_SPKR, - .path = 0, /* XXX */ - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ECODEC_RX, - .hw = Q6_HW_BT_A2DP, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_BT_SCO_MIC, - .cad_id = CAD_HW_DEVICE_ID_BT_SCO_MIC, - .path = 0, /* XXX */ - .rate = 8000, - .dir = Q6_TX, - .codec = Q6_ECODEC_TX, - .hw = Q6_HW_BT_SCO, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_I2S_SPKR, - .cad_id = CAD_HW_DEVICE_ID_I2S_RX, - .path = 0, /* XXX */ - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_SDAC_RX, - .hw = Q6_HW_SPEAKER, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_I2S_MIC, - .cad_id = CAD_HW_DEVICE_ID_I2S_TX, - .path = 0, /* XXX */ - .rate = 16000, - .dir = Q6_TX, - .codec = Q6_SDAC_TX, - .hw = Q6_HW_SPEAKER, - }, - { - .id = 0, - .cad_id = 0, - .path = 0, - .rate = 8000, - .dir = 0, - .codec = Q6_CODEC_NONE, - .hw = 0, - }, -}; - diff --git a/arch/arm/mach-msm/qdsp6/audiov2/qcelp_in.c b/arch/arm/mach-msm/qdsp6/audiov2/qcelp_in.c deleted file mode 100644 index 40ae37dd34b48af261eff071da40321822e1a25b..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/audiov2/qcelp_in.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2009 Google, Inc. - * Copyright (C) 2009 HTC Corporation - * Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * Author: Brian Swetland - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "dal_audio.h" -#include "dal_audio_format.h" -#include - - -struct qcelp { - struct mutex lock; - struct msm_audio_qcelp_enc_config cfg; - struct msm_audio_stream_config str_cfg; - struct audio_client *audio_client; -}; - - -static long q6_qcelp_in_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct qcelp *qcelp = file->private_data; - struct adsp_open_command rpc; - int rc = 0; - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - memset(&stats, 0, sizeof(stats)); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - mutex_lock(&qcelp->lock); - switch (cmd) { - case AUDIO_START: - if (qcelp->audio_client) { - rc = -EBUSY; - break; - } else { - qcelp->audio_client = q6audio_open(AUDIO_FLAG_READ, - qcelp->str_cfg.buffer_size); - - if (!qcelp->audio_client) { - kfree(qcelp); - rc = -ENOMEM; - break; - } - } - - tx_clk_freq = 8000; - - memset(&rpc, 0, sizeof(rpc)); - - rpc.format_block.standard.format = ADSP_AUDIO_FORMAT_V13K_FS; - rpc.format_block.standard.channels = 1; - rpc.format_block.standard.bits_per_sample = 16; - rpc.format_block.standard.sampling_rate = 8000; - rpc.format_block.standard.is_signed = 1; - rpc.format_block.standard.is_interleaved = 0; - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_READ; - rpc.device = ADSP_AUDIO_DEVICE_ID_DEFAULT; - rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_RECORD; - rpc.buf_max_size = qcelp->str_cfg.buffer_size; - rpc.config.qcelp13k.min_rate = qcelp->cfg.min_bit_rate; - rpc.config.qcelp13k.max_rate = qcelp->cfg.max_bit_rate; - - q6audio_start(qcelp->audio_client, &rpc, sizeof(rpc)); - break; - case AUDIO_STOP: - break; - case AUDIO_FLUSH: - break; - case AUDIO_SET_VOLUME: - break; - case AUDIO_GET_STREAM_CONFIG: - if (copy_to_user((void *)arg, &qcelp->str_cfg, - sizeof(struct msm_audio_stream_config))) - rc = -EFAULT; - break; - case AUDIO_SET_STREAM_CONFIG: - if (copy_from_user(&qcelp->str_cfg, (void *)arg, - sizeof(struct msm_audio_stream_config))) { - rc = -EFAULT; - break; - } - - if (qcelp->str_cfg.buffer_size < 35) { - pr_err("[%s:%s] Buffer size too small\n", __MM_FILE__, - __func__); - rc = -EINVAL; - break; - } - - if (qcelp->str_cfg.buffer_count != 2) - pr_info("[%s:%s] Buffer count set to 2\n", __MM_FILE__, - __func__); - break; - case AUDIO_SET_QCELP_ENC_CONFIG: - if (copy_from_user(&qcelp->cfg, (void *) arg, - sizeof(struct msm_audio_qcelp_enc_config))) - rc = -EFAULT; - - if (qcelp->cfg.min_bit_rate > 4 || - qcelp->cfg.min_bit_rate < 1) { - - pr_err("[%s:%s] invalid min bitrate\n", __MM_FILE__, - __func__); - rc = -EINVAL; - } - if (qcelp->cfg.max_bit_rate > 4 || - qcelp->cfg.max_bit_rate < 1) { - - pr_err("[%s:%s] invalid max bitrate\n", __MM_FILE__, - __func__); - rc = -EINVAL; - } - - break; - case AUDIO_GET_QCELP_ENC_CONFIG: - if (copy_to_user((void *) arg, &qcelp->cfg, - sizeof(struct msm_audio_qcelp_enc_config))) - rc = -EFAULT; - break; - - default: - rc = -EINVAL; - } - - mutex_unlock(&qcelp->lock); - return rc; -} - -static int q6_qcelp_in_open(struct inode *inode, struct file *file) -{ - struct qcelp *qcelp; - qcelp = kmalloc(sizeof(struct qcelp), GFP_KERNEL); - if (qcelp == NULL) { - pr_err("[%s:%s] Could not allocate memory for qcelp driver\n", - __MM_FILE__, __func__); - return -ENOMEM; - } - - mutex_init(&qcelp->lock); - file->private_data = qcelp; - qcelp->audio_client = NULL; - qcelp->str_cfg.buffer_size = 35; - qcelp->str_cfg.buffer_count = 2; - qcelp->cfg.cdma_rate = CDMA_RATE_FULL; - qcelp->cfg.min_bit_rate = 1; - qcelp->cfg.max_bit_rate = 4; - return 0; -} - -static ssize_t q6_qcelp_in_read(struct file *file, char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_client *ac; - struct audio_buffer *ab; - const char __user *start = buf; - struct qcelp *qcelp = file->private_data; - int xfer = 0; - int res; - - mutex_lock(&qcelp->lock); - ac = qcelp->audio_client; - if (!ac) { - res = -ENODEV; - goto fail; - } - while (count > xfer) { - ab = ac->buf + ac->cpu_buf; - - if (ab->used) - wait_event(ac->wait, (ab->used == 0)); - - xfer = ab->actual_size; - - if (copy_to_user(buf, ab->data, xfer)) { - res = -EFAULT; - goto fail; - } - - buf += xfer; - count -= xfer; - - ab->used = 1; - q6audio_read(ac, ab); - ac->cpu_buf ^= 1; - } - - res = buf - start; - -fail: - mutex_unlock(&qcelp->lock); - - return res; -} - -static int q6_qcelp_in_release(struct inode *inode, struct file *file) -{ - int rc = 0; - struct qcelp *qcelp = file->private_data; - - mutex_lock(&qcelp->lock); - if (qcelp->audio_client) - rc = q6audio_close(qcelp->audio_client); - mutex_unlock(&qcelp->lock); - kfree(qcelp); - return rc; -} - -static const struct file_operations q6_qcelp_in_fops = { - .owner = THIS_MODULE, - .open = q6_qcelp_in_open, - .read = q6_qcelp_in_read, - .release = q6_qcelp_in_release, - .unlocked_ioctl = q6_qcelp_in_ioctl, -}; - -struct miscdevice q6_qcelp_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_qcelp_in", - .fops = &q6_qcelp_in_fops, -}; - -static int __init q6_qcelp_in_init(void) -{ - return misc_register(&q6_qcelp_in_misc); -} - -device_initcall(q6_qcelp_in_init); diff --git a/arch/arm/mach-msm/qdsp6/audiov2/routing.c b/arch/arm/mach-msm/qdsp6/audiov2/routing.c deleted file mode 100644 index 1ba128ce812016171d088e646a0176ce50270ca8..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/audiov2/routing.c +++ /dev/null @@ -1,73 +0,0 @@ -/* arch/arm/mach-msm/qdsp6/audiov2/routing.c - * - * Copyright (C) 2009 Google, Inc. - * Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * Author: Brian Swetland - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include - -static int q6_open(struct inode *inode, struct file *file) -{ - return 0; -} - -static ssize_t q6_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - char cmd[32]; - - if (count >= sizeof(cmd)) - return -EINVAL; - if (copy_from_user(cmd, buf, count)) - return -EFAULT; - cmd[count] = 0; - - if ((count > 1) && (cmd[count-1] == '\n')) - cmd[count-1] = 0; - - q6audio_set_route(cmd); - - return count; -} - -static int q6_release(struct inode *inode, struct file *file) -{ - return 0; -} - -static const struct file_operations q6_fops = { - .owner = THIS_MODULE, - .open = q6_open, - .write = q6_write, - .release = q6_release, -}; - -static struct miscdevice q6_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_audio_route", - .fops = &q6_fops, -}; - - -static int __init q6_init(void) -{ - return misc_register(&q6_misc); -} - -device_initcall(q6_init); diff --git a/arch/arm/mach-msm/qdsp6/audiov2/voice.c b/arch/arm/mach-msm/qdsp6/audiov2/voice.c deleted file mode 100644 index ccb2bad4c051cab3e71cdd40e5aa61790528ad92..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/audiov2/voice.c +++ /dev/null @@ -1,188 +0,0 @@ -/* Copyright (c) 2010, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../dal.h" -#include "dal_voice.h" -#include - -struct voice_struct { - struct dal_client *cvd; - struct apr_command_pkt apr_pkt; - struct completion compl; -}; - -static struct voice_struct voice; - -static int cvd_send_response(void) -{ - struct apr_command_pkt *pkt; - uint16_t src_addr; - uint16_t src_token; - uint16_t dst_token; - uint16_t dst_addr; - - pkt = &voice.apr_pkt; - src_addr = pkt->dst_addr; - dst_addr = pkt->src_addr; - src_token = pkt->dst_token; - dst_token = pkt->src_token; - - pkt->header &= ~APR_PKTV1_TYPE_MASK; - pkt->header |= APR_SET_FIELD(APR_PKTV1_TYPE, APR_PKTV1_TYPE_EVENT_V); - pkt->src_addr = src_addr; - pkt->dst_addr = dst_addr; - pkt->src_token = src_token; - pkt->dst_token = dst_token; - pkt->opcode = APR_IBASIC_RSP_RESULT; - - dal_call(voice.cvd, VOICE_OP_CONTROL, 5, pkt, - sizeof(struct apr_command_pkt), - pkt, sizeof(u32)); - return 0; -} - -static int cvd_process_voice_setup(void) -{ - q6voice_setup(); - cvd_send_response(); - return 0; -} - -static int cvd_process_voice_teardown(void) -{ - q6voice_teardown(); - cvd_send_response(); - return 0; -} - -static int cvd_process_set_network(void) -{ - cvd_send_response(); - return 0; -} - -static int voice_thread(void *data) -{ - while (!kthread_should_stop()) { - wait_for_completion(&voice.compl); - init_completion(&voice.compl); - - switch (voice.apr_pkt.opcode) { - - case APR_OP_CMD_CREATE: - cvd_send_response(); - break; - case VOICE_OP_CMD_BRINGUP: - cvd_process_voice_setup(); - break; - case APR_OP_CMD_DESTROY: - cvd_send_response(); - break; - case VOICE_OP_CMD_TEARDOWN: - cvd_process_voice_teardown(); - break; - case VOICE_OP_CMD_SET_NETWORK: - cvd_process_set_network(); - break; - default: - pr_err("[%s:%s] Undefined event\n", __MM_FILE__, - __func__); - - } - } - return 0; -} - -static void remote_cb_function(void *data, int len, void *cookie) -{ - struct apr_command_pkt *apr = data + 2*sizeof(uint32_t); - - memcpy(&voice.apr_pkt, apr, sizeof(struct apr_command_pkt)); - - if (len <= 0) { - pr_err("[%s:%s] unexpected event with length %d\n", - __MM_FILE__, __func__, len); - return; - } - - pr_debug("[%s:%s] APR = %x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n", __MM_FILE__, - __func__, - apr->header, - apr->reserved1, - apr->src_addr, - apr->dst_addr, - apr->ret_addr, - apr->src_token, - apr->dst_token, - apr->ret_token, - apr->context, - apr->opcode); - - complete(&voice.compl); -} - -static int __init voice_init(void) -{ - int res = 0; - struct task_struct *task; - u32 tmp[2]; - - tmp[0] = sizeof(u32); - tmp[1] = 0; - - voice.cvd = dal_attach(VOICE_DAL_DEVICE, VOICE_DAL_PORT, 0, - remote_cb_function, 0); - - if (!voice.cvd) { - pr_err("[%s:%s] audio_init: cannot attach to cvd\n", - __MM_FILE__, __func__); - res = -ENODEV; - goto done; - } - - if (check_version(voice.cvd, VOICE_DAL_VERSION) != 0) { - pr_err("[%s:%s] Incompatible cvd version\n", - __MM_FILE__, __func__); - res = -ENODEV; - goto done; - } - dal_call(voice.cvd, VOICE_OP_INIT, 5, tmp, sizeof(tmp), - tmp, sizeof(u32)); - - init_completion(&voice.compl); - task = kthread_run(voice_thread, &voice, "voice_thread"); - - if (IS_ERR(task)) { - pr_err("[%s:%s] Cannot start the voice thread\n", __MM_FILE__, - __func__); - res = PTR_ERR(task); - task = NULL; - } else - goto done; - -done: - return res; -} - -late_initcall(voice_init); diff --git a/arch/arm/mach-msm/qdsp6/auxpcm_lb_in.c b/arch/arm/mach-msm/qdsp6/auxpcm_lb_in.c deleted file mode 100644 index ff254a60ad8bb021e983bc2fc294d7d1d330a563..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/auxpcm_lb_in.c +++ /dev/null @@ -1,190 +0,0 @@ -/* arch/arm/mach-msm/qdsp6/auxpcm_lb_in.c - * - * Copyright (C) 2009 Google, Inc. - * Copyright (C) 2009 HTC Corporation - * Copyright (c) 2010, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -struct auxpcm { - struct mutex lock; - struct audio_client *ac; - uint32_t sample_rate; - uint32_t channel_count; - int opened;; -}; - -static long auxpcmin_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct auxpcm *auxpcmin = file->private_data; - int rc = 0; - - mutex_lock(&auxpcmin->lock); - switch (cmd) { - case AUDIO_START: { - uint32_t acdb_id; - pr_debug("[%s:%s] AUDIO_START\n", __MM_FILE__, __func__); - if (arg == 0) { - acdb_id = 0; - } else if (copy_from_user(&acdb_id, (void *) arg, - sizeof(acdb_id))) { - pr_info("[%s:%s] copy acdb_id from user failed\n", - __MM_FILE__, __func__); - rc = -EFAULT; - break; - } - if (auxpcmin->ac) { - pr_err("[%s:%s] active session already existing\n", - __MM_FILE__, __func__); - rc = -EBUSY; - } else { - auxpcmin->ac = - q6audio_open_auxpcm(auxpcmin->sample_rate, - auxpcmin->channel_count, - AUDIO_FLAG_READ, acdb_id); - if (!auxpcmin->ac) { - pr_err("[%s:%s] auxpcm open session failed\n", - __MM_FILE__, __func__); - rc = -ENOMEM; - } - } - break; - } - case AUDIO_STOP: - pr_debug("[%s:%s] AUDIO_STOP\n", __MM_FILE__, __func__); - break; - case AUDIO_FLUSH: - break; - case AUDIO_SET_CONFIG: { - struct msm_audio_config config; - if (auxpcmin->ac) { - rc = -EBUSY; - pr_err("[%s:%s] active session already existing\n", - __MM_FILE__, __func__); - break; - } - if (copy_from_user(&config, (void *) arg, sizeof(config))) { - rc = -EFAULT; - break; - } - pr_debug("[%s:%s] SET_CONFIG: samplerate = %d, channels = %d\n", - __MM_FILE__, __func__, config.sample_rate, - config.channel_count); - if (config.channel_count != 1) { - rc = -EINVAL; - pr_err("[%s:%s] invalid channelcount %d\n", - __MM_FILE__, __func__, config.channel_count); - break; - } - if (config.sample_rate != 8000) { - rc = -EINVAL; - pr_err("[%s:%s] invalid samplerate %d\n", __MM_FILE__, - __func__, config.sample_rate); - break; - } - auxpcmin->sample_rate = config.sample_rate; - auxpcmin->channel_count = config.channel_count; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config config; - config.buffer_size = 0; - config.buffer_count = 0; - config.sample_rate = auxpcmin->sample_rate; - config.channel_count = auxpcmin->channel_count; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *) arg, &config, sizeof(config))) - rc = -EFAULT; - pr_debug("[%s:%s] GET_CONFIG: samplerate = %d, channels = %d\n", - __MM_FILE__, __func__, config.sample_rate, - config.channel_count); - break; - } - default: - rc = -EINVAL; - } - mutex_unlock(&auxpcmin->lock); - pr_debug("[%s:%s] rc = %d\n", __MM_FILE__, __func__, rc); - return rc; -} - -static struct auxpcm the_auxpcmin; - -static int auxpcmin_open(struct inode *inode, struct file *file) -{ - struct auxpcm *auxpcmin = &the_auxpcmin; - - pr_info("[%s:%s] open\n", __MM_FILE__, __func__); - mutex_lock(&auxpcmin->lock); - if (auxpcmin->opened) { - pr_err("aux pcm loopback tx already open!\n"); - mutex_unlock(&auxpcmin->lock); - return -EBUSY; - } - auxpcmin->channel_count = 1; - auxpcmin->sample_rate = 8000; - auxpcmin->opened = 1; - file->private_data = auxpcmin; - mutex_unlock(&auxpcmin->lock); - return 0; -} - -static int auxpcmin_release(struct inode *inode, struct file *file) -{ - struct auxpcm *auxpcmin = file->private_data; - mutex_lock(&auxpcmin->lock); - if (auxpcmin->ac) - q6audio_auxpcm_close(auxpcmin->ac); - auxpcmin->ac = NULL; - auxpcmin->opened = 0; - mutex_unlock(&auxpcmin->lock); - pr_info("[%s:%s] release\n", __MM_FILE__, __func__); - return 0; -} - -static const struct file_operations auxpcmin_fops = { - .owner = THIS_MODULE, - .open = auxpcmin_open, - .release = auxpcmin_release, - .unlocked_ioctl = auxpcmin_ioctl, -}; - -struct miscdevice auxpcmin_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_aux_pcm_lb_in", - .fops = &auxpcmin_fops, -}; - -static int __init auxpcmin_init(void) -{ - mutex_init(&the_auxpcmin.lock); - return misc_register(&auxpcmin_misc); -} - -device_initcall(auxpcmin_init); diff --git a/arch/arm/mach-msm/qdsp6/auxpcm_lb_out.c b/arch/arm/mach-msm/qdsp6/auxpcm_lb_out.c deleted file mode 100644 index bba6b94dd36b465980c6d270701831872fa0d3c5..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/auxpcm_lb_out.c +++ /dev/null @@ -1,191 +0,0 @@ -/* arch/arm/mach-msm/qdsp6/auxpcm_lb_out.c - * - * Copyright (C) 2009 Google, Inc. - * Author: Brian Swetland - * Copyright (c) 2010, The Linux Foundation. All rights reserved. - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -struct auxpcm { - struct mutex lock; - struct audio_client *ac; - uint32_t sample_rate; - uint32_t channel_count; - int opened;; -}; - -static long auxpcmout_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct auxpcm *auxpcmout = file->private_data; - int rc = 0; - - mutex_lock(&auxpcmout->lock); - switch (cmd) { - case AUDIO_START: { - uint32_t acdb_id; - pr_debug("[%s:%s] AUDIO_START\n", __MM_FILE__, __func__); - if (arg == 0) { - acdb_id = 0; - } else if (copy_from_user(&acdb_id, (void *) arg, - sizeof(acdb_id))) { - pr_info("[%s:%s] copy acdb_id from user failed\n", - __MM_FILE__, __func__); - rc = -EFAULT; - break; - } - if (auxpcmout->ac) { - rc = -EBUSY; - pr_err("[%s:%s] active session already existing\n", - __MM_FILE__, __func__); - } else { - auxpcmout->ac = - q6audio_open_auxpcm(auxpcmout->sample_rate, - auxpcmout->channel_count, - AUDIO_FLAG_WRITE, acdb_id); - if (!auxpcmout->ac) { - pr_err("[%s:%s] auxpcm open session failed\n", - __MM_FILE__, __func__); - rc = -ENOMEM; - } - } - break; - } - case AUDIO_STOP: - pr_debug("[%s:%s] AUDIO_STOP\n", __MM_FILE__, __func__); - break; - case AUDIO_FLUSH: - break; - case AUDIO_SET_CONFIG: { - struct msm_audio_config config; - if (auxpcmout->ac) { - rc = -EBUSY; - pr_err("[%s:%s] active session already existing\n", - __MM_FILE__, __func__); - break; - } - if (copy_from_user(&config, (void *) arg, sizeof(config))) { - rc = -EFAULT; - break; - } - pr_debug("[%s:%s] SET_CONFIG: samplerate = %d, channels = %d\n", - __MM_FILE__, __func__, config.sample_rate, - config.channel_count); - if (config.channel_count != 1) { - rc = -EINVAL; - pr_err("[%s:%s] invalid channelcount %d\n", - __MM_FILE__, __func__, config.channel_count); - break; - } - if (config.sample_rate != 8000) { - rc = -EINVAL; - pr_err("[%s:%s] invalid samplerate %d\n", __MM_FILE__, - __func__, config.sample_rate); - break; - } - auxpcmout->sample_rate = config.sample_rate; - auxpcmout->channel_count = config.channel_count; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config config; - config.buffer_size = 0; - config.buffer_count = 0; - config.sample_rate = auxpcmout->sample_rate; - config.channel_count = auxpcmout->channel_count; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void *) arg, &config, sizeof(config))) - rc = -EFAULT; - pr_debug("[%s:%s] GET_CONFIG: samplerate = %d, channels= %d\n", - __MM_FILE__, __func__, config.sample_rate, - config.channel_count); - break; - } - default: - rc = -EINVAL; - } - mutex_unlock(&auxpcmout->lock); - pr_debug("[%s:%s] rc = %d\n", __MM_FILE__, __func__, rc); - return rc; -} - -static struct auxpcm the_auxpcmout; - -static int auxpcmout_open(struct inode *inode, struct file *file) -{ - struct auxpcm *auxpcmout = &the_auxpcmout; - - pr_info("[%s:%s] open\n", __MM_FILE__, __func__); - - mutex_lock(&auxpcmout->lock); - - if (auxpcmout->opened) { - pr_err("aux pcm loopback rx already open!\n"); - mutex_unlock(&auxpcmout->lock); - return -EBUSY; - } - auxpcmout->channel_count = 1; - auxpcmout->sample_rate = 8000; - auxpcmout->opened = 1; - file->private_data = auxpcmout; - mutex_unlock(&auxpcmout->lock); - return 0; -} - -static int auxpcmout_release(struct inode *inode, struct file *file) -{ - struct auxpcm *auxpcmout = file->private_data; - mutex_lock(&auxpcmout->lock); - if (auxpcmout->ac) - q6audio_auxpcm_close(auxpcmout->ac); - auxpcmout->ac = NULL; - auxpcmout->opened = 0; - mutex_unlock(&auxpcmout->lock); - pr_info("[%s:%s] release\n", __MM_FILE__, __func__); - return 0; -} - -static const struct file_operations auxpcmout_fops = { - .owner = THIS_MODULE, - .open = auxpcmout_open, - .release = auxpcmout_release, - .unlocked_ioctl = auxpcmout_ioctl, -}; - -struct miscdevice auxpcmout_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_aux_pcm_lb_out", - .fops = &auxpcmout_fops, -}; - -static int __init auxpcmout_init(void) -{ - mutex_init(&the_auxpcmout.lock); - return misc_register(&auxpcmout_misc); -} - -device_initcall(auxpcmout_init); diff --git a/arch/arm/mach-msm/qdsp6/dal.c b/arch/arm/mach-msm/qdsp6/dal.c deleted file mode 100644 index 378432b66c07c76620757fac3005c4cd1dcb0c84..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/dal.c +++ /dev/null @@ -1,727 +0,0 @@ -/* arch/arm/mach-msm/qdsp6/dal.c - * - * Copyright (C) 2009 Google, Inc. - * Author: Brian Swetland - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include "dal.h" - -#define DAL_TRACE 0 - -struct dal_hdr { - uint32_t length:16; /* message length (header inclusive) */ - uint32_t version:8; /* DAL protocol version */ - uint32_t priority:7; - uint32_t async:1; - uint32_t ddi:16; /* DDI method number */ - uint32_t prototype:8; /* DDI serialization format */ - uint32_t msgid:8; /* message id (DDI, ATTACH, DETACH, ...) */ - void *from; - void *to; -} __attribute__((packed)); - -#define TRACE_DATA_MAX 128 -#define TRACE_LOG_MAX 32 -#define TRACE_LOG_MASK (TRACE_LOG_MAX - 1) - -struct dal_trace { - unsigned timestamp; - struct dal_hdr hdr; - uint32_t data[TRACE_DATA_MAX]; -}; - -#define DAL_HDR_SIZE (sizeof(struct dal_hdr)) -#define DAL_DATA_MAX 512 -#define DAL_MSG_MAX (DAL_HDR_SIZE + DAL_DATA_MAX) - -#define DAL_VERSION 0x11 - -#define DAL_MSGID_DDI 0x00 -#define DAL_MSGID_ATTACH 0x01 -#define DAL_MSGID_DETACH 0x02 -#define DAL_MSGID_ASYNCH 0xC0 -#define DAL_MSGID_REPLY 0x80 - -struct dal_channel { - struct list_head list; - struct list_head clients; - - /* synchronization for changing channel state, - * adding/removing clients, smd callbacks, etc - */ - spinlock_t lock; - - struct smd_channel *sch; - char *name; - - /* events are delivered at IRQ context immediately, so - * we only need one assembly buffer for the entire channel - */ - struct dal_hdr hdr; - unsigned char data[DAL_DATA_MAX]; - - unsigned count; - void *ptr; - - /* client which the current inbound message is for */ - struct dal_client *active; -}; - -struct dal_client { - struct list_head list; - struct dal_channel *dch; - void *cookie; - dal_event_func_t event; - - /* opaque handle for the far side */ - void *remote; - - /* dal rpc calls are fully synchronous -- only one call may be - * active per client at a time - */ - struct mutex write_lock; - wait_queue_head_t wait; - - unsigned char data[DAL_DATA_MAX]; - - void *reply; - int reply_max; - int status; - unsigned msgid; /* msgid of expected reply */ - - spinlock_t tr_lock; - unsigned tr_head; - unsigned tr_tail; - struct dal_trace *tr_log; -}; - -static unsigned now(void) -{ - struct timespec ts; - ktime_get_ts(&ts); - return (ts.tv_nsec / 1000000) + (ts.tv_sec * 1000); -} - -void dal_trace(struct dal_client *c) -{ - if (c->tr_log) - return; - c->tr_log = kzalloc(sizeof(struct dal_trace) * TRACE_LOG_MAX, - GFP_KERNEL); -} - -void dal_trace_print(struct dal_hdr *hdr, unsigned *data, int len, unsigned when) -{ - int i; - printk("DAL %08x -> %08x L=%03x A=%d D=%04x P=%02x M=%02x T=%d", - (unsigned) hdr->from, (unsigned) hdr->to, - hdr->length, hdr->async, - hdr->ddi, hdr->prototype, hdr->msgid, - when); - len /= 4; - for (i = 0; i < len; i++) { - if (!(i & 7)) - printk("\n%03x", i * 4); - printk(" %08x", data[i]); - } - printk("\n"); -} - -void dal_trace_dump(struct dal_client *c) -{ - struct dal_trace *dt; - unsigned n, len; - - if (!c->tr_log) - return; - - for (n = c->tr_tail; n != c->tr_head; n = (n + 1) & TRACE_LOG_MASK) { - dt = c->tr_log + n; - len = dt->hdr.length - sizeof(dt->hdr); - if (len > TRACE_DATA_MAX) - len = TRACE_DATA_MAX; - dal_trace_print(&dt->hdr, dt->data, len, dt->timestamp); - } -} - -static void dal_trace_log(struct dal_client *c, - struct dal_hdr *hdr, void *data, unsigned len) -{ - unsigned long flags; - unsigned t, n; - struct dal_trace *dt; - - t = now(); - if (len > TRACE_DATA_MAX) - len = TRACE_DATA_MAX; - - spin_lock_irqsave(&c->tr_lock, flags); - n = (c->tr_head + 1) & TRACE_LOG_MASK; - if (c->tr_tail == n) - c->tr_tail = (c->tr_tail + 1) & TRACE_LOG_MASK; - dt = c->tr_log + n; - dt->timestamp = t; - memcpy(&dt->hdr, hdr, sizeof(struct dal_hdr)); - memcpy(dt->data, data, len); - c->tr_head = n; - - spin_unlock_irqrestore(&c->tr_lock, flags); -} - - -static void dal_channel_notify(void *priv, unsigned event) -{ - struct dal_channel *dch = priv; - struct dal_hdr *hdr = &dch->hdr; - struct dal_client *client; - unsigned long flags; - int len; - int r; - - spin_lock_irqsave(&dch->lock, flags); - -again: - if (dch->count == 0) { - if (smd_read_avail(dch->sch) < DAL_HDR_SIZE) - goto done; - - smd_read(dch->sch, hdr, DAL_HDR_SIZE); - - if (hdr->length < DAL_HDR_SIZE) - goto done; - - if (hdr->length > DAL_MSG_MAX) - panic("oversize message"); - - dch->count = hdr->length - DAL_HDR_SIZE; - - /* locate the client this message is targeted to */ - list_for_each_entry(client, &dch->clients, list) { - if (dch->hdr.to == client) { - dch->active = client; - dch->ptr = client->data; - goto check_data; - } - } - pr_err("[%s:%s] $$$ receiving unknown message len = %d $$$\n", - __MM_FILE__, __func__, dch->count); - dch->active = 0; - dch->ptr = dch->data; - } - -check_data: - len = dch->count; - if (len > 0) { - if (smd_read_avail(dch->sch) < len) - goto done; - - r = smd_read(dch->sch, dch->ptr, len); - if (r != len) - panic("invalid read"); - -#if DAL_TRACE - pr_info("[%s:%s] dal recv %p <- %p %02x:%04x:%02x %d\n", - __MM_FILE__, __func__, hdr->to, hdr->from, hdr->msgid, - hdr->ddi, hdr->prototype, hdr->length - sizeof(*hdr)); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, dch->ptr, len); -#endif - dch->count = 0; - - client = dch->active; - if (!client) { - pr_err("[%s:%s] message to %p discarded\n", - __MM_FILE__, __func__, dch->hdr.to); - goto again; - } - - if (client->tr_log) - dal_trace_log(client, hdr, dch->ptr, len); - - if (hdr->msgid == DAL_MSGID_ASYNCH) { - if (client->event) - client->event(dch->ptr, len, client->cookie); - else - pr_err("[%s:%s] client %p has no event \ - handler\n", __MM_FILE__, __func__, - client); - goto again; - } - - if (hdr->msgid == client->msgid) { - if (!client->remote) - client->remote = hdr->from; - if (len > client->reply_max) - len = client->reply_max; - memcpy(client->reply, client->data, len); - client->status = len; - wake_up(&client->wait); - goto again; - } - - pr_err("[%s:%s] cannot find client %p\n", __MM_FILE__, - __func__, dch->hdr.to); - goto again; - } - -done: - spin_unlock_irqrestore(&dch->lock, flags); -} - -static LIST_HEAD(dal_channel_list); -static DEFINE_MUTEX(dal_channel_list_lock); - -static struct dal_channel *dal_open_channel(const char *name, uint32_t cpu) -{ - struct dal_channel *dch; - - pr_debug("[%s:%s]\n", __MM_FILE__, __func__); - mutex_lock(&dal_channel_list_lock); - - list_for_each_entry(dch, &dal_channel_list, list) { - if (!strcmp(dch->name, name)) - goto found_it; - } - - dch = kzalloc(sizeof(*dch) + strlen(name) + 1, GFP_KERNEL); - if (!dch) - goto fail; - - dch->name = (char *) (dch + 1); - strcpy(dch->name, name); - spin_lock_init(&dch->lock); - INIT_LIST_HEAD(&dch->clients); - - list_add(&dch->list, &dal_channel_list); - -found_it: - if (!dch->sch) { - if (smd_named_open_on_edge(name, cpu, &dch->sch, - dch, dal_channel_notify)) { - pr_err("[%s:%s] smd open failed\n", __MM_FILE__, - __func__); - dch = NULL; - } - /* FIXME: wait for channel to open before returning */ - msleep(100); - } - -fail: - mutex_unlock(&dal_channel_list_lock); - - return dch; -} - -int dal_call_raw(struct dal_client *client, - struct dal_hdr *hdr, - void *data, int data_len, - void *reply, int reply_max) -{ - struct dal_channel *dch = client->dch; - unsigned long flags; - - client->reply = reply; - client->reply_max = reply_max; - client->msgid = hdr->msgid | DAL_MSGID_REPLY; - client->status = -EBUSY; - -#if DAL_TRACE - pr_info("[%s:%s:%x] dal send %p -> %p %02x:%04x:%02x %d\n", - __MM_FILE__, __func__, (unsigned int)client, hdr->from, hdr->to, - hdr->msgid, hdr->ddi, hdr->prototype, - hdr->length - sizeof(*hdr)); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, data, data_len); -#endif - - if (client->tr_log) - dal_trace_log(client, hdr, data, data_len); - - spin_lock_irqsave(&dch->lock, flags); - /* FIXME: ensure entire message is written or none. */ - smd_write(dch->sch, hdr, sizeof(*hdr)); - smd_write(dch->sch, data, data_len); - spin_unlock_irqrestore(&dch->lock, flags); - - if (!wait_event_timeout(client->wait, (client->status != -EBUSY), 5*HZ)) { - dal_trace_dump(client); - pr_err("[%s:%s] call timed out. dsp is probably dead.\n", - __MM_FILE__, __func__); - dal_trace_print(hdr, data, data_len, 0); - q6audio_dsp_not_responding(); - } - - return client->status; -} - -int dal_call(struct dal_client *client, - unsigned ddi, unsigned prototype, - void *data, int data_len, - void *reply, int reply_max) -{ - struct dal_hdr hdr; - int r; - - memset(&hdr, 0, sizeof(hdr)); - - hdr.length = data_len + sizeof(hdr); - hdr.version = DAL_VERSION; - hdr.msgid = DAL_MSGID_DDI; - hdr.ddi = ddi; - hdr.prototype = prototype; - hdr.from = client; - hdr.to = client->remote; - - if (hdr.length > DAL_MSG_MAX) - return -EINVAL; - - mutex_lock(&client->write_lock); - r = dal_call_raw(client, &hdr, data, data_len, reply, reply_max); - mutex_unlock(&client->write_lock); - - return r; -} - -struct dal_msg_attach { - uint32_t device_id; - char attach[64]; - char service_name[32]; -} __attribute__((packed)); - -struct dal_reply_attach { - uint32_t status; - char name[64]; -}; - -struct dal_client *dal_attach(uint32_t device_id, const char *name, - uint32_t cpu, dal_event_func_t func, void *cookie) -{ - struct dal_hdr hdr; - struct dal_msg_attach msg; - struct dal_reply_attach reply; - struct dal_channel *dch; - struct dal_client *client; - unsigned long flags; - int r; - - pr_debug("[%s:%s]\n", __MM_FILE__, __func__); - dch = dal_open_channel(name, cpu); - if (!dch) - return 0; - - client = kzalloc(sizeof(*client), GFP_KERNEL); - if (!client) - return 0; - - client->dch = dch; - client->event = func; - client->cookie = cookie; - mutex_init(&client->write_lock); - spin_lock_init(&client->tr_lock); - init_waitqueue_head(&client->wait); - - spin_lock_irqsave(&dch->lock, flags); - list_add(&client->list, &dch->clients); - spin_unlock_irqrestore(&dch->lock, flags); - - memset(&hdr, 0, sizeof(hdr)); - memset(&msg, 0, sizeof(msg)); - - hdr.length = sizeof(hdr) + sizeof(msg); - hdr.version = DAL_VERSION; - hdr.msgid = DAL_MSGID_ATTACH; - hdr.from = client; - msg.device_id = device_id; - - r = dal_call_raw(client, &hdr, &msg, sizeof(msg), - &reply, sizeof(reply)); - - if ((r == sizeof(reply)) && (reply.status == 0)) { - reply.name[63] = 0; - pr_info("[%s:%s] status = %d, name = '%s' dal_client %x\n", - __MM_FILE__, __func__, reply.status, - reply.name, (unsigned int)client); - return client; - } - - pr_err("[%s:%s] failure\n", __MM_FILE__, __func__); - - dal_detach(client); - return 0; -} - -int dal_detach(struct dal_client *client) -{ - struct dal_channel *dch; - unsigned long flags; - - pr_debug("[%s:%s]\n", __MM_FILE__, __func__); - mutex_lock(&client->write_lock); - if (client->remote) { - struct dal_hdr hdr; - uint32_t data; - - memset(&hdr, 0, sizeof(hdr)); - hdr.length = sizeof(hdr) + sizeof(data); - hdr.version = DAL_VERSION; - hdr.msgid = DAL_MSGID_DETACH; - hdr.from = client; - hdr.to = client->remote; - data = (uint32_t) client; - - dal_call_raw(client, &hdr, &data, sizeof(data), - &data, sizeof(data)); - } - - dch = client->dch; - spin_lock_irqsave(&dch->lock, flags); - if (dch->active == client) { - /* We have received a message header for this client - * but not the body of the message. Ensure that when - * the body arrives we don't write it into the now-closed - * client. In *theory* this should never happen. - */ - dch->active = 0; - dch->ptr = dch->data; - } - list_del(&client->list); - spin_unlock_irqrestore(&dch->lock, flags); - - mutex_unlock(&client->write_lock); - - kfree(client); - return 0; -} - -void *dal_get_remote_handle(struct dal_client *client) -{ - return client->remote; -} - -/* convenience wrappers */ - -int dal_call_f0(struct dal_client *client, uint32_t ddi, uint32_t arg1) -{ - uint32_t tmp = arg1; - int res; - res = dal_call(client, ddi, 0, &tmp, sizeof(tmp), &tmp, sizeof(tmp)); - if (res >= 4) - return (int) tmp; - return res; -} - -int dal_call_f1(struct dal_client *client, uint32_t ddi, uint32_t arg1, - uint32_t arg2) -{ - uint32_t tmp[2]; - int res; - tmp[0] = arg1; - tmp[1] = arg2; - res = dal_call(client, ddi, 1, tmp, sizeof(tmp), tmp, sizeof(uint32_t)); - if (res >= 4) - return (int) tmp[0]; - return res; -} - -int dal_call_f5(struct dal_client *client, uint32_t ddi, void *ibuf, uint32_t ilen) -{ - uint32_t tmp[128]; - int res; - int param_idx = 0; - - if (ilen + 4 > DAL_DATA_MAX) - return -EINVAL; - - tmp[param_idx] = ilen; - param_idx++; - - memcpy(&tmp[param_idx], ibuf, ilen); - param_idx += DIV_ROUND_UP(ilen, 4); - - res = dal_call(client, ddi, 5, tmp, param_idx * 4, tmp, sizeof(tmp)); - - if (res >= 4) - return (int) tmp[0]; - return res; -} - -int dal_call_f6(struct dal_client *client, uint32_t ddi, uint32_t s1, - void *ibuf, uint32_t ilen) -{ - uint32_t tmp[128]; - int res; - int param_idx = 0; - - if (ilen + 8 > DAL_DATA_MAX) - return -EINVAL; - - tmp[param_idx] = s1; - param_idx++; - tmp[param_idx] = ilen; - param_idx++; - memcpy(&tmp[param_idx], ibuf, ilen); - param_idx += DIV_ROUND_UP(ilen, 4); - - res = dal_call(client, ddi, 6, tmp, param_idx * 4, tmp, sizeof(tmp)); - - if (res >= 4) - return (int) tmp[0]; - - return res; -} - -int dal_call_f9(struct dal_client *client, uint32_t ddi, void *obuf, - uint32_t olen) -{ - uint32_t tmp[128]; - int res; - - if (olen > sizeof(tmp) - 8) - return -EINVAL; - tmp[0] = olen; - - res = dal_call(client, ddi, 9, tmp, sizeof(uint32_t), tmp, - sizeof(tmp)); - - if (res >= 4) - res = (int)tmp[0]; - - if (!res) { - if (tmp[1] > olen) - return -EIO; - memcpy(obuf, &tmp[2], tmp[1]); - } - return res; -} - -int dal_call_f11(struct dal_client *client, uint32_t ddi, uint32_t s1, - void *obuf, uint32_t olen) -{ - uint32_t tmp[DAL_DATA_MAX/4] = {0}; - int res; - int param_idx = 0; - int num_bytes = 4; - - num_bytes += (DIV_ROUND_UP(olen, 4)) * 4; - - if ((num_bytes > DAL_DATA_MAX - 12) || (olen > DAL_DATA_MAX - 8)) - return -EINVAL; - - tmp[param_idx] = s1; - param_idx++; - tmp[param_idx] = olen; - param_idx += DIV_ROUND_UP(olen, 4); - - res = dal_call(client, ddi, 11, tmp, param_idx * 4, tmp, sizeof(tmp)); - - if (res >= 4) - res = (int) tmp[0]; - if (!res) { - if (tmp[1] > olen) - return -EIO; - memcpy(obuf, &tmp[2], tmp[1]); - } - return res; -} - -int dal_call_f13(struct dal_client *client, uint32_t ddi, void *ibuf1, - uint32_t ilen1, void *ibuf2, uint32_t ilen2, void *obuf, - uint32_t olen) -{ - uint32_t tmp[DAL_DATA_MAX/4]; - int res; - int param_idx = 0; - int num_bytes = 0; - - num_bytes = (DIV_ROUND_UP(ilen1, 4)) * 4; - num_bytes += (DIV_ROUND_UP(ilen2, 4)) * 4; - - if ((num_bytes > DAL_DATA_MAX - 12) || (olen > DAL_DATA_MAX - 8) || - (ilen1 > DAL_DATA_MAX) || (ilen2 > DAL_DATA_MAX)) - return -EINVAL; - - tmp[param_idx] = ilen1; - param_idx++; - - memcpy(&tmp[param_idx], ibuf1, ilen1); - param_idx += DIV_ROUND_UP(ilen1, 4); - - tmp[param_idx++] = ilen2; - memcpy(&tmp[param_idx], ibuf2, ilen2); - param_idx += DIV_ROUND_UP(ilen2, 4); - - tmp[param_idx++] = olen; - res = dal_call(client, ddi, 13, tmp, param_idx * 4, tmp, - sizeof(tmp)); - - if (res >= 4) - res = (int)tmp[0]; - - if (!res) { - if (tmp[1] > olen) - return -EIO; - memcpy(obuf, &tmp[2], tmp[1]); - } - return res; -} -int dal_call_f14(struct dal_client *client, uint32_t ddi, void *ibuf, - uint32_t ilen, void *obuf1, uint32_t olen1, void *obuf2, - uint32_t olen2, uint32_t *oalen2) -{ - uint32_t tmp[128]; - int res; - int param_idx = 0; - - if (olen1 + olen2 + 8 > DAL_DATA_MAX || - ilen + 12 > DAL_DATA_MAX) - return -EINVAL; - - tmp[param_idx] = ilen; - param_idx++; - - memcpy(&tmp[param_idx], ibuf, ilen); - param_idx += DIV_ROUND_UP(ilen, 4); - - tmp[param_idx++] = olen1; - tmp[param_idx++] = olen2; - res = dal_call(client, ddi, 14, tmp, param_idx * 4, tmp, sizeof(tmp)); - - if (res >= 4) - res = (int)tmp[0]; - - if (!res) { - if (tmp[1] > olen1) - return -EIO; - param_idx = DIV_ROUND_UP(tmp[1], 4) + 2; - if (tmp[param_idx] > olen2) - return -EIO; - - memcpy(obuf1, &tmp[2], tmp[1]); - memcpy(obuf2, &tmp[param_idx+1], tmp[param_idx]); - *oalen2 = tmp[param_idx]; - } - return res; -} diff --git a/arch/arm/mach-msm/qdsp6/dal.h b/arch/arm/mach-msm/qdsp6/dal.h deleted file mode 100644 index 1176eb9c10271036cb083513fa25abcd527e1a3d..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/dal.h +++ /dev/null @@ -1,96 +0,0 @@ -/* arch/arm/mach-msm/qdsp6/dal.h - * - * Copyright (C) 2009 Google, Inc. - * Author: Brian Swetland - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _MACH_MSM_DAL_ -#define _MACH_MSM_DAL_ - -struct dal_client; - -struct dal_info { - uint32_t size; - uint32_t version; - char name[32]; -}; - -typedef void (*dal_event_func_t)(void *data, int len, void *cookie); - -struct dal_client *dal_attach(uint32_t device_id, const char *name, - uint32_t cpu, dal_event_func_t func, void *cookie); - -int dal_detach(struct dal_client *client); - -int dal_call(struct dal_client *client, - unsigned ddi, unsigned prototype, - void *data, int data_len, - void *reply, int reply_max); - -void dal_trace(struct dal_client *client); -void dal_trace_dump(struct dal_client *client); - -/* function to call before panic on stalled dal calls */ -void dal_set_oops(struct dal_client *client, void (*oops)(void)); - -/* convenience wrappers */ -int dal_call_f0(struct dal_client *client, uint32_t ddi, - uint32_t arg1); -int dal_call_f1(struct dal_client *client, uint32_t ddi, - uint32_t arg1, uint32_t arg2); -int dal_call_f5(struct dal_client *client, uint32_t ddi, - void *ibuf, uint32_t ilen); -int dal_call_f6(struct dal_client *client, uint32_t ddi, - uint32_t s1, void *ibuf, uint32_t ilen); -int dal_call_f9(struct dal_client *client, uint32_t ddi, - void *obuf, uint32_t olen); -int dal_call_f11(struct dal_client *client, uint32_t ddi, - uint32_t s1, void *obuf, uint32_t olen); -int dal_call_f13(struct dal_client *client, uint32_t ddi, void *ibuf1, - uint32_t ilen1, void *ibuf2, uint32_t ilen2, void *obuf, - uint32_t olen); -int dal_call_f14(struct dal_client *client, uint32_t ddi, void *ibuf, - uint32_t ilen, void *obuf1, uint32_t olen1, void *obuf2, - uint32_t olen2, uint32_t *oalen2); - -/* common DAL operations */ -enum { - DAL_OP_ATTACH = 0, - DAL_OP_DETACH, - DAL_OP_INIT, - DAL_OP_DEINIT, - DAL_OP_OPEN, - DAL_OP_CLOSE, - DAL_OP_INFO, - DAL_OP_POWEREVENT, - DAL_OP_SYSREQUEST, - DAL_OP_FIRST_DEVICE_API, -}; - -static inline int check_version(struct dal_client *client, uint32_t version) -{ - struct dal_info info; - int res; - - res = dal_call_f9(client, DAL_OP_INFO, &info, sizeof(struct dal_info)); - if (!res) { - if (((info.version & 0xFFFF0000) != (version & 0xFFFF0000)) || - ((info.version & 0x0000FFFF) < - (version & 0x0000FFFF))) { - res = -EINVAL; - } - } - return res; -} - -#endif diff --git a/arch/arm/mach-msm/qdsp6/dal_acdb.h b/arch/arm/mach-msm/qdsp6/dal_acdb.h deleted file mode 100644 index 511879cb4968fa9192dc6c2faf8e19bbcef079be..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/dal_acdb.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#define ACDB_DAL_DEVICE 0x02000069 -#define ACDB_DAL_PORT "DAL_AM_AUD" - -#define ACDB_OP_IOCTL DAL_OP_FIRST_DEVICE_API - -/* ioctls */ -#define ACDB_GET_DEVICE 0x0108bb92 -#define ACDB_SET_DEVICE 0x0108bb93 -#define ACDB_GET_STREAM 0x0108bb95 -#define ACDB_SET_STREAM 0x0108bb96 -#define ACDB_GET_DEVICE_TABLE 0x0108bb97 -#define ACDB_GET_STREAM_TABLE 0x0108bb98 - -#define ACDB_RES_SUCCESS 0 -#define ACDB_RES_FAILURE -1 -#define ACDB_RES_BADPARM -2 -#define ACDB_RES_BADSTATE -3 - -struct acdb_cmd_device { - uint32_t size; - - uint32_t command_id; - uint32_t device_id; - uint32_t network_id; - uint32_t sample_rate_id; - uint32_t interface_id; - uint32_t algorithm_block_id; - - /* physical page aligned buffer */ - uint32_t total_bytes; - uint32_t unmapped_buf; -} __attribute__((packed)); - -struct acdb_cmd_device_table { - uint32_t size; - - uint32_t command_id; - uint32_t device_id; - uint32_t network_id; - uint32_t sample_rate_id; - - /* physical page aligned buffer */ - uint32_t total_bytes; - uint32_t unmapped_buf; - - uint32_t res_size; -} __attribute__((packed)); - -struct acdb_result { - uint32_t dal_status; - uint32_t size; - - uint32_t unmapped_buf; - uint32_t used_bytes; - uint32_t result; -} __attribute__((packed)); diff --git a/arch/arm/mach-msm/qdsp6/dal_adie.h b/arch/arm/mach-msm/qdsp6/dal_adie.h deleted file mode 100644 index 78db05fc6027657dab3c2a95606588ca08dae3fd..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/dal_adie.h +++ /dev/null @@ -1,104 +0,0 @@ -/* Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _MACH_MSM_QDSP6_ADIE_ -#define _MACH_MSM_QDSP6_ADIE_ - -#include "dal.h" - -#define ADIE_DAL_DEVICE 0x02000029 -#define ADIE_DAL_PORT "DAL_AM_AUD" - -enum { - ADIE_OP_GET_NUM_PATHS = DAL_OP_FIRST_DEVICE_API, - ADIE_OP_GET_ALL_PATH_IDS, - ADIE_OP_SET_PATH, - ADIE_OP_GET_NUM_PATH_FREQUENCY_PLANS, - ADIE_OP_GET_PATH_FREQUENCY_PLANS, - ADIE_OP_SET_PATH_FREQUENCY_PLAN, - ADIE_OP_PROCEED_TO_STAGE, - ADIE_OP_MUTE_PATH -}; - -/* Path IDs for normal operation. */ -#define ADIE_PATH_HANDSET_TX 0x010740f6 -#define ADIE_PATH_HANDSET_RX 0x010740f7 -#define ADIE_PATH_HEADSET_MONO_TX 0x010740f8 -#define ADIE_PATH_HEADSET_STEREO_TX 0x010740f9 -#define ADIE_PATH_HEADSET_MONO_RX 0x010740fa -#define ADIE_PATH_HEADSET_STEREO_RX 0x010740fb -#define ADIE_PATH_SPEAKER_TX 0x010740fc -#define ADIE_PATH_SPEAKER_RX 0x010740fd -#define ADIE_PATH_SPEAKER_STEREO_RX 0x01074101 - -/* Path IDs used for TTY */ -#define ADIE_PATH_TTY_HEADSET_TX 0x010740fe -#define ADIE_PATH_TTY_HEADSET_RX 0x010740ff - -/* Path IDs used by Factory Test Mode. */ -#define ADIE_PATH_FTM_MIC1_TX 0x01074108 -#define ADIE_PATH_FTM_MIC2_TX 0x01074107 -#define ADIE_PATH_FTM_HPH_L_RX 0x01074106 -#define ADIE_PATH_FTM_HPH_R_RX 0x01074104 -#define ADIE_PATH_FTM_EAR_RX 0x01074103 -#define ADIE_PATH_FTM_SPKR_RX 0x01074102 - -/* Path IDs for Loopback */ -/* Path IDs used for Line in -> AuxPGA -> Line Out Stereo Mode*/ -#define ADIE_PATH_AUXPGA_LINEOUT_STEREO_LB 0x01074100 -/* Line in -> AuxPGA -> LineOut Mono */ -#define ADIE_PATH_AUXPGA_LINEOUT_MONO_LB 0x01073d82 -/* Line in -> AuxPGA -> Stereo Headphone */ -#define ADIE_PATH_AUXPGA_HDPH_STEREO_LB 0x01074109 -/* Line in -> AuxPGA -> Mono Headphone */ -#define ADIE_PATH_AUXPGA_HDPH_MONO_LB 0x01073d85 -/* Line in -> AuxPGA -> Earpiece */ -#define ADIE_PATH_AUXPGA_EAP_LB 0x01073d81 -/* Line in -> AuxPGA -> AuxOut */ -#define ADIE_PATH_AUXPGA_AUXOUT_LB 0x01073d86 - -/* Concurrency Profiles */ -#define ADIE_PATH_SPKR_STEREO_HDPH_MONO_RX 0x01073d83 -#define ADIE_PATH_SPKR_MONO_HDPH_MONO_RX 0x01073d84 -#define ADIE_PATH_SPKR_MONO_HDPH_STEREO_RX 0x01073d88 -#define ADIE_PATH_SPKR_STEREO_HDPH_STEREO_RX 0x01073d89 - - -/** Fluence Profiles **/ - -/* Broadside/Bowsetalk profile, - * For Handset and Speaker phone Tx*/ -#define ADIE_CODEC_HANDSET_SPKR_BS_TX 0x0108fafa -/* EndFire profile, - * For Handset and Speaker phone Tx*/ -#define ADIE_CODEC_HANDSET_SPKR_EF_TX 0x0108fafb - - -/* stages */ -#define ADIE_STAGE_PATH_OFF 0x0050 -#define ADIE_STAGE_DIGITAL_READY 0x0100 -#define ADIE_STAGE_DIGITAL_ANALOG_READY 0x1000 -#define ADIE_STAGE_ANALOG_OFF 0x0750 -#define ADIE_STAGE_DIGITAL_OFF 0x0600 - -/* path types */ -#define ADIE_PATH_RX 0 -#define ADIE_PATH_TX 1 -#define ADIE_PATH_LOOPBACK 2 - -/* mute states */ -#define ADIE_MUTE_OFF 0 -#define ADIE_MUTE_ON 1 - - -#endif diff --git a/arch/arm/mach-msm/qdsp6/dal_audio.h b/arch/arm/mach-msm/qdsp6/dal_audio.h deleted file mode 100644 index 6c353db5633e0379d77552a4cb7fcbae0f91e2c8..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/dal_audio.h +++ /dev/null @@ -1,604 +0,0 @@ -/* Copyright (c) 2009-2010, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __DAL_AUDIO_H__ -#define __DAL_AUDIO_H__ - -#include "dal_audio_format.h" - -#define AUDIO_DAL_DEVICE 0x02000028 -#define AUDIO_DAL_PORT "DAL_AQ_AUD" - -enum { - AUDIO_OP_CONTROL = DAL_OP_FIRST_DEVICE_API, - AUDIO_OP_DATA, - AUDIO_OP_INIT, -}; - -/* ---- common audio structures ---- */ - -/* This flag, if set, indicates that the beginning of the data in the*/ -/* buffer is a synchronization point or key frame, meaning no data */ -/* before it in the stream is required in order to render the stream */ -/* from this point onward. */ -#define ADSP_AUDIO_BUFFER_FLAG_SYNC_POINT 0x01 - -/* This flag, if set, indicates that the buffer object is using valid */ -/* physical address used to store the media data */ -#define ADSP_AUDIO_BUFFER_FLAG_PHYS_ADDR 0x04 - -/* This flag, if set, indicates that a media start timestamp has been */ -/* set for a buffer. */ -#define ADSP_AUDIO_BUFFER_FLAG_START_SET 0x08 - -/* This flag, if set, indicates that a media stop timestamp has been set */ -/* for a buffer. */ -#define ADSP_AUDIO_BUFFER_FLAG_STOP_SET 0x10 - -/* This flag, if set, indicates that a preroll timestamp has been set */ -/* for a buffer. */ -#define ADSP_AUDIO_BUFFER_FLAG_PREROLL_SET 0x20 - -/* This flag, if set, indicates that the data in the buffer is a fragment of */ -/* a larger block of data, and will be continued by the data in the next */ -/* buffer to be delivered. */ -#define ADSP_AUDIO_BUFFER_FLAG_CONTINUATION 0x40 - -struct adsp_audio_buffer { - u32 addr; /* Physical Address of buffer */ - u32 max_size; /* Maximum size of buffer */ - u32 actual_size; /* Actual size of valid data in the buffer */ - u32 offset; /* Offset to the first valid byte */ - u32 flags; /* ADSP_AUDIO_BUFFER_FLAGs that has been set */ - s64 start; /* Start timestamp, if any */ - s64 stop; /* Stop timestamp, if any */ - s64 preroll; /* Preroll timestamp, if any */ -} __attribute__ ((packed)); - - - -/* ---- audio commands ---- */ - -/* Command/event response types */ -#define ADSP_AUDIO_RESPONSE_COMMAND 0 -#define ADSP_AUDIO_RESPONSE_ASYNC 1 - -struct adsp_command_hdr { - u32 size; /* sizeof(cmd) - sizeof(u32) */ - - u32 dst; - u32 src; - - u32 opcode; - u32 response_type; - u32 seq_number; - - u32 context; /* opaque to DSP */ - u32 data; - - u32 padding; -} __attribute__ ((packed)); - - -#define AUDIO_DOMAIN_APP 0 -#define AUDIO_DOMAIN_MODEM 1 -#define AUDIO_DOMAIN_DSP 2 - -#define AUDIO_SERVICE_AUDIO 0 -#define AUDIO_SERVICE_VIDEO 1 /* really? */ - -/* adsp audio addresses are (byte order) domain, service, major, minor */ -//#define AUDIO_ADDR(maj,min) ( (((maj) & 0xff) << 16) | (((min) & 0xff) << 24) | (1) ) - -#define AUDIO_ADDR(maj,min,dom) ( (((min) & 0xff) << 24) | (((maj) & 0xff) << 16) | ((AUDIO_SERVICE_AUDIO) << 8) | (dom) ) - - -/* AAC Encoder modes */ -#define ADSP_AUDIO_ENC_AAC_LC_ONLY_MODE 0 -#define ADSP_AUDIO_ENC_AAC_PLUS_MODE 1 -#define ADSP_AUDIO_ENC_ENHANCED_AAC_PLUS_MODE 2 - -struct adsp_audio_aac_enc_cfg { - u32 bit_rate; /* bits per second */ - u32 encoder_mode; /* ADSP_AUDIO_ENC_* */ -} __attribute__ ((packed)); - -#define ADSP_AUDIO_ENC_SBC_ALLOCATION_METHOD_LOUNDNESS 0 -#define ADSP_AUDIO_ENC_SBC_ALLOCATION_METHOD_SNR 1 - -#define ADSP_AUDIO_ENC_SBC_CHANNEL_MODE_MONO 1 -#define ADSP_AUDIO_ENC_SBC_CHANNEL_MODE_STEREO 2 -#define ADSP_AUDIO_ENC_SBC_CHANNEL_MODE_DUAL 8 -#define ADSP_AUDIO_ENC_SBC_CHANNEL_MODE_JOINT_STEREO 9 - -struct adsp_audio_sbc_encoder_cfg { - u32 num_subbands; - u32 block_len; - u32 channel_mode; - u32 allocation_method; - u32 bit_rate; -} __attribute__ ((packed)); - -/* AMR NB encoder modes */ -#define ADSP_AUDIO_AMR_MR475 0 -#define ADSP_AUDIO_AMR_MR515 1 -#define ADSP_AUDIO_AMR_MMR59 2 -#define ADSP_AUDIO_AMR_MMR67 3 -#define ADSP_AUDIO_AMR_MMR74 4 -#define ADSP_AUDIO_AMR_MMR795 5 -#define ADSP_AUDIO_AMR_MMR102 6 -#define ADSP_AUDIO_AMR_MMR122 7 - -/* The following are valid AMR NB DTX modes */ -#define ADSP_AUDIO_AMR_DTX_MODE_OFF 0 -#define ADSP_AUDIO_AMR_DTX_MODE_ON_VAD1 1 -#define ADSP_AUDIO_AMR_DTX_MODE_ON_VAD2 2 -#define ADSP_AUDIO_AMR_DTX_MODE_ON_AUTO 3 - -/* AMR Encoder configuration */ -struct adsp_audio_amr_enc_cfg { - u32 mode; /* ADSP_AUDIO_AMR_MR* */ - u32 dtx_mode; /* ADSP_AUDIO_AMR_DTX_MODE* */ - u32 enable; /* 1 = enable, 0 = disable */ -} __attribute__ ((packed)); - -struct adsp_audio_qcelp13k_enc_cfg { - u16 min_rate; - u16 max_rate; -} __attribute__ ((packed)); - -struct adsp_audio_evrc_enc_cfg { - u16 min_rate; - u16 max_rate; -} __attribute__ ((packed)); - -union adsp_audio_codec_config { - struct adsp_audio_amr_enc_cfg amr; - struct adsp_audio_aac_enc_cfg aac; - struct adsp_audio_qcelp13k_enc_cfg qcelp13k; - struct adsp_audio_evrc_enc_cfg evrc; - struct adsp_audio_sbc_encoder_cfg sbc; -} __attribute__ ((packed)); - - -/* This is the default value. */ -#define ADSP_AUDIO_OPEN_STREAM_MODE_NONE 0x0000 - -/* This bit, if set, indicates that the AVSync mode is activated. */ -#define ADSP_AUDIO_OPEN_STREAM_MODE_AVSYNC 0x0001 - -/* This bit, if set, indicates that the Sample Rate/Channel Mode */ -/* Change Notification mode is activated. */ -#define ADSP_AUDIO_OPEN_STREAM_MODE_SR_CM_NOTIFY 0x0002 - -/* This bit, if set, indicates that the sync clock is enabled */ -#define ADSP_AUDIO_OPEN_STREAM_MODE_ENABLE_SYNC_CLOCK 0x0004 - -/* This bit, if set, indicates that the AUX PCM loopback is enabled */ -#define ADSP_AUDIO_OPEN_STREAM_MODE_AUX_PCM 0x0040 - -struct adsp_open_command { - struct adsp_command_hdr hdr; - - u32 device; - u32 endpoint; /* address */ - - u32 stream_context; - u32 mode; - - u32 buf_max_size; - - union adsp_audio_format format; - union adsp_audio_codec_config config; -} __attribute__ ((packed)); - - -/* --- audio control and stream session ioctls ---- */ - -/* Opcode to open a device stream session to capture audio */ -#define ADSP_AUDIO_IOCTL_CMD_OPEN_READ 0x0108dd79 - -/* Opcode to open a device stream session to render audio */ -#define ADSP_AUDIO_IOCTL_CMD_OPEN_WRITE 0x0108dd7a - -/* Opcode to open a device session, must open a device */ -#define ADSP_AUDIO_IOCTL_CMD_OPEN_DEVICE 0x0108dd7b - -/* Close an existing stream or device */ -#define ADSP_AUDIO_IOCTL_CMD_CLOSE 0x0108d8bc - - - -/* A device switch requires three IOCTL */ -/* commands in the following sequence: PREPARE, STANDBY, COMMIT */ - -/* adsp_audio_device_switch_command structure is needed for */ -/* DEVICE_SWITCH_PREPARE */ - -/* Device switch protocol step #1. Pause old device and */ -/* generate silence for the old device. */ -#define ADSP_AUDIO_IOCTL_CMD_DEVICE_SWITCH_PREPARE 0x010815c4 - -/* Device switch protocol step #2. Release old device, */ -/* create new device and generate silence for the new device. */ - -/* When client receives ack for this IOCTL, the client can */ -/* start sending IOCTL commands to configure, calibrate and */ -/* change filter settings on the new device. */ -#define ADSP_AUDIO_IOCTL_CMD_DEVICE_SWITCH_STANDBY 0x010815c5 - -/* Device switch protocol step #3. Start normal operations on new device */ -#define ADSP_AUDIO_IOCTL_CMD_DEVICE_SWITCH_COMMIT 0x01075ee7 - -struct adsp_device_switch_command { - struct adsp_command_hdr hdr; - u32 old_device; - u32 new_device; - u8 device_class; /* 0 = i.rx, 1 = i.tx, 2 = e.rx, 3 = e.tx */ - u8 device_type; /* 0 = rx, 1 = tx, 2 = both */ -} __attribute__ ((packed)); - - - -/* --- audio control session ioctls ---- */ - -#define ADSP_PATH_RX 0 -#define ADSP_PATH_TX 1 -#define ADSP_PATH_BOTH 2 -#define ADSP_PATH_TX_CNG_DIS 3 - -struct adsp_audio_dtmf_start_command { - struct adsp_command_hdr hdr; - u32 tone1_hz; - u32 tone2_hz; - u32 duration_usec; - s32 gain_mb; -} __attribute__ ((packed)); - -/* These commands will affect a logical device and all its associated */ -/* streams. */ - -#define ADSP_AUDIO_MAX_EQ_BANDS 12 - -struct adsp_audio_eq_band { - u16 band_idx; /* The band index, 0 .. 11 */ - u32 filter_type; /* Filter band type */ - u32 center_freq_hz; /* Filter band center frequency */ - s32 filter_gain; /* Filter band initial gain (dB) */ - /* Range is +12 dB to -12 dB with 1dB increments. */ - s32 q_factor; - /* Filter band quality factor expressed as q-8 number, */ - /* e.g. 3000/(2^8) */ -} __attribute__ ((packed)); - -struct adsp_audio_eq_stream_config { - uint32_t enable; /* Number of consequtive bands specified */ - uint32_t num_bands; - struct adsp_audio_eq_band eq_bands[ADSP_AUDIO_MAX_EQ_BANDS]; -} __attribute__ ((packed)); - -/* set device equalizer */ -struct adsp_set_dev_equalizer_command { - struct adsp_command_hdr hdr; - u32 device_id; - u32 enable; - u32 num_bands; - struct adsp_audio_eq_band eq_bands[ADSP_AUDIO_MAX_EQ_BANDS]; -} __attribute__ ((packed)); - -/* Set device volume. */ -#define ADSP_AUDIO_IOCTL_CMD_SET_DEVICE_VOL 0x0107605c - -struct adsp_set_dev_volume_command { - struct adsp_command_hdr hdr; - u32 device_id; - u32 path; /* 0 = rx, 1 = tx, 2 = both */ - s32 volume; -} __attribute__ ((packed)); - -/* Set Device stereo volume. This command has data payload, */ -/* struct adsp_audio_set_dev_stereo_volume_command. */ -#define ADSP_AUDIO_IOCTL_SET_DEVICE_STEREO_VOL 0x0108df3e - -/* Set L, R cross channel gain for a Device. This command has */ -/* data payload, struct adsp_audio_set_dev_x_chan_gain_command. */ -#define ADSP_AUDIO_IOCTL_SET_DEVICE_XCHAN_GAIN 0x0108df40 - -/* Set device mute state. */ -#define ADSP_AUDIO_IOCTL_CMD_SET_DEVICE_MUTE 0x0107605f - -struct adsp_set_dev_mute_command { - struct adsp_command_hdr hdr; - u32 device_id; - u32 path; /* 0 = rx, 1 = tx, 2 = both */ - u32 mute; /* 1 = mute */ -} __attribute__ ((packed)); - -/* Configure Equalizer for a device. */ -/* This command has payload struct adsp_audio_set_dev_equalizer_command. */ -#define ADSP_AUDIO_IOCTL_CMD_SET_DEVICE_EQ_CONFIG 0x0108b10e - -/* Set configuration data for an algorithm aspect of a device. */ -/* This command has payload struct adsp_audio_set_dev_cfg_command. */ -#define ADSP_AUDIO_IOCTL_SET_DEVICE_CONFIG 0x0108b6cb - -struct adsp_set_dev_cfg_command { - struct adsp_command_hdr hdr; - u32 device_id; - u32 block_id; - u32 interface_id; - u32 phys_addr; - u32 phys_size; - u32 phys_used; -} __attribute__ ((packed)); - -/* Set configuration data for all interfaces of a device. */ -#define ADSP_AUDIO_IOCTL_SET_DEVICE_CONFIG_TABLE 0x0108b6bf - -struct adsp_set_dev_cfg_table_command { - struct adsp_command_hdr hdr; - u32 device_id; - u32 phys_addr; - u32 phys_size; - u32 phys_used; -} __attribute__ ((packed)); - -/* ---- audio stream data commands ---- */ - -#define ADSP_AUDIO_IOCTL_CMD_DATA_TX 0x0108dd7f -#define ADSP_AUDIO_IOCTL_CMD_DATA_RX 0x0108dd80 - -struct adsp_buffer_command { - struct adsp_command_hdr hdr; - struct adsp_audio_buffer buffer; -} __attribute__ ((packed)); - - - -/* ---- audio stream ioctls (only affect a single stream in a session) ---- */ - -/* Stop stream for audio device. */ -#define ADSP_AUDIO_IOCTL_CMD_STREAM_STOP 0x01075c54 - -/* End of stream reached. Client will not send any more data. */ -#define ADSP_AUDIO_IOCTL_CMD_STREAM_EOS 0x0108b150 - -/* Do sample slipping/stuffing on AAC outputs. The payload of */ -/* this command is struct adsp_audio_slip_sample_command. */ -#define ADSP_AUDIO_IOCTL_CMD_STREAM_SLIPSAMPLE 0x0108d40e - -/* Set stream volume. */ -/* This command has data payload, struct adsp_audio_set_volume_command. */ -#define ADSP_AUDIO_IOCTL_CMD_SET_STREAM_VOL 0x0108c0de - -/* Set stream stereo volume. This command has data payload, */ -/* struct adsp_audio_set_stereo_volume_command. */ -#define ADSP_AUDIO_IOCTL_SET_STREAM_STEREO_VOL 0x0108dd7c - -/* Set L, R cross channel gain for a Stream. This command has */ -/* data payload, struct adsp_audio_set_x_chan_gain_command. */ -#define ADSP_AUDIO_IOCTL_SET_STREAM_XCHAN_GAIN 0x0108dd7d - -/* Set stream mute state. */ -/* This command has data payload, struct adsp_audio_set_stream_mute. */ -#define ADSP_AUDIO_IOCTL_CMD_SET_STREAM_MUTE 0x0108c0df - -/* Reconfigure bit rate information. This command has data */ -/* payload, struct adsp_audio_set_bit_rate_command */ -#define ADSP_AUDIO_IOCTL_SET_STREAM_BITRATE 0x0108ccf1 - -/* Set Channel Mapping. This command has data payload, struct */ -/* This command has data payload struct adsp_audio_set_channel_map_command. */ -#define ADSP_AUDIO_IOCTL_SET_STREAM_CHANNELMAP 0x0108d32a - -/* Enable/disable AACPlus SBR. */ -/* This command has data payload struct adsp_audio_set_sbr_command */ -#define ADSP_AUDIO_IOCTL_SET_STREAM_SBR 0x0108d416 - -/* Enable/disable WMA Pro Chex and Fex. This command has data payload */ -/* struct adsp_audio_stream_set_wma_command. */ -#define ADSP_AUDIO_IOCTL_SET_STREAM_WMAPRO 0x0108d417 - - -/* ---- audio session ioctls (affect all streams in a session) --- */ - -/* Start stream for audio device. */ -#define ADSP_AUDIO_IOCTL_CMD_SESSION_START 0x010815c6 - -/* Stop all stream(s) for audio session as indicated by major id. */ -#define ADSP_AUDIO_IOCTL_CMD_SESSION_STOP 0x0108dd7e - -/* Pause the data flow for a session as indicated by major id. */ -#define ADSP_AUDIO_IOCTL_CMD_SESSION_PAUSE 0x01075ee8 - -/* Resume the data flow for a session as indicated by major id. */ -#define ADSP_AUDIO_IOCTL_CMD_SESSION_RESUME 0x01075ee9 - -/* Drop any unprocessed data buffers for a session as indicated by major id. */ -#define ADSP_AUDIO_IOCTL_CMD_SESSION_FLUSH 0x01075eea - -/* Start Stream DTMF tone */ -#define ADSP_AUDIO_IOCTL_CMD_SESSION_DTMF_START 0x0108c0dd - -/* Stop Stream DTMF tone */ -#define ADSP_AUDIO_IOCTL_CMD_SESSION_DTMF_STOP 0x01087554 - -/* Set Session volume. */ -/* This command has data payload, struct adsp_audio_set_volume_command. */ -#define ADSP_AUDIO_IOCTL_SET_SESSION_VOL 0x0108d8bd - -/* Set session stereo volume. This command has data payload, */ -/* struct adsp_audio_set_stereo_volume_command. */ -#define ADSP_AUDIO_IOCTL_SET_SESSION_STEREO_VOL 0x0108df3d - -/* Set L, R cross channel gain for a session. This command has */ -/* data payload, struct adsp_audio_set_x_chan_gain_command. */ -#define ADSP_AUDIO_IOCTL_SET_SESSION_XCHAN_GAIN 0x0108df3f - -/* Set Session mute state. */ -/* This command has data payload, struct adsp_audio_set_mute_command. */ -#define ADSP_AUDIO_IOCTL_SET_SESSION_MUTE 0x0108d8be - -/* Configure Equalizer for a stream. */ -/* This command has payload struct adsp_audio_set_equalizer_command. */ -#define ADSP_AUDIO_IOCTL_SET_SESSION_EQ_CONFIG 0x0108c0e0 - -/* Set Audio Video sync information. */ -/* This command has data payload, struct adsp_audio_set_av_sync_command. */ -#define ADSP_AUDIO_IOCTL_SET_SESSION_AVSYNC 0x0108d1e2 - -/* Get Audio Media Session time. */ -/* This command returns the audioTime in adsp_audio_unsigned64_event */ -#define ADSP_AUDIO_IOCTL_CMD_GET_AUDIO_TIME 0x0108c26c - - -/* these command structures are used for both STREAM and SESSION ioctls */ - -struct adsp_set_volume_command { - struct adsp_command_hdr hdr; - s32 volume; -} __attribute__ ((packed)); - -struct adsp_set_mute_command { - struct adsp_command_hdr hdr; - u32 mute; /* 1 == mute */ -} __attribute__ ((packed)); - - -struct adsp_set_equalizer_command { - struct adsp_command_hdr hdr; - u32 enable; - u32 num_bands; - struct adsp_audio_eq_band eq_bands[ADSP_AUDIO_MAX_EQ_BANDS]; -} __attribute__ ((packed)); - -/* ---- audio events ---- */ - -/* All IOCTL commands generate an event with the IOCTL opcode as the */ -/* event id after the IOCTL command has been executed. */ - -/* This event is generated after a media stream session is opened. */ -#define ADSP_AUDIO_EVT_STATUS_OPEN 0x0108c0d6 - -/* This event is generated after a media stream session is closed. */ -#define ADSP_AUDIO_EVT_STATUS_CLOSE 0x0108c0d7 - -/* Asyncronous buffer consumption. This event is generated after a */ -/* recived buffer is consumed during rendering or filled during */ -/* capture opeartion. */ -#define ADSP_AUDIO_EVT_STATUS_BUF_DONE 0x0108c0d8 - -/* This event is generated when rendering operation is starving for */ -/* data. In order to avoid audio loss at the end of a plauback, the */ -/* client should wait for this event before issuing the close command. */ -#define ADSP_AUDIO_EVT_STATUS_BUF_UNDERRUN 0x0108c0d9 - -/* This event is generated during capture operation when there are no */ -/* buffers available to copy the captured audio data */ -#define ADSP_AUDIO_EVT_STATUS_BUF_OVERFLOW 0x0108c0da - -/* This asynchronous event is generated as a result of an input */ -/* sample rate change and/or channel mode change detected by the */ -/* decoder. The event payload data is an array of 2 uint32 */ -/* values containing the sample rate in Hz and channel mode. */ -#define ADSP_AUDIO_EVT_SR_CM_CHANGE 0x0108d329 - -struct adsp_event_hdr { - u32 evt_handle; /* DAL common header */ - u32 evt_cookie; - u32 evt_length; - - u32 src; /* "source" audio address */ - u32 dst; /* "destination" audio address */ - - u32 event_id; - u32 response_type; - u32 seq_number; - - u32 context; /* opaque to DSP */ - u32 data; - - u32 status; -} __attribute__ ((packed)); - -struct adsp_buffer_event { - struct adsp_event_hdr hdr; - struct adsp_audio_buffer buffer; -} __attribute__ ((packed)); - - -/* ---- audio device IDs ---- */ - -/* Device direction Rx/Tx flag */ -#define ADSP_AUDIO_RX_DEVICE 0x00 -#define ADSP_AUDIO_TX_DEVICE 0x01 - -/* Default RX or TX device */ -#define ADSP_AUDIO_DEVICE_ID_DEFAULT 0x1081679 - -/* Source (TX) devices */ -#define ADSP_AUDIO_DEVICE_ID_HANDSET_MIC 0x107ac8d -#define ADSP_AUDIO_DEVICE_ID_HEADSET_MIC 0x1081510 -#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MIC 0x1081512 -#define ADSP_AUDIO_DEVICE_ID_BT_SCO_MIC 0x1081518 -#define ADSP_AUDIO_DEVICE_ID_AUXPCM_TX 0x1081518 -#define ADSP_AUDIO_DEVICE_ID_TTY_HEADSET_MIC 0x108151b -#define ADSP_AUDIO_DEVICE_ID_I2S_MIC 0x1089bf3 - -#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_DUAL_MIC 0x108f9c5 -#define ADSP_AUDIO_DEVICE_ID_HANDSET_DUAL_MIC 0x108f9c3 - -/* Special loopback pseudo device to be paired with an RX device */ -/* with usage ADSP_AUDIO_DEVICE_USAGE_MIXED_PCM_LOOPBACK */ -#define ADSP_AUDIO_DEVICE_ID_MIXED_PCM_LOOPBACK_TX 0x1089bf2 - -/* Sink (RX) devices */ -#define ADSP_AUDIO_DEVICE_ID_HANDSET_SPKR 0x107ac88 -#define ADSP_AUDIO_DEVICE_ID_HEADSET_SPKR_MONO 0x1081511 -#define ADSP_AUDIO_DEVICE_ID_HEADSET_SPKR_STEREO 0x107ac8a -#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO 0x1081513 -#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO_W_MONO_HEADSET 0x108c508 -#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO_W_STEREO_HEADSET 0x108c894 -#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO 0x1081514 -#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO_W_MONO_HEADSET 0x108c895 -#define ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO_W_STEREO_HEADSET 0x108c509 -#define ADSP_AUDIO_DEVICE_ID_BT_SCO_SPKR 0x1081519 -#define ADSP_AUDIO_DEVICE_ID_AUXPCM_RX 0x1081519 -#define ADSP_AUDIO_DEVICE_ID_TTY_HEADSET_SPKR 0x108151c -#define ADSP_AUDIO_DEVICE_ID_I2S_SPKR 0x1089bf4 -#define ADSP_AUDIO_DEVICE_ID_NULL_SINK 0x108e512 - -/* BT A2DP playback device. */ -/* This device must be paired with */ -/* ADSP_AUDIO_DEVICE_ID_MIXED_PCM_LOOPBACK_TX using */ -/* ADSP_AUDIO_DEVICE_USAGE_MIXED_PCM_LOOPBACK mode */ -#define ADSP_AUDIO_DEVICE_ID_BT_A2DP_SPKR 0x108151a - -/* Voice Destination identifier - specifically used for */ -/* controlling Voice module from the Device Control Session */ -#define ADSP_AUDIO_DEVICE_ID_VOICE 0x0108df3c - -/* Audio device usage types. */ -/* This is a bit mask to determine which topology to use in the */ -/* device session */ -#define ADSP_AUDIO_DEVICE_CONTEXT_VOICE 0x01 -#define ADSP_AUDIO_DEVICE_CONTEXT_PLAYBACK 0x02 -#define ADSP_AUDIO_DEVICE_CONTEXT_MIXED_RECORD 0x10 -#define ADSP_AUDIO_DEVICE_CONTEXT_RECORD 0x20 -#define ADSP_AUDIO_DEVICE_CONTEXT_PCM_LOOPBACK 0x40 - -/* ADSP audio driver return codes */ -#define ADSP_AUDIO_STATUS_SUCCESS 0 -#define ADSP_AUDIO_STATUS_EUNSUPPORTED 20 - -#endif diff --git a/arch/arm/mach-msm/qdsp6/dal_audio_format.h b/arch/arm/mach-msm/qdsp6/dal_audio_format.h deleted file mode 100644 index 4223974b28048334a22e0ebb19f492324cb035dc..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/dal_audio_format.h +++ /dev/null @@ -1,270 +0,0 @@ -/* Copyright (c) 2009, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __ADSP_AUDIO_MEDIA_FORMAT_H -#define __ADSP_AUDIO_MEDIA_FORMAT_H - - - -/* Supported audio media formats */ - -/* format block in shmem */ -#define ADSP_AUDIO_FORMAT_SHAREDMEMORY 0x01091a78 -/* adsp_audio_format_raw_pcm type */ -#define ADSP_AUDIO_FORMAT_PCM 0x0103d2fd -/* adsp_audio_format_raw_pcm type */ -#define ADSP_AUDIO_FORMAT_DTMF 0x01087725 -/* adsp_audio_format_adpcm type */ -#define ADSP_AUDIO_FORMAT_ADPCM 0x0103d2ff -/* Yamaha PCM format */ -#define ADSP_AUDIO_FORMAT_YADPCM 0x0108dc07 -/* ISO/IEC 11172 */ -#define ADSP_AUDIO_FORMAT_MP3 0x0103d308 -/* ISO/IEC 14496 */ -#define ADSP_AUDIO_FORMAT_MPEG4_AAC 0x010422f1 -/* AMR-NB audio in FS format */ -#define ADSP_AUDIO_FORMAT_AMRNB_FS 0x0105c16c -/* AMR-WB audio in FS format */ -#define ADSP_AUDIO_FORMAT_AMRWB_FS 0x0105c16e -/* QCELP 13k, IS733 */ -#define ADSP_AUDIO_FORMAT_V13K_FS 0x01080b8a -/* EVRC 8k, IS127 */ -#define ADSP_AUDIO_FORMAT_EVRC_FS 0x01080b89 -/* EVRC-B 8k, 4GV */ -#define ADSP_AUDIO_FORMAT_EVRCB_FS 0x0108f2a3 -/* MIDI command stream */ -#define ADSP_AUDIO_FORMAT_MIDI 0x0103d300 -/* A2DP SBC stream */ -#define ADSP_AUDIO_FORMAT_SBC 0x0108c4d8 -/* Version 10 Professional */ -#define ADSP_AUDIO_FORMAT_WMA_V10PRO 0x0108aa92 -/* Version 9 Starndard */ -#define ADSP_AUDIO_FORMAT_WMA_V9 0x0108d430 -/* AMR WideBand Plus */ -#define ADSP_AUDIO_FORMAT_AMR_WB_PLUS 0x0108f3da -/* AC3 Decoder */ -#define ADSP_AUDIO_FORMAT_AC3_DECODER 0x0108d5f9 - - -/* Not yet supported audio media formats */ - - - -/* ISO/IEC 13818 */ -#define ADSP_AUDIO_FORMAT_MPEG2_AAC 0x0103d309 -/* 3GPP TS 26.101 Sec 4.0 */ -#define ADSP_AUDIO_FORMAT_AMRNB_IF1 0x0103d305 -/* 3GPP TS 26.101 Annex A */ -#define ADSP_AUDIO_FORMAT_AMRNB_IF2 0x01057b31 -/* 3GPP TS 26.201 */ -#define ADSP_AUDIO_FORMAT_AMRWB_IF1 0x0103d306 -/* 3GPP TS 26.201 */ -#define ADSP_AUDIO_FORMAT_AMRWB_IF2 0x0105c16d -/* G.711 */ -#define ADSP_AUDIO_FORMAT_G711 0x0106201d -/* QCELP 8k, IS96A */ -#define ADSP_AUDIO_FORMAT_V8K_FS 0x01081d29 -/* Version 1 codec */ -#define ADSP_AUDIO_FORMAT_WMA_V1 0x01055b2b -/* Version 2, 7 & 8 codec */ -#define ADSP_AUDIO_FORMAT_WMA_V8 0x01055b2c -/* Version 9 Professional codec */ -#define ADSP_AUDIO_FORMAT_WMA_V9PRO 0x01055b2d -/* Version 9 Voice codec */ -#define ADSP_AUDIO_FORMAT_WMA_SP1 0x01055b2e -/* Version 9 Lossless codec */ -#define ADSP_AUDIO_FORMAT_WMA_LOSSLESS 0x01055b2f -/* Real Media content, low-bitrate */ -#define ADSP_AUDIO_FORMAT_RA_SIPR 0x01042a0f -/* Real Media content */ -#define ADSP_AUDIO_FORMAT_RA_COOK 0x01042a0e - - -/* For all of the audio formats, unless specified otherwise, */ -/* the following apply: */ -/* Format block bits are arranged in bytes and words in little-endian */ -/* order, i.e., least-significant bit first and least-significant */ -/* byte first. */ - - - -/* AAC Format Block. */ - -/* AAC format block consist of a format identifier followed by */ -/* AudioSpecificConfig formatted according to ISO/IEC 14496-3 */ - -/* The following AAC format identifiers are supported */ -#define ADSP_AUDIO_AAC_ADTS 0x010619cf -#define ADSP_AUDIO_AAC_MPEG4_ADTS 0x010619d0 -#define ADSP_AUDIO_AAC_LOAS 0x010619d1 -#define ADSP_AUDIO_AAC_ADIF 0x010619d2 -#define ADSP_AUDIO_AAC_RAW 0x010619d3 -#define ADSP_AUDIO_AAC_FRAMED_RAW 0x0108c1fb - - -#define ADSP_AUDIO_COMPANDING_ALAW 0x10619cd -#define ADSP_AUDIO_COMPANDING_MLAW 0x10619ce - -/* Maxmum number of bytes allowed in a format block */ -#define ADSP_AUDIO_FORMAT_DATA_MAX 16 - - -struct adsp_audio_no_payload_format { - /* Media Format Code (must always be first element) */ - u32 format; - - /* no payload for this format type */ -} __attribute__ ((packed)); - - -/* For convenience, to be used as a standard format block */ -/* for various media types that don't need a unique format block */ -/* ie. PCM, DTMF, etc. */ -struct adsp_audio_standard_format { - /* Media Format Code (must always be first element) */ - u32 format; - - /* payload */ - u16 channels; - u16 bits_per_sample; - u32 sampling_rate; - u8 is_signed; - u8 is_interleaved; -} __attribute__ ((packed)); - - - -/* ADPCM format block */ -struct adsp_audio_adpcm_format { - /* Media Format Code (must always be first element) */ - u32 format; - - /* payload */ - u16 channels; - u16 bits_per_sample; - u32 sampling_rate; - u8 is_signed; - u8 is_interleaved; - u32 block_size; -} __attribute__ ((packed)); - - -/* MIDI format block */ -struct adsp_audio_midi_format { - /* Media Format Code (must always be first element) */ - u32 format; - - /* payload */ - u32 sampling_rate; - u16 channels; - u16 mode; -} __attribute__ ((packed)); - - -/* G711 format block */ -struct adsp_audio_g711_format { - /* Media Format Code (must always be first element) */ - u32 format; - - /* payload */ - u32 companding; -} __attribute__ ((packed)); - - -struct adsp_audio_wma_pro_format { - /* Media Format Code (must always be first element) */ - u32 format; - - /* payload */ - u16 format_tag; - u16 channels; - u32 samples_per_sec; - u32 avg_bytes_per_sec; - u16 block_align; - u16 valid_bits_per_sample; - u32 channel_mask; - u16 encode_opt; - u16 advanced_encode_opt; - u32 advanced_encode_opt2; - u32 drc_peak_reference; - u32 drc_peak_target; - u32 drc_average_reference; - u32 drc_average_target; -} __attribute__ ((packed)); - - -struct adsp_audio_amrwb_plus_format { - /* Media Format Code (must always be first element) */ - u32 format; - - /* payload */ - u32 size; - u32 version; - u32 channels; - u32 amr_band_mode; - u32 amr_dtx_mode; - u32 amr_frame_format; - u32 amr_isf_index; -} __attribute__ ((packed)); - - -/* Binary Byte Stream Format */ -/* Binary format type that defines a byte stream, */ -/* can be used to specify any format (ie. AAC) */ -struct adsp_audio_binary_format { - /* Media Format Code (must always be first element) */ - u32 format; - - /* payload */ - /* number of bytes set in byte stream */ - u32 num_bytes; - /* Byte stream binary data */ - u8 data[ADSP_AUDIO_FORMAT_DATA_MAX]; -} __attribute__ ((packed)); - - -struct adsp_audio_shared_memory_format { - /* Media Format Code (must always be first element) */ - u32 format; - - /* Number of bytes in shared memory */ - u32 len; - /* Phyisical address to data in shared memory */ - u32 address; -} __attribute__ ((packed)); - - -/* Union of all format types */ -union adsp_audio_format { - /* Basic format block with no payload */ - struct adsp_audio_no_payload_format no_payload; - /* Generic format block PCM, DTMF */ - struct adsp_audio_standard_format standard; - /* ADPCM format block */ - struct adsp_audio_adpcm_format adpcm; - /* MIDI format block */ - struct adsp_audio_midi_format midi; - /* G711 format block */ - struct adsp_audio_g711_format g711; - /* WmaPro format block */ - struct adsp_audio_wma_pro_format wma_pro; - /* WmaPro format block */ - struct adsp_audio_amrwb_plus_format amrwb_plus; - /* binary (byte stream) format block, used for AAC */ - struct adsp_audio_binary_format binary; - /* format block in shared memory */ - struct adsp_audio_shared_memory_format shared_mem; -}; - -#endif - diff --git a/arch/arm/mach-msm/qdsp6/dsp_debug.c b/arch/arm/mach-msm/qdsp6/dsp_debug.c deleted file mode 100644 index 922f8cd39cdcfe7d60d5cde68dce91e95918ccd6..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/dsp_debug.c +++ /dev/null @@ -1,179 +0,0 @@ -/* arch/arm/mach-msm/qdsp6/dsp_dump.c - * - * Copyright (C) 2009 Google, Inc. - * Author: Brian Swetland - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -static wait_queue_head_t dsp_wait; -static int dsp_has_crashed; -static int dsp_wait_count; - -static atomic_t dsp_crash_count = ATOMIC_INIT(0); - -void q6audio_dsp_not_responding(void) -{ - - if (atomic_add_return(1, &dsp_crash_count) != 1) { - pr_err("q6audio_dsp_not_responding() - parking additional crasher...\n"); - for (;;) - msleep(1000); - } - if (dsp_wait_count) { - dsp_has_crashed = 1; - wake_up(&dsp_wait); - - while (dsp_has_crashed != 2) - wait_event(dsp_wait, dsp_has_crashed == 2); - } else { - pr_err("q6audio_dsp_not_responding() - no waiter?\n"); - } - BUG(); -} - -static int dsp_open(struct inode *inode, struct file *file) -{ - return 0; -} - -static ssize_t dsp_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - char cmd[32]; - - if (count >= sizeof(cmd)) - return -EINVAL; - if (copy_from_user(cmd, buf, count)) - return -EFAULT; - cmd[count] = 0; - - if ((count > 1) && (cmd[count-1] == '\n')) - cmd[count-1] = 0; - - if (!strcmp(cmd, "wait-for-crash")) { - while (!dsp_has_crashed) { - int res; - dsp_wait_count++; - res = wait_event_interruptible(dsp_wait, dsp_has_crashed); - if (res < 0) { - dsp_wait_count--; - return res; - } - } -#if defined(CONFIG_MACH_MAHIMAHI) - /* assert DSP NMI */ - msm_proc_comm(PCOM_CUSTOMER_CMD1, 0, 0); - msleep(250); -#endif - } else if (!strcmp(cmd, "boom")) { - q6audio_dsp_not_responding(); - } else if (!strcmp(cmd, "continue-crash")) { - dsp_has_crashed = 2; - wake_up(&dsp_wait); - } else { - pr_err("[%s:%s] unknown dsp_debug command: %s\n", __MM_FILE__, - __func__, cmd); - } - - return count; -} - -#define DSP_RAM_BASE 0x2E800000 -#define DSP_RAM_SIZE 0x01800000 - -static unsigned copy_ok_count; - -static ssize_t dsp_read(struct file *file, char __user *buf, - size_t count, loff_t *pos) -{ - size_t actual = 0; - size_t mapsize = PAGE_SIZE; - unsigned addr; - void __iomem *ptr; - - if (*pos >= DSP_RAM_SIZE) - return 0; - - if (*pos & (PAGE_SIZE - 1)) - return -EINVAL; - - addr = (*pos + DSP_RAM_BASE); - - /* don't blow up if we're unaligned */ - if (addr & (PAGE_SIZE - 1)) - mapsize *= 2; - - while (count >= PAGE_SIZE) { - ptr = ioremap(addr, mapsize); - if (!ptr) { - pr_err("[%s:%s] map error @ %x\n", __MM_FILE__, - __func__, addr); - return -EFAULT; - } - if (copy_to_user(buf, ptr, PAGE_SIZE)) { - iounmap(ptr); - pr_err("[%s:%s] copy error @ %p\n", __MM_FILE__, - __func__, buf); - return -EFAULT; - } - copy_ok_count += PAGE_SIZE; - iounmap(ptr); - addr += PAGE_SIZE; - buf += PAGE_SIZE; - actual += PAGE_SIZE; - count -= PAGE_SIZE; - } - - *pos += actual; - return actual; -} - -static int dsp_release(struct inode *inode, struct file *file) -{ - return 0; -} - -static const struct file_operations dsp_fops = { - .owner = THIS_MODULE, - .open = dsp_open, - .read = dsp_read, - .write = dsp_write, - .release = dsp_release, -}; - -static struct miscdevice dsp_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "dsp_debug", - .fops = &dsp_fops, -}; - - -static int __init dsp_init(void) -{ - init_waitqueue_head(&dsp_wait); - return misc_register(&dsp_misc); -} - -device_initcall(dsp_init); diff --git a/arch/arm/mach-msm/qdsp6/dtmf.c b/arch/arm/mach-msm/qdsp6/dtmf.c deleted file mode 100644 index 30978df9b97d5a50a2ed8ae60aa7487653d7c6a6..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/dtmf.c +++ /dev/null @@ -1,126 +0,0 @@ -/* Copyright (c) 2010, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -struct dtmf { - struct mutex lock; - struct audio_client *ac; - struct msm_dtmf_config cfg; -}; - -static long dtmf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct dtmf *dtmf = file->private_data; - int rc = 0; - - mutex_lock(&dtmf->lock); - switch (cmd) { - - case AUDIO_START: { - pr_debug("[%s:%s] AUDIO_START\n", __MM_FILE__, __func__); - if (dtmf->ac) { - pr_err("[%s:%s] active session already existing\n", - __MM_FILE__, __func__); - rc = -EBUSY; - } else { - dtmf->ac = q6audio_open_dtmf(48000, 2, 0); - if (!dtmf->ac) - rc = -ENOMEM; - } - break; - } - case AUDIO_PLAY_DTMF: { - rc = copy_from_user((void *)&dtmf->cfg, (void *)arg, - sizeof(struct msm_dtmf_config)); - - pr_debug("[%s:%s] PLAY_DTMF: high = %d, low = %d\n", - __MM_FILE__, __func__, dtmf->cfg.dtmf_hi, - dtmf->cfg.dtmf_low); - rc = q6audio_play_dtmf(dtmf->ac, dtmf->cfg.dtmf_hi, - dtmf->cfg.dtmf_low, dtmf->cfg.duration, - dtmf->cfg.rx_gain); - if (rc) { - pr_err("[%s:%s] DTMF_START failed\n", __MM_FILE__, - __func__); - break; - } - break; - } - default: - rc = -EINVAL; - } - mutex_unlock(&dtmf->lock); - - pr_debug("[%s:%s] rc = %d\n", __MM_FILE__, __func__, rc) ; - return rc; -} - -static int dtmf_open(struct inode *inode, struct file *file) -{ - int rc = 0; - - struct dtmf *dtmf; - pr_info("[%s:%s] open\n", __MM_FILE__, __func__); - dtmf = kzalloc(sizeof(struct dtmf), GFP_KERNEL); - - if (!dtmf) - return -ENOMEM; - - mutex_init(&dtmf->lock); - - file->private_data = dtmf; - return rc; -} - -static int dtmf_release(struct inode *inode, struct file *file) -{ - struct dtmf *dtmf = file->private_data; - if (dtmf->ac) - q6audio_close(dtmf->ac); - kfree(dtmf); - pr_info("[%s:%s] release\n", __MM_FILE__, __func__); - return 0; -} - -static const struct file_operations dtmf_fops = { - .owner = THIS_MODULE, - .open = dtmf_open, - .release = dtmf_release, - .unlocked_ioctl = dtmf_ioctl, -}; - -struct miscdevice dtmf_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_dtmf", - .fops = &dtmf_fops, -}; - -static int __init dtmf_init(void) -{ - return misc_register(&dtmf_misc); -} - -device_initcall(dtmf_init); diff --git a/arch/arm/mach-msm/qdsp6/evrc_in.c b/arch/arm/mach-msm/qdsp6/evrc_in.c deleted file mode 100644 index e059efaefa5cdff9cad893329fb02a30c143e531..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/evrc_in.c +++ /dev/null @@ -1,468 +0,0 @@ -/* - * Copyright (C) 2009 Google, Inc. - * Copyright (C) 2009 HTC Corporation - * Copyright (c) 2010, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "dal_audio_format.h" -#include - -#define EVRC_FC_BUFF_CNT 10 -#define EVRC_READ_TIMEOUT 2000 -struct evrc_fc_buff { - struct mutex lock; - int empty; - void *data; - int size; - int actual_size; -}; - -struct evrc_fc { - struct task_struct *task; - wait_queue_head_t fc_wq; - struct evrc_fc_buff fc_buff[EVRC_FC_BUFF_CNT]; - int buff_index; -}; - -struct evrc { - struct mutex lock; - struct msm_audio_evrc_enc_config cfg; - struct msm_audio_stream_config str_cfg; - struct audio_client *audio_client; - struct msm_voicerec_mode voicerec_mode; - struct evrc_fc *evrc_fc; -}; - - -static int q6_evrc_flowcontrol(void *data) -{ - struct audio_client *ac; - struct audio_buffer *ab; - struct evrc *evrc = data; - int buff_index = 0; - int xfer = 0; - struct evrc_fc *fc; - - - ac = evrc->audio_client; - fc = evrc->evrc_fc; - if (!ac) { - pr_err("[%s:%s] audio_client is NULL\n", __MM_FILE__, __func__); - return 0; - } - - while (!kthread_should_stop()) { - ab = ac->buf + ac->cpu_buf; - if (ab->used) - wait_event(ac->wait, (ab->used == 0)); - pr_debug("[%s:%s] ab->data = %p, cpu_buf = %d\n", __MM_FILE__, - __func__, ab->data, ac->cpu_buf); - xfer = ab->actual_size; - - - mutex_lock(&(fc->fc_buff[buff_index].lock)); - if (!fc->fc_buff[buff_index].empty) { - pr_err("[%s:%s] flow control buffer[%d] not read!\n", - __MM_FILE__, __func__, buff_index); - } - - if (fc->fc_buff[buff_index].size < xfer) { - pr_err("[%s:%s] buffer %d too small\n", __MM_FILE__, - __func__, buff_index); - memcpy(fc->fc_buff[buff_index].data, ab->data, - fc->fc_buff[buff_index].size); - fc->fc_buff[buff_index].empty = 0; - fc->fc_buff[buff_index].actual_size = - fc->fc_buff[buff_index].size; - } else { - memcpy(fc->fc_buff[buff_index].data, ab->data, xfer); - fc->fc_buff[buff_index].empty = 0; - fc->fc_buff[buff_index].actual_size = xfer; - } - mutex_unlock(&(fc->fc_buff[buff_index].lock)); - /*wake up client, if any*/ - wake_up(&fc->fc_wq); - - buff_index++; - if (buff_index >= EVRC_FC_BUFF_CNT) - buff_index = 0; - - ab->used = 1; - - q6audio_read(ac, ab); - ac->cpu_buf ^= 1; - } - - return 0; -} -static long q6_evrc_in_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct evrc *evrc = file->private_data; - int rc = 0; - int i = 0; - struct evrc_fc *fc; - int size = 0; - - mutex_lock(&evrc->lock); - switch (cmd) { - case AUDIO_SET_VOLUME: - pr_debug("[%s:%s] SET_VOLUME\n", __MM_FILE__, __func__); - break; - case AUDIO_GET_STATS: - { - struct msm_audio_stats stats; - pr_debug("[%s:%s] GET_STATS\n", __MM_FILE__, __func__); - memset(&stats, 0, sizeof(stats)); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - case AUDIO_START: - { - uint32_t acdb_id; - pr_debug("[%s:%s] AUDIO_START\n", __MM_FILE__, __func__); - if (arg == 0) { - acdb_id = 0; - } else { - if (copy_from_user(&acdb_id, (void *) arg, - sizeof(acdb_id))) { - rc = -EFAULT; - break; - } - } - if (evrc->audio_client) { - rc = -EBUSY; - pr_err("[%s:%s] active session already existing\n", - __MM_FILE__, __func__); - break; - } else { - evrc->audio_client = q6audio_open_qcp( - evrc->str_cfg.buffer_size, - evrc->cfg.min_bit_rate, - evrc->cfg.max_bit_rate, - evrc->voicerec_mode.rec_mode, - ADSP_AUDIO_FORMAT_EVRC_FS, - acdb_id); - - if (!evrc->audio_client) { - pr_err("[%s:%s] evrc open session failed\n", - __MM_FILE__, __func__); - kfree(evrc); - rc = -ENOMEM; - break; - } - } - - /*allocate flow control buffers*/ - fc = evrc->evrc_fc; - size = evrc->str_cfg.buffer_size; - for (i = 0; i < EVRC_FC_BUFF_CNT; ++i) { - mutex_init(&(fc->fc_buff[i].lock)); - fc->fc_buff[i].empty = 1; - fc->fc_buff[i].data = kmalloc(size, GFP_KERNEL); - if (fc->fc_buff[i].data == NULL) { - pr_err("[%s:%s] No memory for FC buffers\n", - __MM_FILE__, __func__); - rc = -ENOMEM; - goto fc_fail; - } - fc->fc_buff[i].size = size; - fc->fc_buff[i].actual_size = 0; - } - - /*create flow control thread*/ - fc->task = kthread_run(q6_evrc_flowcontrol, - evrc, "evrc_flowcontrol"); - if (IS_ERR(fc->task)) { - rc = PTR_ERR(fc->task); - pr_err("[%s:%s] error creating flow control thread\n", - __MM_FILE__, __func__); - goto fc_fail; - } - break; -fc_fail: - /*free flow control buffers*/ - --i; - for (; i >= 0; i--) { - kfree(fc->fc_buff[i].data); - fc->fc_buff[i].data = NULL; - } - break; - } - case AUDIO_STOP: - pr_debug("[%s:%s] AUDIO_STOP\n", __MM_FILE__, __func__); - break; - case AUDIO_FLUSH: - break; - case AUDIO_SET_INCALL: { - pr_debug("[%s:%s] SET_INCALL\n", __MM_FILE__, __func__); - if (copy_from_user(&evrc->voicerec_mode, - (void *)arg, sizeof(struct msm_voicerec_mode))) - rc = -EFAULT; - - if (evrc->voicerec_mode.rec_mode != AUDIO_FLAG_READ - && evrc->voicerec_mode.rec_mode != - AUDIO_FLAG_INCALL_MIXED) { - evrc->voicerec_mode.rec_mode = AUDIO_FLAG_READ; - pr_err("[%s:%s] Invalid rec_mode\n", __MM_FILE__, - __func__); - rc = -EINVAL; - } - break; - } - case AUDIO_GET_STREAM_CONFIG: - if (copy_to_user((void *)arg, &evrc->str_cfg, - sizeof(struct msm_audio_stream_config))) - rc = -EFAULT; - - pr_debug("[%s:%s] GET_STREAM_CONFIG: buffsz=%d, buffcnt=%d\n", - __MM_FILE__, __func__, evrc->str_cfg.buffer_size, - evrc->str_cfg.buffer_count); - break; - case AUDIO_SET_STREAM_CONFIG: - if (copy_from_user(&evrc->str_cfg, (void *)arg, - sizeof(struct msm_audio_stream_config))) { - rc = -EFAULT; - break; - } - - pr_debug("[%s:%s] SET_STREAM_CONFIG: buffsz=%d, buffcnt=%d\n", - __MM_FILE__, __func__, evrc->str_cfg.buffer_size, - evrc->str_cfg.buffer_count); - - if (evrc->str_cfg.buffer_size < 23) { - pr_err("[%s:%s] Buffer size too small\n", __MM_FILE__, - __func__); - rc = -EINVAL; - break; - } - - if (evrc->str_cfg.buffer_count != 2) - pr_info("[%s:%s] Buffer count set to 2\n", __MM_FILE__, - __func__); - break; - case AUDIO_SET_EVRC_ENC_CONFIG: - if (copy_from_user(&evrc->cfg, (void *) arg, - sizeof(struct msm_audio_evrc_enc_config))) - rc = -EFAULT; - pr_debug("[%s:%s] SET_EVRC_ENC_CONFIG\n", __MM_FILE__, - __func__); - - if (evrc->cfg.min_bit_rate > 4 || evrc->cfg.min_bit_rate < 1) { - pr_err("[%s:%s] invalid min bitrate\n", __MM_FILE__, - __func__); - rc = -EINVAL; - } - if (evrc->cfg.max_bit_rate > 4 || evrc->cfg.max_bit_rate < 1) { - pr_err("[%s:%s] invalid max bitrate\n", __MM_FILE__, - __func__); - rc = -EINVAL; - } - break; - case AUDIO_GET_EVRC_ENC_CONFIG: - if (copy_to_user((void *) arg, &evrc->cfg, - sizeof(struct msm_audio_evrc_enc_config))) - rc = -EFAULT; - pr_debug("[%s:%s] GET_EVRC_ENC_CONFIG\n", __MM_FILE__, - __func__); - break; - - default: - rc = -EINVAL; - } - - mutex_unlock(&evrc->lock); - pr_debug("[%s:%s] rc = %d\n", __MM_FILE__, __func__, rc); - return rc; -} - -static int q6_evrc_in_open(struct inode *inode, struct file *file) -{ - struct evrc *evrc; - struct evrc_fc *fc; - int i; - - pr_info("[%s:%s] open\n", __MM_FILE__, __func__); - evrc = kmalloc(sizeof(struct evrc), GFP_KERNEL); - if (evrc == NULL) { - pr_err("[%s:%s] Could not allocate memory for evrc driver\n", - __MM_FILE__, __func__); - return -ENOMEM; - } - - mutex_init(&evrc->lock); - file->private_data = evrc; - evrc->audio_client = NULL; - evrc->str_cfg.buffer_size = 23; - evrc->str_cfg.buffer_count = 2; - evrc->cfg.cdma_rate = CDMA_RATE_FULL; - evrc->cfg.min_bit_rate = 1; - evrc->cfg.max_bit_rate = 4; - evrc->voicerec_mode.rec_mode = AUDIO_FLAG_READ; - - evrc->evrc_fc = kmalloc(sizeof(struct evrc_fc), GFP_KERNEL); - if (evrc->evrc_fc == NULL) { - pr_err("[%s:%s] Could not allocate memory for evrc_fc\n", - __MM_FILE__, __func__); - kfree(evrc); - return -ENOMEM; - } - fc = evrc->evrc_fc; - fc->task = NULL; - fc->buff_index = 0; - for (i = 0; i < EVRC_FC_BUFF_CNT; ++i) { - fc->fc_buff[i].data = NULL; - fc->fc_buff[i].size = 0; - fc->fc_buff[i].actual_size = 0; - } - /*initialize wait queue head*/ - init_waitqueue_head(&fc->fc_wq); - return 0; -} - -static ssize_t q6_evrc_in_read(struct file *file, char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_client *ac; - const char __user *start = buf; - struct evrc *evrc = file->private_data; - struct evrc_fc *fc; - int xfer = 0; - int res = 0; - - pr_debug("[%s:%s] count = %d\n", __MM_FILE__, __func__, count); - mutex_lock(&evrc->lock); - ac = evrc->audio_client; - if (!ac) { - res = -ENODEV; - goto fail; - } - fc = evrc->evrc_fc; - while (count > xfer) { - /*wait for buffer to full*/ - if (fc->fc_buff[fc->buff_index].empty != 0) { - res = wait_event_interruptible_timeout(fc->fc_wq, - (fc->fc_buff[fc->buff_index].empty == 0), - msecs_to_jiffies(EVRC_READ_TIMEOUT)); - - pr_debug("[%s:%s] buff_index = %d\n", __MM_FILE__, - __func__, fc->buff_index); - if (res == 0) { - pr_err("[%s:%s] Timeout!\n", __MM_FILE__, - __func__); - res = -ETIMEDOUT; - goto fail; - } else if (res < 0) { - pr_err("[%s:%s] Returning on Interrupt\n", - __MM_FILE__, __func__); - goto fail; - } - } - /*lock the buffer*/ - mutex_lock(&(fc->fc_buff[fc->buff_index].lock)); - xfer = fc->fc_buff[fc->buff_index].actual_size; - - if (xfer > count) { - mutex_unlock(&(fc->fc_buff[fc->buff_index].lock)); - pr_err("[%s:%s] read failed! byte count too small\n", - __MM_FILE__, __func__); - res = -EINVAL; - goto fail; - } - - if (copy_to_user(buf, fc->fc_buff[fc->buff_index].data, xfer)) { - mutex_unlock(&(fc->fc_buff[fc->buff_index].lock)); - pr_err("[%s:%s] copy_to_user failed at index %d\n", - __MM_FILE__, __func__, fc->buff_index); - res = -EFAULT; - goto fail; - } - buf += xfer; - count -= xfer; - - fc->fc_buff[fc->buff_index].empty = 1; - fc->fc_buff[fc->buff_index].actual_size = 0; - - mutex_unlock(&(fc->fc_buff[fc->buff_index].lock)); - ++(fc->buff_index); - if (fc->buff_index >= EVRC_FC_BUFF_CNT) - fc->buff_index = 0; - } - res = buf - start; - -fail: - mutex_unlock(&evrc->lock); - - return res; -} - -static int q6_evrc_in_release(struct inode *inode, struct file *file) -{ - int rc = 0; - struct evrc *evrc = file->private_data; - int i = 0; - struct evrc_fc *fc; - - mutex_lock(&evrc->lock); - fc = evrc->evrc_fc; - kthread_stop(fc->task); - fc->task = NULL; - /*free flow control buffers*/ - for (i = 0; i < EVRC_FC_BUFF_CNT; ++i) { - kfree(fc->fc_buff[i].data); - fc->fc_buff[i].data = NULL; - } - kfree(fc); - if (evrc->audio_client) - rc = q6audio_close(evrc->audio_client); - mutex_unlock(&evrc->lock); - kfree(evrc); - pr_info("[%s:%s] release\n", __MM_FILE__, __func__); - return rc; -} - -static const struct file_operations q6_evrc_in_fops = { - .owner = THIS_MODULE, - .open = q6_evrc_in_open, - .read = q6_evrc_in_read, - .release = q6_evrc_in_release, - .unlocked_ioctl = q6_evrc_in_ioctl, -}; - -struct miscdevice q6_evrc_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_evrc_in", - .fops = &q6_evrc_in_fops, -}; - -static int __init q6_evrc_in_init(void) -{ - return misc_register(&q6_evrc_in_misc); -} - -device_initcall(q6_evrc_in_init); diff --git a/arch/arm/mach-msm/qdsp6/mp3.c b/arch/arm/mach-msm/qdsp6/mp3.c deleted file mode 100644 index 16f6204febb7cf9d4c0c074b5a2c0d26547aca62..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/mp3.c +++ /dev/null @@ -1,249 +0,0 @@ -/* arch/arm/mach-msm/qdsp6/mp3.c - * - * Copyright (C) 2009 Google, Inc. - * Copyright (C) 2009 HTC Corporation - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#define BUFSZ (8192) -#define DMASZ (BUFSZ * 2) - -struct mp3 { - struct mutex lock; - struct audio_client *ac; - uint32_t sample_rate; - uint32_t channel_count; -}; - -static long mp3_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct mp3 *mp3 = file->private_data; - int rc = 0; - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - memset(&stats, 0, sizeof(stats)); - if (copy_to_user((void*) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - mutex_lock(&mp3->lock); - switch (cmd) { - case AUDIO_SET_VOLUME: { - int vol; - pr_debug("[%s:%s] SET_VOLUME = %d\n", __MM_FILE__, - __func__, vol); - if (copy_from_user(&vol, (void*) arg, sizeof(vol))) { - rc = -EFAULT; - break; - } - rc = q6audio_set_stream_volume(mp3->ac, vol); - break; - } - case AUDIO_START: { - uint32_t acdb_id; - pr_debug("[%s:%s] AUDIO_START\n", __MM_FILE__, __func__); - if (arg == 0) { - acdb_id = 0; - } else if (copy_from_user(&acdb_id, (void*) arg, sizeof(acdb_id))) { - pr_info("[%s:%s] copy acdb_id from user failed\n", - __MM_FILE__, __func__); - rc = -EFAULT; - break; - } - if (mp3->ac) { - pr_err("[%s:%s] active session already existing\n", - __MM_FILE__, __func__); - rc = -EBUSY; - } else { - mp3->ac = q6audio_open_mp3(BUFSZ, - mp3->sample_rate, mp3->channel_count, acdb_id); - if (!mp3->ac) { - pr_err("[%s:%s] mp3 open session failed\n", - __MM_FILE__, __func__); - rc = -ENOMEM; - } - } - break; - } - case AUDIO_STOP: - pr_debug("[%s:%s] AUDIO_STOP\n", __MM_FILE__, __func__); - break; - case AUDIO_FLUSH: - break; - case AUDIO_SET_CONFIG: { - struct msm_audio_config config; - if (mp3->ac) { - rc = -EBUSY; - pr_err("[%s:%s] active session already existing\n", - __MM_FILE__, __func__); - break; - } - if (copy_from_user(&config, (void*) arg, sizeof(config))) { - rc = -EFAULT; - break; - } - pr_debug("[%s:%s] SET_CONFIG: buffsize = %d, samplerate = %d, \ - channelcount = %d\n", __MM_FILE__, __func__, - config.buffer_size, config.sample_rate, - config.channel_count); - if (config.channel_count < 1 || config.channel_count > 2) { - rc = -EINVAL; - pr_err("[%s:%s] invalid channelcount\n", __MM_FILE__, - __func__); - break; - } - mp3->sample_rate = config.sample_rate; - mp3->channel_count = config.channel_count; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config config; - config.buffer_size = BUFSZ; - config.buffer_count = 2; - config.sample_rate = mp3->sample_rate; - config.channel_count = mp3->channel_count; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void*) arg, &config, sizeof(config))) { - rc = -EFAULT; - } - pr_debug("[%s:%s] GET_CONFIG: buffsize = %d, samplerate = %d, \ - channelcount = %d\n", __MM_FILE__, __func__, - config.buffer_size, config.sample_rate, - config.channel_count); - break; - } - default: - rc = -EINVAL; - } - mutex_unlock(&mp3->lock); - pr_debug("[%s:%s] rc = %d\n", __MM_FILE__, __func__, rc); - return rc; -} - -static int mp3_open(struct inode *inode, struct file *file) -{ - int rc = 0; - - struct mp3 *mp3; - pr_info("[%s:%s] open\n", __MM_FILE__, __func__); - mp3 = kzalloc(sizeof(struct mp3), GFP_KERNEL); - - if (!mp3) - return -ENOMEM; - - mutex_init(&mp3->lock); - mp3->channel_count = 2; - mp3->sample_rate = 44100; - - file->private_data = mp3; - return rc; -} - -static ssize_t mp3_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct mp3 *mp3 = file->private_data; - struct audio_client *ac; - struct audio_buffer *ab; - const char __user *start = buf; - int xfer; - - pr_debug("[%s:%s] count = %d\n", __MM_FILE__, __func__, count); - if (!mp3->ac) - mp3_ioctl(file, AUDIO_START, 0); - - ac = mp3->ac; - if (!ac) - return -ENODEV; - - while (count > 0) { - ab = ac->buf + ac->cpu_buf; - - if (ab->used) - wait_event(ac->wait, (ab->used == 0)); - - pr_debug("[%s:%s] ab->data = %p, ac->cpu_buf = %d\n", - __MM_FILE__, __func__, ab->data, ac->cpu_buf); - xfer = count; - if (xfer > ab->size) - xfer = ab->size; - - if (copy_from_user(ab->data, buf, xfer)) - return -EFAULT; - - buf += xfer; - count -= xfer; - - ab->used = xfer; - q6audio_write(ac, ab); - ac->cpu_buf ^= 1; - } - - return buf - start; -} - -static int mp3_fsync(struct file *f, int datasync) -{ - struct mp3 *mp3 = f->private_data; - if (mp3->ac) - return q6audio_async(mp3->ac); - return -ENODEV; -} - -static int mp3_release(struct inode *inode, struct file *file) -{ - struct mp3 *mp3 = file->private_data; - if (mp3->ac) - q6audio_mp3_close(mp3->ac); - kfree(mp3); - pr_info("[%s:%s] release\n", __MM_FILE__, __func__); - return 0; -} - -static struct file_operations mp3_fops = { - .owner = THIS_MODULE, - .open = mp3_open, - .write = mp3_write, - .fsync = mp3_fsync, - .release = mp3_release, - .unlocked_ioctl = mp3_ioctl, -}; - -struct miscdevice mp3_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_mp3", - .fops = &mp3_fops, -}; - -static int __init mp3_init(void) { - return misc_register(&mp3_misc); -} - -device_initcall(mp3_init); diff --git a/arch/arm/mach-msm/qdsp6/msm_q6vdec.c b/arch/arm/mach-msm/qdsp6/msm_q6vdec.c deleted file mode 100644 index 24d2117a8f9ce8d708bda8f6e944531babf668aa..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/msm_q6vdec.c +++ /dev/null @@ -1,1510 +0,0 @@ -/* Copyright (c) 2008-2010, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -/* -#define DEBUG_TRACE_VDEC -#define DEBUG -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "dal.h" - -#define DALDEVICEID_VDEC_DEVICE 0x02000026 -#define DALDEVICEID_VDEC_PORTNAME "DAL_AQ_VID" - -#define VDEC_INTERFACE_VERSION 0x00020000 - -#define MAJOR_MASK 0xFFFF0000 -#define MINOR_MASK 0x0000FFFF - -#define VDEC_GET_MAJOR_VERSION(version) (((version)&MAJOR_MASK)>>16) - -#define VDEC_GET_MINOR_VERSION(version) ((version)&MINOR_MASK) - -#ifdef DEBUG_TRACE_VDEC -#define TRACE(fmt,x...) \ - do { pr_debug("%s:%d " fmt, __func__, __LINE__, ##x); } while (0) -#else -#define TRACE(fmt,x...) do { } while (0) -#endif - -#define YAMATO_COLOR_FORMAT 0x02 -#define MAX_Q6_LOAD ((720*1280)/256) /* 720p */ -#define MAX_Q6_LOAD_YAMATO ((736*1280)/256) -#define MAX_Q6_LOAD_VP6 ((800*480)/256) - -#define VDEC_MAX_PORTS 4 - -/* - *why magic number 300? - - *the Maximum size of the DAL payload is 512 bytes according to DAL protocol - *Initialize call to QDSP6 from scorpion need to send sequence header as part of - *the DAL payload. DAL payload to initialize contains the following - - *1) configuration data- 52 bytes 2) length field of config data - 4 bytes - *3) sequence header data ( that is from the bit stream) - *4) length field for sequence header - 4 bytes - *5) length field for output structure - 4 bytes - - *that left with 512 - 68 = 448 bytes. It is unusual that we get a sequence - *header with such a big length unless the bit stream has multiple sequence - *headers.We estimated 300 is good enough which gives enough room for rest - *of the payload and even reserves some space for future payload. - */ - -#define VDEC_MAX_SEQ_HEADER_SIZE 300 - -char *Q6Portnames[] = { -"DAL_AQ_VID_0", -"DAL_AQ_VID_1", -"DAL_AQ_VID_2", -"DAL_AQ_VID_3" -}; - - - -#define DALDEVICEID_VDEC_DEVICE_0 0x020000D2 -#define DALDEVICEID_VDEC_DEVICE_1 0x020000D3 -#define DALDEVICEID_VDEC_DEVICE_2 0x020000D4 -#define DALDEVICEID_VDEC_DEVICE_3 0x020000D5 -#define DALDEVICEID_VDEC_DEVICE_4 0x020000D6 -#define DALDEVICEID_VDEC_DEVICE_5 0x020000D7 -#define DALDEVICEID_VDEC_DEVICE_6 0x020000D8 -#define DALDEVICEID_VDEC_DEVICE_7 0x020000D9 -#define DALDEVICEID_VDEC_DEVICE_8 0x020000DA -#define DALDEVICEID_VDEC_DEVICE_9 0x020000DB -#define DALDEVICEID_VDEC_DEVICE_10 0x020000DC -#define DALDEVICEID_VDEC_DEVICE_11 0x020000DD -#define DALDEVICEID_VDEC_DEVICE_12 0x020000DE -#define DALDEVICEID_VDEC_DEVICE_13 0x020000DF -#define DALDEVICEID_VDEC_DEVICE_14 0x020000E0 -#define DALDEVICEID_VDEC_DEVICE_15 0x020000E1 -#define DALDEVICEID_VDEC_DEVICE_16 0x020000E2 -#define DALDEVICEID_VDEC_DEVICE_17 0x020000E3 -#define DALDEVICEID_VDEC_DEVICE_18 0x020000E4 -#define DALDEVICEID_VDEC_DEVICE_19 0x020000E5 -#define DALDEVICEID_VDEC_DEVICE_20 0x020000E6 -#define DALDEVICEID_VDEC_DEVICE_21 0x020000E7 -#define DALDEVICEID_VDEC_DEVICE_22 0x020000E8 -#define DALDEVICEID_VDEC_DEVICE_23 0x020000E9 -#define DALDEVICEID_VDEC_DEVICE_24 0x020000EA -#define DALDEVICEID_VDEC_DEVICE_25 0x020000EB -#define DALDEVICEID_VDEC_DEVICE_26 0x020000EC -#define DALDEVICEID_VDEC_DEVICE_27 0x020000ED -#define DALDEVICEID_VDEC_DEVICE_28 0x020000EE -#define DALDEVICEID_VDEC_DEVICE_29 0x020000EF -#define DALDEVICEID_VDEC_DEVICE_30 0x020000F0 -#define DALDEVICEID_VDEC_DEVICE_31 0x020000F1 - -#define DALVDEC_MAX_DEVICE_IDS 32 - - -static int numOfPorts; - - -static char loadOnPorts[VDEC_MAX_PORTS]; - -static char deviceIdRegistry[DALVDEC_MAX_DEVICE_IDS]; - - -#define VDEC_DEVID_FREE 0 -#define VDEC_DEVID_OCCUPIED 1 - -#define MAX_SUPPORTED_INSTANCES 6 - -#define MAKEFOURCC(ch0, ch1, ch2, ch3) ((unsigned int)(unsigned char)(ch0) | \ - ((unsigned int)(unsigned char)(ch1) << 8) | \ - ((unsigned int)(unsigned char)(ch2) << 16) | \ - ((unsigned int)(unsigned char)(ch3) << 24)) - -#define FOURCC_MPEG4 MAKEFOURCC('m', 'p', '4', 'v') -#define FOURCC_H263 MAKEFOURCC('h', '2', '6', '3') -#define FOURCC_H264 MAKEFOURCC('h', '2', '6', '4') -#define FOURCC_VC1 MAKEFOURCC('w', 'm', 'v', '3') -#define FOURCC_DIVX MAKEFOURCC('D', 'I', 'V', 'X') -#define FOURCC_SPARK MAKEFOURCC('F', 'L', 'V', '1') -#define FOURCC_VP6 MAKEFOURCC('V', 'P', '6', '0') - -/* static struct vdec_data *multiInstances[MAX_SUPPORTED_INSTANCES];*/ - -static int totalPlaybackQ6load; -static int totalTnailQ6load; - -#define FLAG_THUMBNAIL_MODE 0x8 -#define MAX_TNAILS 3 - -#define TRUE 1 -#define FALSE 0 - -enum { - VDEC_DALRPC_INITIALIZE = DAL_OP_FIRST_DEVICE_API, - VDEC_DALRPC_SETBUFFERS, - VDEC_DALRPC_FREEBUFFERS, - VDEC_DALRPC_QUEUE, - VDEC_DALRPC_SIGEOFSTREAM, - VDEC_DALRPC_FLUSH, - VDEC_DALRPC_REUSEFRAMEBUFFER, - VDEC_DALRPC_GETDECATTRIBUTES, - VDEC_DALRPC_SUSPEND, - VDEC_DALRPC_RESUME, - VDEC_DALRPC_INITIALIZE_00, - VDEC_DALRPC_GETINTERNALBUFFERREQ, - VDEC_DALRPC_SETBUFFERS_00, - VDEC_DALRPC_FREEBUFFERS_00, - VDEC_DALRPC_GETPROPERTY, - VDEC_DALRPC_SETPROPERTY, - VDEC_DALRPC_GETDECATTRIBUTES_00, - VDEC_DALRPC_PERFORMANCE_CHANGE_REQUEST -}; - -enum { - VDEC_ASYNCMSG_DECODE_DONE = 0xdec0de00, - VDEC_ASYNCMSG_REUSE_FRAME, -}; - -struct vdec_init_cfg { - u32 decode_done_evt; - u32 reuse_frame_evt; - struct vdec_config cfg; -}; - -struct vdec_buffer_status { - u32 data; - u32 status; -}; - -#define VDEC_MSG_MAX 128 - -struct vdec_msg_list { - struct list_head list; - struct vdec_msg vdec_msg; -}; - -struct vdec_mem_info { - u32 buf_type; - u32 id; - unsigned long phys_addr; - unsigned long len; - struct file *file; -}; - -struct vdec_mem_list { - struct list_head list; - struct vdec_mem_info mem; -}; - -struct videoStreamDetails{ - int height; - int width; - unsigned int fourcc; - int Q6usage; - bool isThisTnail; - bool isTnailGranted; -}; - -struct vdec_data { - struct dal_client *vdec_handle; - unsigned int Q6deviceId; - struct videoStreamDetails streamDetails; - struct list_head vdec_msg_list_head; - struct list_head vdec_msg_list_free; - wait_queue_head_t vdec_msg_evt; - spinlock_t vdec_list_lock; - struct list_head vdec_mem_list_head; - spinlock_t vdec_mem_list_lock; - int mem_initialized; - int running; - int close_decode; -}; - -static struct class *driver_class; -static dev_t vdec_device_no; -static struct cdev vdec_cdev; -static int ref_cnt; -static DEFINE_MUTEX(vdec_ref_lock); - -static DEFINE_MUTEX(idlecount_lock); - -static DEFINE_MUTEX(vdec_rm_lock); - -static int idlecount; -static struct wake_lock wakelock; -static struct pm_qos_request pm_qos_req; - -static void prevent_sleep(void) -{ - mutex_lock(&idlecount_lock); - if (++idlecount == 1) { - pm_qos_update_request(&pm_qos_req, - msm_cpuidle_get_deep_idle_latency()); - wake_lock(&wakelock); - } - mutex_unlock(&idlecount_lock); -} - -static void allow_sleep(void) -{ - mutex_lock(&idlecount_lock); - if (--idlecount == 0) { - wake_unlock(&wakelock); - pm_qos_update_request(&pm_qos_req, PM_QOS_DEFAULT_VALUE); - } - mutex_unlock(&idlecount_lock); -} - -static inline int vdec_check_version(u32 client, u32 server) -{ - int ret = -EINVAL; - if ((VDEC_GET_MAJOR_VERSION(client) == VDEC_GET_MAJOR_VERSION(server)) - && (VDEC_GET_MINOR_VERSION(client) <= - VDEC_GET_MINOR_VERSION(server))) - ret = 0; - return ret; -} - -static int vdec_get_msg(struct vdec_data *vd, void *msg) -{ - struct vdec_msg_list *l; - unsigned long flags; - int ret = 0; - - if (!vd->running) - return -EPERM; - - spin_lock_irqsave(&vd->vdec_list_lock, flags); - list_for_each_entry_reverse(l, &vd->vdec_msg_list_head, list) { - if (copy_to_user(msg, &l->vdec_msg, sizeof(struct vdec_msg))) - pr_err("vdec_get_msg failed to copy_to_user!\n"); - if (l->vdec_msg.id == VDEC_MSG_REUSEINPUTBUFFER) - TRACE("reuse_input_buffer %d\n", l->vdec_msg.buf_id); - else if (l->vdec_msg.id == VDEC_MSG_FRAMEDONE) - TRACE("frame_done (stat=%d)\n", - l->vdec_msg.vfr_info.status); - else - TRACE("unknown msg (msgid=%d)\n", l->vdec_msg.id); - list_del(&l->list); - list_add(&l->list, &vd->vdec_msg_list_free); - ret = 1; - break; - } - spin_unlock_irqrestore(&vd->vdec_list_lock, flags); - - if (vd->close_decode) - ret = 1; - - return ret; -} - -static void vdec_put_msg(struct vdec_data *vd, struct vdec_msg *msg) -{ - struct vdec_msg_list *l; - unsigned long flags; - int found = 0; - - spin_lock_irqsave(&vd->vdec_list_lock, flags); - list_for_each_entry(l, &vd->vdec_msg_list_free, list) { - memcpy(&l->vdec_msg, msg, sizeof(struct vdec_msg)); - list_del(&l->list); - list_add(&l->list, &vd->vdec_msg_list_head); - found = 1; - break; - } - spin_unlock_irqrestore(&vd->vdec_list_lock, flags); - - if (found) - wake_up(&vd->vdec_msg_evt); - else - pr_err("vdec_put_msg can't find free list!\n"); -} - -static struct vdec_mem_list *vdec_get_mem_from_list(struct vdec_data *vd, - u32 pmem_id, u32 buf_type) -{ - struct vdec_mem_list *l; - unsigned long flags; - int found = 0; - - spin_lock_irqsave(&vd->vdec_mem_list_lock, flags); - list_for_each_entry(l, &vd->vdec_mem_list_head, list) { - if (l->mem.buf_type == buf_type && l->mem.id == pmem_id) { - found = 1; - break; - } - } - spin_unlock_irqrestore(&vd->vdec_mem_list_lock, flags); - - if (found) - return l; - else - return NULL; - -} -static int vdec_setproperty(struct vdec_data *vd, void *argp) -{ - struct vdec_property_info property; - int res; - - if (copy_from_user(&property, argp, sizeof(struct vdec_property_info))) - return -1; - - res = dal_call_f6(vd->vdec_handle, VDEC_DALRPC_SETPROPERTY, - property.id, &(property.property), sizeof(union vdec_property)); - if (res) - TRACE("Set Property failed"); - else - TRACE("Set Property succeeded"); - return res; -} -static int vdec_getproperty(struct vdec_data *vd, void *argp) -{ - int res; - union vdec_property property = {0}; - - res = dal_call_f11(vd->vdec_handle, VDEC_DALRPC_GETPROPERTY, - ((struct vdec_property_info *)argp)->id, &property, - sizeof(union vdec_property)); - - if (res) - TRACE("get Property failed"); - else - TRACE("get Property succeeded"); - - res = copy_to_user( - (&((struct vdec_property_info *)argp)->property), - &property, sizeof(property)); - - return res; -} -static int vdec_performance_change_request(struct vdec_data *vd, void* argp) -{ - u32 request_type; - int ret; - - ret = copy_from_user(&request_type, argp, sizeof(request_type)); - if (ret) { - pr_err("%s: copy_from_user failed\n", __func__); - return ret; - } - ret = dal_call_f0(vd->vdec_handle, - VDEC_DALRPC_PERFORMANCE_CHANGE_REQUEST, - request_type); - if (ret) { - pr_err("%s: remote function failed (%d)\n", __func__, ret); - return ret; - } - return ret; -} - -#ifdef TRACE_PORTS -static void printportsanddeviceids(void) -{ - int i; - - pr_err("\n\n%s:loadOnPorts", __func__); - for (i = 0; i < numOfPorts; i++) - pr_err("\t%d", loadOnPorts[i]); - - pr_err("\n\n"); - - pr_err("\n\n%s:Devids", __func__); - for (i = 0; i < DALVDEC_MAX_DEVICE_IDS; i++) - pr_err("Devid[%d]:%d\n", i, deviceIdRegistry[i]); - - - pr_err("\n\n"); -} -#endif /*TRACE_PORTS*/ - - -/* - * - * This method is used to get the number of ports supported on the Q6 - * - */ -static int vdec_get_numberofq6ports(void) -{ - struct dal_client *vdec_handle = NULL; - int retval = 0; - union vdec_property property = {0}; - - vdec_handle = dal_attach(DALDEVICEID_VDEC_DEVICE, - DALDEVICEID_VDEC_PORTNAME, 1, NULL, NULL); - if (!vdec_handle) { - pr_err("%s: failed to attach\n", __func__); - return 1;/* default setting */ - } - - retval = dal_call_f6(vdec_handle, VDEC_DALRPC_GETPROPERTY, - VDEC_NUM_DAL_PORTS, (void *)&property, sizeof(union vdec_property)); - if (retval) { - pr_err("%s: Q6get prperty failed\n", __func__); - return 1;/* default setting */ - } - - dal_detach(vdec_handle); - return property.num_dal_ports ; -} - - -/** - * This method is used to get the find the least loaded port and a corresponding - * free device id in that port. - * - * Prerequisite: vdec_open should have been called. - * - * @param[in] deviceid - * device id will be populated here. - * - * @param[in] portname - * portname will be populated here. - */ -static void vdec_get_next_portanddevid(int *deviceid, char **portname) -{ - - int i = 0; - int leastLoad = 0; - int leastLoadedIndex = 0; - - if (0 == numOfPorts) { - numOfPorts = vdec_get_numberofq6ports(); - pr_err("%s: Q6get numOfPorts %d\n", __func__, numOfPorts); - numOfPorts = 4; - /*fix: me currently hard coded to 4 as - *the Q6 getproperty is failing - */ - } - - if ((NULL == deviceid) || (NULL == portname)) - return; - else - *deviceid = 0; /* init value */ - - if (numOfPorts > 1) { - /* multi ports mode*/ - - /* find the least loaded port*/ - for (i = 1, leastLoad = loadOnPorts[0], leastLoadedIndex = 0; - i < numOfPorts; i++) { - if (leastLoad > loadOnPorts[i]) { - leastLoadedIndex = i; - leastLoad = loadOnPorts[i]; - } - } - - /* register the load */ - loadOnPorts[leastLoadedIndex]++; - *portname = Q6Portnames[leastLoadedIndex]; - - /* find a free device id corresponding to the port*/ - for (i = leastLoadedIndex; i < DALVDEC_MAX_DEVICE_IDS; - i += numOfPorts) { - if (VDEC_DEVID_FREE == deviceIdRegistry[i]) { - deviceIdRegistry[i] = VDEC_DEVID_OCCUPIED; - *deviceid = DALDEVICEID_VDEC_DEVICE_0 + i; - break; - } - } - -#ifdef TRACE_PORTS - printportsanddeviceids(); -#endif /*TRACE_PORTS*/ - } else if (1 == numOfPorts) { - /* single port mode */ - *deviceid = DALDEVICEID_VDEC_DEVICE; - *portname = DALDEVICEID_VDEC_PORTNAME; - } else if (numOfPorts <= 0) { - pr_err("%s: FATAL error numOfPorts cannot be \ - less than or equal to zero\n", __func__); - } - - -} - - -/** - * This method frees up the used dev id and decrements the port load. - * - */ - -static void vdec_freeup_portanddevid(int deviceid) -{ - - if (numOfPorts > 1) { - /* multi ports mode*/ - if (VDEC_DEVID_FREE == - deviceIdRegistry[deviceid - DALDEVICEID_VDEC_DEVICE_0]) - pr_err("device id cannot be already free\n"); - deviceIdRegistry[deviceid - DALDEVICEID_VDEC_DEVICE_0] = - VDEC_DEVID_FREE; - - loadOnPorts[(deviceid - DALDEVICEID_VDEC_DEVICE_0) - % numOfPorts]--; - - if (loadOnPorts[(deviceid - DALDEVICEID_VDEC_DEVICE_0) - % numOfPorts] < 0) - pr_err("Warning:load cannot be negative\n"); - - pr_err("dettaching on deviceid %x portname %s\n", deviceid, - Q6Portnames[(deviceid - DALDEVICEID_VDEC_DEVICE_0) - % numOfPorts]); - -#ifdef TRACE_PORTS - printportsanddeviceids(); -#endif /*TRACE_PORTS*/ - } else { - /*single port mode, nothing to be done here*/ - } - -} - - -/** - * This method validates whether a new instance can be houred or not. - * - */ -static int vdec_rm_checkWithRm(struct vdec_data *vdecInstance, - unsigned int color_format) -{ - - unsigned int maxQ6load = 0;/* in the units of macro blocks per second */ - unsigned int currentq6load = 0; - struct videoStreamDetails *streamDetails = &vdecInstance->streamDetails; - - - - if (streamDetails->isThisTnail) { - if (totalTnailQ6load < MAX_TNAILS) { - - totalTnailQ6load++; - streamDetails->isTnailGranted = TRUE; - pr_info("%s: thumbnail granted %d\n", __func__, - totalTnailQ6load); - return 0; - - } else { - - pr_err("%s: thumbnails load max this instance cannot \ - be supported\n", __func__); - streamDetails->isTnailGranted = FALSE; - return -ENOSPC; - - } - } - - /* calculate the Q6 percentage instance would need */ - if ((streamDetails->fourcc == FOURCC_MPEG4) || - (streamDetails->fourcc == FOURCC_H264) || - (streamDetails->fourcc == FOURCC_DIVX) || - (streamDetails->fourcc == FOURCC_VC1) || - (streamDetails->fourcc == FOURCC_SPARK) || - (streamDetails->fourcc == FOURCC_H263) - ){ - - /* is yamato color format, - Rounds the H & W --> mutiple of 32 */ - if (color_format == YAMATO_COLOR_FORMAT) - maxQ6load = MAX_Q6_LOAD_YAMATO; - else - maxQ6load = MAX_Q6_LOAD; /* 720p */ - - } else if (streamDetails->fourcc == FOURCC_VP6) { - - maxQ6load = MAX_Q6_LOAD_VP6; /* FWVGA */ - - } else { - - pr_err("%s: unknown fourcc %d maxQ6load %u\n", __func__, - streamDetails->fourcc, maxQ6load); - return -EINVAL; - - } - - currentq6load = ((streamDetails->height)*(streamDetails->width) / 256); - currentq6load = ((currentq6load * 100)/maxQ6load); - if ((currentq6load+totalPlaybackQ6load) > 100) { - /* reject this instance */ - pr_err("%s: too much Q6load [cur+tot] = [%d + %d] = %d", - __func__, currentq6load, totalPlaybackQ6load, - (currentq6load+totalPlaybackQ6load)); - pr_err("rejecting the instance,[WxH] = [%d x %d],color_fmt=0x%x\n", - streamDetails->width, streamDetails->height, color_format); - pr_err("VDEC_fmt=%s\n", (char *)(&streamDetails->fourcc)); - streamDetails->Q6usage = 0; - return -ENOSPC; - } - - totalPlaybackQ6load += currentq6load; - streamDetails->Q6usage = currentq6load; - - pr_info("%s: adding a load [%d%%] bringing total Q6load to [%d%%]\n", - __func__, currentq6load, totalPlaybackQ6load); - - return 0; -} - - -static int vdec_initialize(struct vdec_data *vd, void *argp) -{ - struct vdec_config_sps vdec_cfg_sps; - struct vdec_init_cfg vi_cfg; - struct vdec_buf_req vdec_buf_req; - struct u8 *header; - int ret = 0; - - ret = copy_from_user(&vdec_cfg_sps, - &((struct vdec_init *)argp)->sps_cfg, - sizeof(vdec_cfg_sps)); - - if (ret) { - pr_err("%s: copy_from_user failed\n", __func__); - return ret; - } - - vi_cfg.decode_done_evt = VDEC_ASYNCMSG_DECODE_DONE; - vi_cfg.reuse_frame_evt = VDEC_ASYNCMSG_REUSE_FRAME; - memcpy(&vi_cfg.cfg, &vdec_cfg_sps.cfg, sizeof(struct vdec_config)); - - /* - * restricting the max value of the seq header - */ - if (vdec_cfg_sps.seq.len > VDEC_MAX_SEQ_HEADER_SIZE) - vdec_cfg_sps.seq.len = VDEC_MAX_SEQ_HEADER_SIZE; - - header = kmalloc(vdec_cfg_sps.seq.len, GFP_KERNEL); - if (!header) { - pr_err("%s: kmalloc failed\n", __func__); - return -ENOMEM; - } - - ret = copy_from_user(header, - ((struct vdec_init *)argp)->sps_cfg.seq.header, - vdec_cfg_sps.seq.len); - - if (ret) { - pr_err("%s: copy_from_user failed\n", __func__); - kfree(header); - return ret; - } - - TRACE("vi_cfg: handle=%p fourcc=0x%x w=%d h=%d order=%d notify_en=%d " - "vc1_rb=%d h264_sd=%d h264_nls=%d pp_flag=%d fruc_en=%d\n", - vd->vdec_handle, vi_cfg.cfg.fourcc, vi_cfg.cfg.width, - vi_cfg.cfg.height, vi_cfg.cfg.order, vi_cfg.cfg.notify_enable, - vi_cfg.cfg.vc1_rowbase, vi_cfg.cfg.h264_startcode_detect, - vi_cfg.cfg.h264_nal_len_size, vi_cfg.cfg.postproc_flag, - vi_cfg.cfg.fruc_enable); - - vd->streamDetails.height = vi_cfg.cfg.height; - vd->streamDetails.width = vi_cfg.cfg.width; - vd->streamDetails.fourcc = vi_cfg.cfg.fourcc; - if (FLAG_THUMBNAIL_MODE == vi_cfg.cfg.postproc_flag) - vd->streamDetails.isThisTnail = TRUE; - else - vd->streamDetails.isThisTnail = FALSE; - - mutex_lock(&vdec_rm_lock); - ret = vdec_rm_checkWithRm(vd, vi_cfg.cfg.color_format); - mutex_unlock(&vdec_rm_lock); - if (ret) - return ret; - - ret = dal_call_f13(vd->vdec_handle, VDEC_DALRPC_INITIALIZE, - &vi_cfg, sizeof(vi_cfg), - header, vdec_cfg_sps.seq.len, - &vdec_buf_req, sizeof(vdec_buf_req)); - - kfree(header); - - if (ret) - pr_err("%s: remote function failed (%d)\n", __func__, ret); - else - ret = copy_to_user(((struct vdec_init *)argp)->buf_req, - &vdec_buf_req, sizeof(vdec_buf_req)); - - vd->close_decode = 0; - return ret; -} - -static void vdec_rm_freeupResources(struct vdec_data *vdecInstance) -{ - struct videoStreamDetails *streamDetails = &vdecInstance->streamDetails; - - - - if ((streamDetails->isThisTnail) && - (streamDetails->isTnailGranted)) { - - totalTnailQ6load--; - pr_info("%s: Thumbnail released %d\n", __func__, - totalTnailQ6load); - - } else if (streamDetails->Q6usage > 0) { - - totalPlaybackQ6load -= streamDetails->Q6usage; - if (totalPlaybackQ6load < 0) - pr_err("Warning:Q6load cannot be negative\n"); - - pr_info("%s:Releasing [%d%%] of Q6load from a total of [%d%%]\n" - , __func__, streamDetails->Q6usage, - (streamDetails->Q6usage+totalPlaybackQ6load)); - } - -} - -static int vdec_setbuffers(struct vdec_data *vd, void *argp) -{ - struct vdec_buffer vmem; - struct vdec_mem_list *l; - unsigned long vstart; - unsigned long flags; - struct { - uint32_t size; - struct vdec_buf_info buf; - } rpc; - uint32_t res; - - int ret = 0; - - vd->mem_initialized = 0; - - ret = copy_from_user(&vmem, argp, sizeof(vmem)); - if (ret) { - pr_err("%s: copy_from_user failed\n", __func__); - return ret; - } - - l = kzalloc(sizeof(struct vdec_mem_list), GFP_KERNEL); - if (!l) { - pr_err("%s: kzalloc failed!\n", __func__); - return -ENOMEM; - } - - l->mem.id = vmem.pmem_id; - l->mem.buf_type = vmem.buf.buf_type; - - ret = get_pmem_file(l->mem.id, &l->mem.phys_addr, &vstart, - &l->mem.len, &l->mem.file); - if (ret) { - pr_err("%s: get_pmem_fd failed\n", __func__); - goto err_get_pmem_file; - } - - TRACE("pmem_id=%d (phys=0x%08lx len=0x%lx) buftype=%d num_buf=%d " - "islast=%d src_id=%d offset=0x%08x size=0x%x\n", - vmem.pmem_id, l->mem.phys_addr, l->mem.len, - vmem.buf.buf_type, vmem.buf.num_buf, vmem.buf.islast, - vmem.buf.region.src_id, vmem.buf.region.offset, - vmem.buf.region.size); - - /* input buffers */ - if ((vmem.buf.region.offset + vmem.buf.region.size) > l->mem.len) { - pr_err("%s: invalid input buffer offset!\n", __func__); - ret = -EINVAL; - goto err_bad_offset; - - } - vmem.buf.region.offset += l->mem.phys_addr; - - rpc.size = sizeof(vmem.buf); - memcpy(&rpc.buf, &vmem.buf, sizeof(struct vdec_buf_info)); - - - ret = dal_call(vd->vdec_handle, VDEC_DALRPC_SETBUFFERS, 5, - &rpc, sizeof(rpc), &res, sizeof(res)); - - if (ret < 4) { - pr_err("%s: remote function failed (%d)\n", __func__, ret); - ret = -EIO; - goto err_dal_call; - } - - spin_lock_irqsave(&vd->vdec_mem_list_lock, flags); - list_add(&l->list, &vd->vdec_mem_list_head); - spin_unlock_irqrestore(&vd->vdec_mem_list_lock, flags); - - vd->mem_initialized = 1; - return ret; - -err_dal_call: -err_bad_offset: - put_pmem_file(l->mem.file); -err_get_pmem_file: - kfree(l); - return ret; -} - -static int vdec_queue(struct vdec_data *vd, void *argp) -{ - struct { - uint32_t size; - struct vdec_input_buf_info buf_info; - uint32_t osize; - } rpc; - struct vdec_mem_list *l; - struct { - uint32_t result; - uint32_t size; - struct vdec_queue_status status; - } rpc_res; - - u32 pmem_id; - int ret = 0; - - if (!vd->mem_initialized) { - pr_err("%s: memory is not being initialized!\n", __func__); - return -EPERM; - } - - ret = copy_from_user(&rpc.buf_info, - &((struct vdec_input_buf *)argp)->buffer, - sizeof(rpc.buf_info)); - if (ret) { - pr_err("%s: copy_from_user failed\n", __func__); - return ret; - } - - ret = copy_from_user(&pmem_id, - &((struct vdec_input_buf *)argp)->pmem_id, - sizeof(u32)); - if (ret) { - pr_err("%s: copy_from_user failed\n", __func__); - return ret; - } - - l = vdec_get_mem_from_list(vd, pmem_id, VDEC_BUFFER_TYPE_INPUT); - - if (NULL == l) { - pr_err("%s: not able to find the buffer from list\n", __func__); - return -EPERM; - } - - if ((rpc.buf_info.size + rpc.buf_info.offset) >= l->mem.len) { - pr_err("%s: invalid queue buffer offset!\n", __func__); - return -EINVAL; - } - - rpc.buf_info.offset += l->mem.phys_addr; - rpc.size = sizeof(struct vdec_input_buf_info); - rpc.osize = sizeof(struct vdec_queue_status); - - /* complete the writes to the buffer */ - wmb(); - ret = dal_call(vd->vdec_handle, VDEC_DALRPC_QUEUE, 8, - &rpc, sizeof(rpc), &rpc_res, sizeof(rpc_res)); - if (ret < 4) { - pr_err("%s: remote function failed (%d)\n", __func__, ret); - ret = -EIO; - } - return ret; -} - -static int vdec_reuse_framebuffer(struct vdec_data *vd, void *argp) -{ - u32 buf_id; - int ret = 0; - - ret = copy_from_user(&buf_id, argp, sizeof(buf_id)); - if (ret) { - pr_err("%s: copy_from_user failed\n", __func__); - return ret; - } - - ret = dal_call_f0(vd->vdec_handle, VDEC_DALRPC_REUSEFRAMEBUFFER, - buf_id); - if (ret) - pr_err("%s: remote function failed (%d)\n", __func__, ret); - - return ret; -} - -static int vdec_flush(struct vdec_data *vd, void *argp) -{ - u32 flush_type; - int ret = 0; - - if (!vd->mem_initialized) { - pr_err("%s: memory is not being initialized!\n", __func__); - return -EPERM; - } - - ret = copy_from_user(&flush_type, argp, sizeof(flush_type)); - if (ret) { - pr_err("%s: copy_from_user failed\n", __func__); - return ret; - } - - TRACE("flush_type=%d\n", flush_type); - ret = dal_call_f0(vd->vdec_handle, VDEC_DALRPC_FLUSH, flush_type); - if (ret) { - pr_err("%s: remote function failed (%d)\n", __func__, ret); - return ret; - } - - return ret; -} - -static int vdec_close(struct vdec_data *vd, void *argp) -{ - struct vdec_mem_list *l; - int ret = 0; - - pr_info("q6vdec_close()\n"); - vd->close_decode = 1; - wake_up(&vd->vdec_msg_evt); - - ret = dal_call_f0(vd->vdec_handle, DAL_OP_CLOSE, 0); - if (ret) - pr_err("%s: failed to close daldevice (%d)\n", __func__, ret); - - if (vd->mem_initialized) { - list_for_each_entry(l, &vd->vdec_mem_list_head, list) - put_pmem_file(l->mem.file); - } - - return ret; -} -static int vdec_getdecattributes(struct vdec_data *vd, void *argp) -{ - struct { - uint32_t status; - uint32_t size; - struct vdec_dec_attributes dec_attr; - } rpc; - uint32_t inp; - int ret = 0; - inp = sizeof(struct vdec_dec_attributes); - - ret = dal_call(vd->vdec_handle, VDEC_DALRPC_GETDECATTRIBUTES, 9, - &inp, sizeof(inp), &rpc, sizeof(rpc)); - if (ret < 4 || rpc.size != sizeof(struct vdec_dec_attributes)) { - pr_err("%s: remote function failed (%d)\n", __func__, ret); - ret = -EIO; - } else - ret = - copy_to_user(((struct vdec_dec_attributes *)argp), - &rpc.dec_attr, sizeof(rpc.dec_attr)); - return ret; -} - -static int vdec_freebuffers(struct vdec_data *vd, void *argp) -{ - struct vdec_buffer vmem; - struct vdec_mem_list *l; - struct { - uint32_t size; - struct vdec_buf_info buf; - } rpc; - uint32_t res; - - int ret = 0; - - if (!vd->mem_initialized) { - pr_err("%s: memory is not being initialized!\n", __func__); - return -EPERM; - } - - ret = copy_from_user(&vmem, argp, sizeof(vmem)); - if (ret) { - pr_err("%s: copy_from_user failed\n", __func__); - return ret; - } - - l = vdec_get_mem_from_list(vd, vmem.pmem_id, vmem.buf.buf_type); - - if (NULL == l) { - pr_err("%s: not able to find the buffer from list\n", __func__); - return -EPERM; - } - - /* input buffers */ - if ((vmem.buf.region.offset + vmem.buf.region.size) > l->mem.len) { - pr_err("%s: invalid input buffer offset!\n", __func__); - return -EINVAL; - - } - vmem.buf.region.offset += l->mem.phys_addr; - - rpc.size = sizeof(vmem.buf); - memcpy(&rpc.buf, &vmem.buf, sizeof(struct vdec_buf_info)); - - ret = dal_call(vd->vdec_handle, VDEC_DALRPC_FREEBUFFERS, 5, - &rpc, sizeof(rpc), &res, sizeof(res)); - if (ret < 4) { - pr_err("%s: remote function failed (%d)\n", __func__, ret); - } - - return ret; -} - -static int vdec_getversion(struct vdec_data *vd, void *argp) -{ - struct vdec_version ver_info; - int ret = 0; - - ver_info.major = VDEC_GET_MAJOR_VERSION(VDEC_INTERFACE_VERSION); - ver_info.minor = VDEC_GET_MINOR_VERSION(VDEC_INTERFACE_VERSION); - - ret = copy_to_user(((struct vdec_version *)argp), - &ver_info, sizeof(ver_info)); - - return ret; - -} - -static long vdec_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct vdec_data *vd = file->private_data; - void __user *argp = (void __user *)arg; - int ret = 0; - - if (!vd->running) - return -EPERM; - - switch (cmd) { - case VDEC_IOCTL_INITIALIZE: - ret = vdec_initialize(vd, argp); - break; - - case VDEC_IOCTL_SETBUFFERS: - ret = vdec_setbuffers(vd, argp); - break; - - case VDEC_IOCTL_QUEUE: - TRACE("VDEC_IOCTL_QUEUE (pid=%d tid=%d)\n", - current->group_leader->pid, current->pid); - ret = vdec_queue(vd, argp); - break; - - case VDEC_IOCTL_REUSEFRAMEBUFFER: - TRACE("VDEC_IOCTL_REUSEFRAMEBUFFER (pid=%d tid=%d)\n", - current->group_leader->pid, current->pid); - ret = vdec_reuse_framebuffer(vd, argp); - break; - - case VDEC_IOCTL_FLUSH: - TRACE("IOCTL flush\n"); - ret = vdec_flush(vd, argp); - break; - - case VDEC_IOCTL_EOS: - TRACE("VDEC_IOCTL_EOS (pid=%d tid=%d)\n", - current->group_leader->pid, current->pid); - ret = dal_call_f0(vd->vdec_handle, VDEC_DALRPC_SIGEOFSTREAM, 0); - if (ret) - pr_err("%s: remote function failed (%d)\n", - __func__, ret); - break; - - case VDEC_IOCTL_GETMSG: - TRACE("VDEC_IOCTL_GETMSG (pid=%d tid=%d)\n", - current->group_leader->pid, current->pid); - wait_event_interruptible(vd->vdec_msg_evt, - vdec_get_msg(vd, argp)); - - if (vd->close_decode) - ret = -EINTR; - else - /* order the reads from the buffer */ - rmb(); - break; - - case VDEC_IOCTL_CLOSE: - ret = vdec_close(vd, argp); - break; - - case VDEC_IOCTL_GETDECATTRIBUTES: - TRACE("VDEC_IOCTL_GETDECATTRIBUTES (pid=%d tid=%d)\n", - current->group_leader->pid, current->pid); - ret = vdec_getdecattributes(vd, argp); - - if (ret) - pr_err("%s: remote function failed (%d)\n", - __func__, ret); - break; - - case VDEC_IOCTL_FREEBUFFERS: - TRACE("VDEC_IOCTL_FREEBUFFERS (pid=%d tid=%d)\n", - current->group_leader->pid, current->pid); - ret = vdec_freebuffers(vd, argp); - - if (ret) - pr_err("%s: remote function failed (%d)\n", - __func__, ret); - break; - case VDEC_IOCTL_GETVERSION: - TRACE("VDEC_IOCTL_GETVERSION (pid=%d tid=%d)\n", - current->group_leader->pid, current->pid); - ret = vdec_getversion(vd, argp); - - if (ret) - pr_err("%s: remote function failed (%d)\n", - __func__, ret); - break; - case VDEC_IOCTL_GETPROPERTY: - TRACE("VDEC_IOCTL_GETPROPERTY (pid=%d tid=%d)\n", - current->group_leader->pid, current->pid); - ret = vdec_getproperty(vd, argp); - break; - case VDEC_IOCTL_SETPROPERTY: - TRACE("VDEC_IOCTL_SETPROPERTY (pid=%d tid=%d)\n", - current->group_leader->pid, current->pid); - ret = vdec_setproperty(vd, argp); - break; - case VDEC_IOCTL_PERFORMANCE_CHANGE_REQ: - ret = vdec_performance_change_request(vd, argp); - break; - default: - pr_err("%s: invalid ioctl!\n", __func__); - ret = -EINVAL; - break; - } - - TRACE("ioctl done (pid=%d tid=%d)\n", - current->group_leader->pid, current->pid); - - return ret; -} - -static void vdec_dcdone_handler(struct vdec_data *vd, void *frame, - uint32_t frame_size) -{ - struct vdec_msg msg; - struct vdec_mem_list *l; - unsigned long flags; - int found = 0; - - if (frame_size < sizeof(struct vdec_frame_info)) { - pr_warning("%s: msg size mismatch %d != %d\n", __func__, - frame_size, sizeof(struct vdec_frame_info)); - return; - } - - memcpy(&msg.vfr_info, (struct vdec_frame_info *)frame, - sizeof(struct vdec_frame_info)); - - if (msg.vfr_info.status == VDEC_FRAME_DECODE_OK) { - spin_lock_irqsave(&vd->vdec_mem_list_lock, flags); - list_for_each_entry(l, &vd->vdec_mem_list_head, list) { - if ((l->mem.buf_type == VDEC_BUFFER_TYPE_OUTPUT) && - (msg.vfr_info.offset >= l->mem.phys_addr) && - (msg.vfr_info.offset < - (l->mem.phys_addr + l->mem.len))) { - found = 1; - msg.vfr_info.offset -= l->mem.phys_addr; - msg.vfr_info.data2 = l->mem.id; - break; - } - } - spin_unlock_irqrestore(&vd->vdec_mem_list_lock, flags); - } - - if (found || (msg.vfr_info.status != VDEC_FRAME_DECODE_OK)) { - msg.id = VDEC_MSG_FRAMEDONE; - vdec_put_msg(vd, &msg); - } else { - pr_err("%s: invalid phys addr = 0x%x\n", - __func__, msg.vfr_info.offset); - } - -} - -static void vdec_reuseibuf_handler(struct vdec_data *vd, void *bufstat, - uint32_t bufstat_size) -{ - struct vdec_buffer_status *vdec_bufstat; - struct vdec_msg msg; - - /* TODO: how do we signal the client? If they are waiting on a - * message in an ioctl, they may block forever */ - if (bufstat_size != sizeof(struct vdec_buffer_status)) { - pr_warning("%s: msg size mismatch %d != %d\n", __func__, - bufstat_size, sizeof(struct vdec_buffer_status)); - return; - } - vdec_bufstat = (struct vdec_buffer_status *)bufstat; - msg.id = VDEC_MSG_REUSEINPUTBUFFER; - msg.buf_id = vdec_bufstat->data; - vdec_put_msg(vd, &msg); -} - -static void callback(void *data, int len, void *cookie) -{ - struct vdec_data *vd = (struct vdec_data *)cookie; - uint32_t *tmp = (uint32_t *) data; - - if (!vd->mem_initialized) { - pr_err("%s:memory not initialize but callback called!\n", - __func__); - return; - } - - TRACE("vdec_async: tmp=0x%08x 0x%08x 0x%08x\n", tmp[0], tmp[1], tmp[2]); - switch (tmp[0]) { - case VDEC_ASYNCMSG_DECODE_DONE: - vdec_dcdone_handler(vd, &tmp[3], tmp[2]); - break; - case VDEC_ASYNCMSG_REUSE_FRAME: - vdec_reuseibuf_handler(vd, &tmp[3], tmp[2]); - break; - default: - pr_err("%s: Unknown async message from DSP id=0x%08x sz=%u\n", - __func__, tmp[0], tmp[2]); - } -} - -static int vdec_open(struct inode *inode, struct file *file) -{ - int ret; - int i; - struct vdec_msg_list *l; - struct vdec_data *vd; - struct dal_info version_info; - char *portname = NULL; - - pr_info("q6vdec_open()\n"); - mutex_lock(&vdec_ref_lock); - if (ref_cnt >= MAX_SUPPORTED_INSTANCES) { - pr_err("%s: Max allowed instances exceeded \n", __func__); - mutex_unlock(&vdec_ref_lock); - return -EBUSY; - } - ref_cnt++; - mutex_unlock(&vdec_ref_lock); - - vd = kmalloc(sizeof(struct vdec_data), GFP_KERNEL); - if (!vd) { - pr_err("%s: kmalloc failed\n", __func__); - ret = -ENOMEM; - goto vdec_open_err_handle_vd; - } - file->private_data = vd; - - vd->mem_initialized = 0; - INIT_LIST_HEAD(&vd->vdec_msg_list_head); - INIT_LIST_HEAD(&vd->vdec_msg_list_free); - INIT_LIST_HEAD(&vd->vdec_mem_list_head); - init_waitqueue_head(&vd->vdec_msg_evt); - - spin_lock_init(&vd->vdec_list_lock); - spin_lock_init(&vd->vdec_mem_list_lock); - for (i = 0; i < VDEC_MSG_MAX; i++) { - l = kzalloc(sizeof(struct vdec_msg_list), GFP_KERNEL); - if (!l) { - pr_err("%s: kzalloc failed!\n", __func__); - ret = -ENOMEM; - goto vdec_open_err_handle_list; - } - list_add(&l->list, &vd->vdec_msg_list_free); - } - - memset(&vd->streamDetails, 0, sizeof(struct videoStreamDetails)); - - mutex_lock(&vdec_ref_lock); - vdec_get_next_portanddevid(&vd->Q6deviceId, &portname); - mutex_unlock(&vdec_ref_lock); - - if ((0 == vd->Q6deviceId) || (NULL == portname)) { - pr_err("%s: FATAL error portname %s or deviceId %d not picked properly\n", - __func__, portname, vd->Q6deviceId); - ret = -EIO; - goto vdec_open_err_handle_list; - } else { - pr_err("attaching on deviceid %x portname %s\n", - vd->Q6deviceId, portname); - vd->vdec_handle = dal_attach(vd->Q6deviceId, - portname, 1, callback, vd); - } - - if (!vd->vdec_handle) { - pr_err("%s: failed to attach\n", __func__); - ret = -EIO; - goto vdec_open_err_handle_list; - } - ret = dal_call_f9(vd->vdec_handle, DAL_OP_INFO, - &version_info, sizeof(struct dal_info)); - - if (ret) { - pr_err("%s: failed to get version \n", __func__); - goto vdec_open_err_handle_version; - } - - TRACE("q6vdec_open() interface version 0x%x\n", version_info.version); - if (vdec_check_version(VDEC_INTERFACE_VERSION, - version_info.version)) { - pr_err("%s: driver version mismatch !\n", __func__); - goto vdec_open_err_handle_version; - } - - vd->running = 1; - prevent_sleep(); - - return 0; -vdec_open_err_handle_version: - dal_detach(vd->vdec_handle); -vdec_open_err_handle_list: - { - struct vdec_msg_list *l, *n; - list_for_each_entry_safe(l, n, &vd->vdec_msg_list_free, list) { - list_del(&l->list); - kfree(l); - } - } -vdec_open_err_handle_vd: - mutex_lock(&vdec_ref_lock); - vdec_freeup_portanddevid(vd->Q6deviceId); - ref_cnt--; - mutex_unlock(&vdec_ref_lock); - kfree(vd); - return ret; -} - -static int vdec_release(struct inode *inode, struct file *file) -{ - int ret; - struct vdec_msg_list *l, *n; - struct vdec_mem_list *m, *k; - struct vdec_data *vd = file->private_data; - - vd->running = 0; - wake_up_all(&vd->vdec_msg_evt); - - if (!vd->close_decode) - vdec_close(vd, NULL); - - ret = dal_detach(vd->vdec_handle); - if (ret) - printk(KERN_INFO "%s: failed to detach (%d)\n", __func__, ret); - - list_for_each_entry_safe(l, n, &vd->vdec_msg_list_free, list) { - list_del(&l->list); - kfree(l); - } - - list_for_each_entry_safe(l, n, &vd->vdec_msg_list_head, list) { - list_del(&l->list); - kfree(l); - } - - list_for_each_entry_safe(m, k, &vd->vdec_mem_list_head, list) { - list_del(&m->list); - kfree(m); - } - mutex_lock(&vdec_ref_lock); - BUG_ON(ref_cnt <= 0); - ref_cnt--; - vdec_freeup_portanddevid(vd->Q6deviceId); - mutex_unlock(&vdec_ref_lock); - - mutex_lock(&vdec_rm_lock); - vdec_rm_freeupResources(vd); - mutex_unlock(&vdec_rm_lock); - - - kfree(vd); - allow_sleep(); - return 0; -} - -static const struct file_operations vdec_fops = { - .owner = THIS_MODULE, - .open = vdec_open, - .release = vdec_release, - .unlocked_ioctl = vdec_ioctl, -}; - -static int __init vdec_init(void) -{ - struct device *class_dev; - int rc = 0; - - pm_qos_add_request(&pm_qos_req, PM_QOS_CPU_DMA_LATENCY, - PM_QOS_DEFAULT_VALUE); - wake_lock_init(&wakelock, WAKE_LOCK_SUSPEND, "vdec_suspend"); - - rc = alloc_chrdev_region(&vdec_device_no, 0, 1, "vdec"); - if (rc < 0) { - pr_err("%s: alloc_chrdev_region failed %d\n", __func__, rc); - return rc; - } - - driver_class = class_create(THIS_MODULE, "vdec"); - if (IS_ERR(driver_class)) { - rc = -ENOMEM; - pr_err("%s: class_create failed %d\n", __func__, rc); - goto vdec_init_err_unregister_chrdev_region; - } - class_dev = device_create(driver_class, NULL, - vdec_device_no, NULL, "vdec"); - if (!class_dev) { - pr_err("%s: class_device_create failed %d\n", __func__, rc); - rc = -ENOMEM; - goto vdec_init_err_class_destroy; - } - - cdev_init(&vdec_cdev, &vdec_fops); - vdec_cdev.owner = THIS_MODULE; - rc = cdev_add(&vdec_cdev, MKDEV(MAJOR(vdec_device_no), 0), 1); - - if (rc < 0) { - pr_err("%s: cdev_add failed %d\n", __func__, rc); - goto vdec_init_err_class_device_destroy; - } - - memset(&deviceIdRegistry, 0, sizeof(deviceIdRegistry)); - memset(&loadOnPorts, 0, sizeof(loadOnPorts)); - numOfPorts = 0; - - return 0; - -vdec_init_err_class_device_destroy: - device_destroy(driver_class, vdec_device_no); -vdec_init_err_class_destroy: - class_destroy(driver_class); -vdec_init_err_unregister_chrdev_region: - unregister_chrdev_region(vdec_device_no, 1); - return rc; -} - -static void __exit vdec_exit(void) -{ - device_destroy(driver_class, vdec_device_no); - class_destroy(driver_class); - unregister_chrdev_region(vdec_device_no, 1); -} - -MODULE_DESCRIPTION("video decoder driver for QSD platform"); -MODULE_VERSION("2.00"); - -module_init(vdec_init); -module_exit(vdec_exit); diff --git a/arch/arm/mach-msm/qdsp6/msm_q6venc.c b/arch/arm/mach-msm/qdsp6/msm_q6venc.c deleted file mode 100644 index 4704ae7830a78fee7436fe57e9a658719ed032b7..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/msm_q6venc.c +++ /dev/null @@ -1,1201 +0,0 @@ -/* Copyright (c) 2008-2009, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "dal.h" - -#define DALDEVICEID_VENC_DEVICE 0x0200002D -#define DALDEVICEID_VENC_PORTNAME "DAL_AQ_VID" - -#define VENC_NAME "q6venc" -#define VENC_MSG_MAX 128 - -#define VENC_INTERFACE_VERSION 0x00020000 -#define MAJOR_MASK 0xFFFF0000 -#define MINOR_MASK 0x0000FFFF -#define VENC_GET_MAJOR_VERSION(version) ((version & MAJOR_MASK)>>16) -#define VENC_GET_MINOR_VERSION(version) (version & MINOR_MASK) - -enum { - VENC_BUFFER_TYPE_INPUT, - VENC_BUFFER_TYPE_OUTPUT, - VENC_BUFFER_TYPE_QDSP6, - VENC_BUFFER_TYPE_HDR -}; -enum { - VENC_DALRPC_GET_SYNTAX_HEADER = DAL_OP_FIRST_DEVICE_API, - VENC_DALRPC_UPDATE_INTRA_REFRESH, - VENC_DALRPC_UPDATE_FRAME_RATE, - VENC_DALRPC_UPDATE_BITRATE, - VENC_DALRPC_UPDATE_QP_RANGE, - VENC_DALRPC_UPDATE_INTRA_PERIOD, - VENC_DALRPC_REQUEST_IFRAME, - VENC_DALRPC_START, - VENC_DALRPC_STOP, - VENC_DALRPC_SUSPEND, - VENC_DALRPC_RESUME, - VENC_DALRPC_FLUSH, - VENC_DALRPC_QUEUE_INPUT, - VENC_DALRPC_QUEUE_OUTPUT -}; -struct venc_input_payload { - u32 data; -}; -struct venc_output_payload { - u32 size; - long long time_stamp; - u32 flags; - u32 data; - u32 client_data_from_input; -}; -union venc_payload { - struct venc_input_payload input_payload; - struct venc_output_payload output_payload; -}; -struct venc_msg_type { - u32 event; - u32 status; - union venc_payload payload; -}; -struct venc_input_buf { - struct venc_buf_type yuv_buf; - u32 data_size; - long long time_stamp; - u32 flags; - u32 dvs_offsetx; - u32 dvs_offsety; - u32 client_data; - u32 op_client_data; -}; -struct venc_output_buf { - struct venc_buf_type bit_stream_buf; - u32 client_data; -}; - -struct venc_msg_list { - struct list_head list; - struct venc_msg msg_data; -}; -struct venc_buf { - int fd; - u32 src; - u32 offset; - u32 size; - u32 btype; - unsigned long paddr; - struct file *file; -}; -struct venc_pmem_list { - struct list_head list; - struct venc_buf buf; -}; -struct venc_dev { - bool is_active; - bool pmem_freed; - enum venc_state_type state; - struct list_head venc_msg_list_head; - struct list_head venc_msg_list_free; - spinlock_t venc_msg_list_lock; - struct list_head venc_pmem_list_head; - spinlock_t venc_pmem_list_lock; - struct dal_client *q6_handle; - wait_queue_head_t venc_msg_evt; - struct device *class_devp; -}; - -#define DEBUG_VENC 0 -#if DEBUG_VENC -#define TRACE(fmt, x...) \ - do { pr_debug("%s:%d " fmt, __func__, __LINE__, ##x); } while (0) -#else -#define TRACE(fmt, x...) do { } while (0) -#endif - -static struct cdev cdev; -static dev_t venc_dev_num; -static struct class *venc_class; -static struct venc_dev *venc_device_p; -static int venc_ref; - -static DEFINE_MUTEX(idlecount_lock); -static int idlecount; -static struct wake_lock wakelock; -static struct pm_qos_request pm_qos_req; - -static void prevent_sleep(void) -{ - mutex_lock(&idlecount_lock); - if (++idlecount == 1) { - pm_qos_update_request(&pm_qos_req, - msm_cpuidle_get_deep_idle_latency()); - wake_lock(&wakelock); - } - mutex_unlock(&idlecount_lock); -} - -static void allow_sleep(void) -{ - mutex_lock(&idlecount_lock); - if (--idlecount == 0) { - wake_unlock(&wakelock); - pm_qos_update_request(&pm_qos_req, PM_QOS_DEFAULT_VALUE); - } - mutex_unlock(&idlecount_lock); -} - -static inline int venc_check_version(u32 client, u32 server) -{ - int ret = -EINVAL; - - if ((VENC_GET_MAJOR_VERSION(client) == VENC_GET_MAJOR_VERSION(server)) - && (VENC_GET_MINOR_VERSION(client) <= - VENC_GET_MINOR_VERSION(server))) - ret = 0; - - return ret; -} - -static int venc_get_msg(struct venc_dev *dvenc, void *msg) -{ - struct venc_msg_list *l; - unsigned long flags; - int ret = 0; - struct venc_msg qdsp_msg; - - if (!dvenc->is_active) - return -EPERM; - spin_lock_irqsave(&dvenc->venc_msg_list_lock, flags); - list_for_each_entry_reverse(l, &dvenc->venc_msg_list_head, list) { - memcpy(&qdsp_msg, &l->msg_data, sizeof(struct venc_msg)); - list_del(&l->list); - list_add(&l->list, &dvenc->venc_msg_list_free); - ret = 1; - break; - } - spin_unlock_irqrestore(&dvenc->venc_msg_list_lock, flags); - if (copy_to_user(msg, &qdsp_msg, sizeof(struct venc_msg))) - pr_err("%s failed to copy_to_user\n", __func__); - return ret; -} - -static void venc_put_msg(struct venc_dev *dvenc, struct venc_msg *msg) -{ - struct venc_msg_list *l; - unsigned long flags; - int found = 0; - - spin_lock_irqsave(&dvenc->venc_msg_list_lock, flags); - list_for_each_entry(l, &dvenc->venc_msg_list_free, list) { - memcpy(&l->msg_data, msg, sizeof(struct venc_msg)); - list_del(&l->list); - list_add(&l->list, &dvenc->venc_msg_list_head); - found = 1; - break; - } - spin_unlock_irqrestore(&dvenc->venc_msg_list_lock, flags); - if (found) - wake_up(&dvenc->venc_msg_evt); - else - pr_err("%s: failed to find a free node\n", __func__); - -} - -static struct venc_pmem_list *venc_add_pmem_to_list(struct venc_dev *dvenc, - struct venc_pmem *mptr, - u32 btype) -{ - int ret = 0; - unsigned long flags; - unsigned long len; - unsigned long vaddr; - struct venc_pmem_list *plist = NULL; - - plist = kzalloc(sizeof(struct venc_pmem_list), GFP_KERNEL); - if (!plist) { - pr_err("%s: kzalloc failed\n", __func__); - return NULL; - } - - ret = get_pmem_file(mptr->fd, &(plist->buf.paddr), - &vaddr, &len, &(plist->buf.file)); - if (ret) { - pr_err("%s: get_pmem_file failed for fd=%d offset=%d\n", - __func__, mptr->fd, mptr->offset); - goto err_venc_add_pmem; - } else if (mptr->offset >= len) { - pr_err("%s: invalid offset (%d > %ld) for fd=%d\n", - __func__, mptr->offset, len, mptr->fd); - ret = -EINVAL; - goto err_venc_get_pmem; - } - - plist->buf.fd = mptr->fd; - plist->buf.paddr += mptr->offset; - plist->buf.size = mptr->size; - plist->buf.btype = btype; - plist->buf.offset = mptr->offset; - plist->buf.src = mptr->src; - - spin_lock_irqsave(&dvenc->venc_pmem_list_lock, flags); - list_add(&plist->list, &dvenc->venc_pmem_list_head); - spin_unlock_irqrestore(&dvenc->venc_pmem_list_lock, flags); - return plist; - -err_venc_get_pmem: - put_pmem_file(plist->buf.file); -err_venc_add_pmem: - kfree(plist); - return NULL; -} - -static struct venc_pmem_list *venc_get_pmem_from_list( - struct venc_dev *dvenc, u32 pmem_fd, - u32 offset, u32 btype) -{ - struct venc_pmem_list *plist; - unsigned long flags; - struct file *file; - int found = 0; - - file = fget(pmem_fd); - if (!file) { - pr_err("%s: invalid encoder buffer fd(%d)\n", __func__, - pmem_fd); - return NULL; - } - spin_lock_irqsave(&dvenc->venc_pmem_list_lock, flags); - list_for_each_entry(plist, &dvenc->venc_pmem_list_head, list) { - if (plist->buf.btype == btype && plist->buf.file == file && - plist->buf.offset == offset) { - found = 1; - break; - } - } - spin_unlock_irqrestore(&dvenc->venc_pmem_list_lock, flags); - fput(file); - if (found) - return plist; - - else - return NULL; -} - -static int venc_set_buffer(struct venc_dev *dvenc, void *argp, - u32 btype) -{ - struct venc_pmem pmem; - struct venc_pmem_list *plist; - int ret = 0; - - ret = copy_from_user(&pmem, argp, sizeof(pmem)); - if (ret) { - pr_err("%s: copy_from_user failed\n", __func__); - return ret; - } - plist = venc_add_pmem_to_list(dvenc, &pmem, btype); - if (plist == NULL) { - pr_err("%s: buffer add_to_pmem_list failed\n", - __func__); - return -EPERM; - } - return ret; -} - -static int venc_assign_q6_buffers(struct venc_dev *dvenc, - struct venc_buffers *pbufs, - struct venc_nonio_buf_config *pcfg) -{ - int ret = 0; - struct venc_pmem_list *plist; - - plist = venc_add_pmem_to_list(dvenc, &(pbufs->recon_buf[0]), - VENC_BUFFER_TYPE_QDSP6); - if (plist == NULL) { - pr_err("%s: recon_buf0 failed to add_to_pmem_list\n", - __func__); - return -EPERM; - } - pcfg->recon_buf1.region = pbufs->recon_buf[0].src; - pcfg->recon_buf1.phys = plist->buf.paddr; - pcfg->recon_buf1.size = plist->buf.size; - pcfg->recon_buf1.offset = 0; - - plist = venc_add_pmem_to_list(dvenc, &(pbufs->recon_buf[1]), - VENC_BUFFER_TYPE_QDSP6); - if (plist == NULL) { - pr_err("%s: recons_buf1 failed to add_to_pmem_list\n", - __func__); - return -EPERM; - } - pcfg->recon_buf2.region = pbufs->recon_buf[1].src; - pcfg->recon_buf2.phys = plist->buf.paddr; - pcfg->recon_buf2.size = plist->buf.size; - pcfg->recon_buf2.offset = 0; - - plist = venc_add_pmem_to_list(dvenc, &(pbufs->wb_buf), - VENC_BUFFER_TYPE_QDSP6); - if (plist == NULL) { - pr_err("%s: wb_buf failed to add_to_pmem_list\n", - __func__); - return -EPERM; - } - pcfg->wb_buf.region = pbufs->wb_buf.src; - pcfg->wb_buf.phys = plist->buf.paddr; - pcfg->wb_buf.size = plist->buf.size; - pcfg->wb_buf.offset = 0; - - plist = venc_add_pmem_to_list(dvenc, &(pbufs->cmd_buf), - VENC_BUFFER_TYPE_QDSP6); - if (plist == NULL) { - pr_err("%s: cmd_buf failed to add_to_pmem_list\n", - __func__); - return -EPERM; - } - pcfg->cmd_buf.region = pbufs->cmd_buf.src; - pcfg->cmd_buf.phys = plist->buf.paddr; - pcfg->cmd_buf.size = plist->buf.size; - pcfg->cmd_buf.offset = 0; - - plist = venc_add_pmem_to_list(dvenc, &(pbufs->vlc_buf), - VENC_BUFFER_TYPE_QDSP6); - if (plist == NULL) { - pr_err("%s: vlc_buf failed to add_to_pmem_list" - " failed\n", __func__); - return -EPERM; - } - pcfg->vlc_buf.region = pbufs->vlc_buf.src; - pcfg->vlc_buf.phys = plist->buf.paddr; - pcfg->vlc_buf.size = plist->buf.size; - pcfg->vlc_buf.offset = 0; - - return ret; -} - -static int venc_start(struct venc_dev *dvenc, void *argp) -{ - int ret = 0; - struct venc_q6_config q6_config; - struct venc_init_config vconfig; - - dvenc->state = VENC_STATE_START; - ret = copy_from_user(&vconfig, argp, sizeof(struct venc_init_config)); - if (ret) { - pr_err("%s: copy_from_user failed\n", __func__); - return ret; - } - memcpy(&q6_config, &(vconfig.q6_config), sizeof(q6_config)); - ret = venc_assign_q6_buffers(dvenc, &(vconfig.q6_bufs), - &(q6_config.buf_params)); - if (ret != 0) { - pr_err("%s: assign_q6_buffers failed\n", __func__); - return -EPERM; - } - - q6_config.callback_event = dvenc->q6_handle; - TRACE("%s: parameters: handle:%p, config:%p, callback:%p \n", __func__, - dvenc->q6_handle, &q6_config, q6_config.callback_event); - TRACE("%s: parameters:recon1:0x%x, recon2:0x%x," - " wb_buf:0x%x, cmd:0x%x, vlc:0x%x\n", __func__, - q6_config.buf_params.recon_buf1.phys, - q6_config.buf_params.recon_buf2.phys, - q6_config.buf_params.wb_buf.phys, - q6_config.buf_params.cmd_buf.phys, - q6_config.buf_params.vlc_buf.phys); - TRACE("%s: size of param:%d \n", __func__, sizeof(q6_config)); - ret = dal_call_f5(dvenc->q6_handle, VENC_DALRPC_START, &q6_config, - sizeof(q6_config)); - if (ret != 0) { - pr_err("%s: remote function failed (%d)\n", __func__, ret); - return ret; - } - return ret; -} - -static int venc_encode_frame(struct venc_dev *dvenc, void *argp) -{ - int ret = 0; - struct venc_pmem buf; - struct venc_input_buf q6_input; - struct venc_pmem_list *plist; - struct venc_buffer input; - - ret = copy_from_user(&input, argp, sizeof(struct venc_buffer)); - if (ret) { - pr_err("%s: copy_from_user failed\n", __func__); - return ret; - } - ret = copy_from_user(&buf, - ((struct venc_buffer *)argp)->ptr_buffer, - sizeof(struct venc_pmem)); - if (ret) { - pr_err("%s: copy_from_user failed\n", __func__); - return ret; - } - - plist = venc_get_pmem_from_list(dvenc, buf.fd, buf.offset, - VENC_BUFFER_TYPE_INPUT); - if (NULL == plist) { - plist = venc_add_pmem_to_list(dvenc, &buf, - VENC_BUFFER_TYPE_INPUT); - if (plist == NULL) { - pr_err("%s: buffer add_to_pmem_list failed\n", - __func__); - return -EPERM; - } - } - - q6_input.flags = 0; - if (input.flags & VENC_FLAG_EOS) - q6_input.flags |= 0x00000001; - q6_input.yuv_buf.region = plist->buf.src; - q6_input.yuv_buf.phys = plist->buf.paddr; - q6_input.yuv_buf.size = plist->buf.size; - q6_input.yuv_buf.offset = 0; - q6_input.data_size = plist->buf.size; - q6_input.client_data = (u32)input.client_data; - q6_input.time_stamp = input.time_stamp; - q6_input.dvs_offsetx = 0; - q6_input.dvs_offsety = 0; - - TRACE("Pushing down input phys=0x%x fd= %d, client_data: 0x%x," - " time_stamp:%lld \n", q6_input.yuv_buf.phys, plist->buf.fd, - input.client_data, input.time_stamp); - ret = dal_call_f5(dvenc->q6_handle, VENC_DALRPC_QUEUE_INPUT, - &q6_input, sizeof(q6_input)); - - if (ret != 0) - pr_err("%s: Q6 queue_input failed (%d)\n", __func__, - (int)ret); - return ret; -} - -static int venc_fill_output(struct venc_dev *dvenc, void *argp) -{ - int ret = 0; - struct venc_pmem buf; - struct venc_output_buf q6_output; - struct venc_pmem_list *plist; - struct venc_buffer output; - - ret = copy_from_user(&output, argp, sizeof(struct venc_buffer)); - if (ret) { - pr_err("%s: copy_from_user failed\n", __func__); - return ret; - } - ret = copy_from_user(&buf, - ((struct venc_buffer *)argp)->ptr_buffer, - sizeof(struct venc_pmem)); - if (ret) { - pr_err("%s: copy_from_user failed\n", __func__); - return ret; - } - plist = venc_get_pmem_from_list(dvenc, buf.fd, buf.offset, - VENC_BUFFER_TYPE_OUTPUT); - if (NULL == plist) { - plist = venc_add_pmem_to_list(dvenc, &buf, - VENC_BUFFER_TYPE_OUTPUT); - if (NULL == plist) { - pr_err("%s: output buffer failed to add_to_pmem_list" - "\n", __func__); - return -EPERM; - } - } - q6_output.bit_stream_buf.region = plist->buf.src; - q6_output.bit_stream_buf.phys = (u32)plist->buf.paddr; - q6_output.bit_stream_buf.size = plist->buf.size; - q6_output.bit_stream_buf.offset = 0; - q6_output.client_data = (u32)output.client_data; - ret = - dal_call_f5(dvenc->q6_handle, VENC_DALRPC_QUEUE_OUTPUT, &q6_output, - sizeof(q6_output)); - if (ret != 0) - pr_err("%s: remote function failed (%d)\n", __func__, ret); - return ret; -} - -static int venc_stop(struct venc_dev *dvenc) -{ - int ret = 0; - struct venc_msg msg; - - ret = dal_call_f0(dvenc->q6_handle, VENC_DALRPC_STOP, 1); - if (ret) { - pr_err("%s: remote runction failed (%d)\n", __func__, ret); - msg.msg_code = VENC_MSG_STOP; - msg.msg_data_size = 0; - msg.status_code = VENC_S_EFAIL; - venc_put_msg(dvenc, &msg); - } - return ret; -} - -static int venc_pause(struct venc_dev *dvenc) -{ - int ret = 0; - struct venc_msg msg; - - ret = dal_call_f0(dvenc->q6_handle, VENC_DALRPC_SUSPEND, 1); - if (ret) { - pr_err("%s: remote function failed (%d)\n", __func__, ret); - msg.msg_code = VENC_MSG_PAUSE; - msg.status_code = VENC_S_EFAIL; - msg.msg_data_size = 0; - venc_put_msg(dvenc, &msg); - } - return ret; -} - -static int venc_resume(struct venc_dev *dvenc) -{ - int ret = 0; - struct venc_msg msg; - - ret = dal_call_f0(dvenc->q6_handle, VENC_DALRPC_RESUME, 1); - if (ret) { - pr_err("%s: remote function failed (%d)\n", __func__, ret); - msg.msg_code = VENC_MSG_RESUME; - msg.msg_data_size = 0; - msg.status_code = VENC_S_EFAIL; - venc_put_msg(dvenc, &msg); - } - return ret; -} - -static int venc_flush(struct venc_dev *dvenc, void *argp) -{ - int ret = 0; - struct venc_msg msg; - union venc_msg_data smsg; - int status = VENC_S_SUCCESS; - struct venc_buffer_flush flush; - - if (copy_from_user(&flush, argp, sizeof(struct venc_buffer_flush))) - return -EFAULT; - if (flush.flush_mode == VENC_FLUSH_ALL) { - ret = dal_call_f0(dvenc->q6_handle, VENC_DALRPC_FLUSH, 1); - if (ret) - status = VENC_S_EFAIL; - } else - status = VENC_S_ENOTSUPP; - - if (status != VENC_S_SUCCESS) { - if ((flush.flush_mode == VENC_FLUSH_INPUT) || - (flush.flush_mode == VENC_FLUSH_ALL)) { - smsg.flush_ret.flush_mode = VENC_FLUSH_INPUT; - msg.msg_data = smsg; - msg.status_code = status; - msg.msg_code = VENC_MSG_FLUSH; - msg.msg_data_size = sizeof(union venc_msg_data); - venc_put_msg(dvenc, &msg); - } - if (flush.flush_mode == VENC_FLUSH_OUTPUT || - (flush.flush_mode == VENC_FLUSH_ALL)) { - smsg.flush_ret.flush_mode = VENC_FLUSH_OUTPUT; - msg.msg_data = smsg; - msg.status_code = status; - msg.msg_code = VENC_MSG_FLUSH; - msg.msg_data_size = sizeof(union venc_msg_data); - venc_put_msg(dvenc, &msg); - } - return -EIO; - } - return ret; -} - -static int venc_get_sequence_hdr(struct venc_dev *dvenc, void *argp) -{ - pr_err("%s not supported\n", __func__); - return -EIO; -} - -static int venc_set_qp_range(struct venc_dev *dvenc, void *argp) -{ - int ret = 0; - struct venc_qp_range qp; - - ret = copy_from_user(&qp, argp, sizeof(struct venc_qp_range)); - if (ret) { - pr_err("%s: copy_from_user failed\n", __func__); - return ret; - } - - if (dvenc->state == VENC_STATE_START || - dvenc->state == VENC_STATE_PAUSE) { - ret = - dal_call_f5(dvenc->q6_handle, VENC_DALRPC_UPDATE_QP_RANGE, - &qp, sizeof(struct venc_qp_range)); - if (ret) { - pr_err("%s: remote function failed (%d) \n", __func__, - ret); - return ret; - } - } - return ret; -} - -static int venc_set_intra_period(struct venc_dev *dvenc, void *argp) -{ - int ret = 0; - u32 pnum = 0; - - ret = copy_from_user(&pnum, argp, sizeof(int)); - if (ret) { - pr_err("%s: copy_from_user failed\n", __func__); - return ret; - } - if (dvenc->state == VENC_STATE_START || - dvenc->state == VENC_STATE_PAUSE) { - ret = dal_call_f0(dvenc->q6_handle, - VENC_DALRPC_UPDATE_INTRA_PERIOD, pnum); - if (ret) - pr_err("%s: remote function failed (%d)\n", __func__, - ret); - } - return ret; -} - -static int venc_set_intra_refresh(struct venc_dev *dvenc, void *argp) -{ - int ret = 0; - u32 mb_num = 0; - - ret = copy_from_user(&mb_num, argp, sizeof(int)); - if (ret) { - pr_err("%s: copy_from_user failed\n", __func__); - return ret; - } - if (dvenc->state == VENC_STATE_START || - dvenc->state == VENC_STATE_PAUSE) { - ret = dal_call_f0(dvenc->q6_handle, - VENC_DALRPC_UPDATE_INTRA_REFRESH, mb_num); - if (ret) - pr_err("%s: remote function failed (%d)\n", __func__, - ret); - } - return ret; -} - -static int venc_set_frame_rate(struct venc_dev *dvenc, void *argp) -{ - int ret = 0; - struct venc_frame_rate pdata; - ret = copy_from_user(&pdata, argp, sizeof(struct venc_frame_rate)); - if (ret) { - pr_err("%s: copy_from_user failed\n", __func__); - return ret; - } - if (dvenc->state == VENC_STATE_START || - dvenc->state == VENC_STATE_PAUSE) { - ret = dal_call_f5(dvenc->q6_handle, - VENC_DALRPC_UPDATE_FRAME_RATE, - (void *)&(pdata), - sizeof(struct venc_frame_rate)); - if (ret) - pr_err("%s: remote function failed (%d)\n", __func__, - ret); - } - return ret; -} - -static int venc_set_target_bitrate(struct venc_dev *dvenc, void *argp) -{ - int ret = 0; - u32 pdata = 0; - - ret = copy_from_user(&pdata, argp, sizeof(int)); - if (ret) { - pr_err("%s: copy_from_user failed\n", __func__); - return ret; - } - if (dvenc->state == VENC_STATE_START || - dvenc->state == VENC_STATE_PAUSE) { - ret = dal_call_f0(dvenc->q6_handle, - VENC_DALRPC_UPDATE_BITRATE, pdata); - if (ret) - pr_err("%s: remote function failed (%d)\n", __func__, - ret); - } - return ret; -} - -static int venc_request_iframe(struct venc_dev *dvenc) -{ - int ret = 0; - - if (dvenc->state != VENC_STATE_START) - return -EINVAL; - - ret = dal_call_f0(dvenc->q6_handle, VENC_DALRPC_REQUEST_IFRAME, 1); - if (ret) - pr_err("%s: remote function failed (%d)\n", __func__, ret); - return ret; -} - -static int venc_stop_read_msg(struct venc_dev *dvenc) -{ - struct venc_msg msg; - int ret = 0; - - msg.status_code = 0; - msg.msg_code = VENC_MSG_STOP_READING_MSG; - msg.msg_data_size = 0; - venc_put_msg(dvenc, &msg); - return ret; -} - -static int venc_q6_stop(struct venc_dev *dvenc) -{ - int ret = 0; - struct venc_pmem_list *plist; - unsigned long flags; - - wake_up(&dvenc->venc_msg_evt); - spin_lock_irqsave(&dvenc->venc_pmem_list_lock, flags); - if (!dvenc->pmem_freed) { - list_for_each_entry(plist, &dvenc->venc_pmem_list_head, list) - put_pmem_file(plist->buf.file); - dvenc->pmem_freed = 1; - } - spin_unlock_irqrestore(&dvenc->venc_pmem_list_lock, flags); - - dvenc->state = VENC_STATE_STOP; - return ret; -} - -static int venc_translate_error(enum venc_status_code q6_status) -{ - int ret = 0; - - switch (q6_status) { - case VENC_STATUS_SUCCESS: - ret = VENC_S_SUCCESS; - break; - case VENC_STATUS_ERROR: - ret = VENC_S_EFAIL; - break; - case VENC_STATUS_INVALID_STATE: - ret = VENC_S_EINVALSTATE; - break; - case VENC_STATUS_FLUSHING: - ret = VENC_S_EFLUSHED; - break; - case VENC_STATUS_INVALID_PARAM: - ret = VENC_S_EBADPARAM; - break; - case VENC_STATUS_CMD_QUEUE_FULL: - ret = VENC_S_ECMDQFULL; - break; - case VENC_STATUS_CRITICAL: - ret = VENC_S_EFATAL; - break; - case VENC_STATUS_INSUFFICIENT_RESOURCES: - ret = VENC_S_ENOHWRES; - break; - case VENC_STATUS_TIMEOUT: - ret = VENC_S_ETIMEOUT; - break; - } - if (q6_status != VENC_STATUS_SUCCESS) - pr_err("%s: Q6 failed (%d)", __func__, (int)q6_status); - return ret; -} - -static void venc_q6_callback(void *data, int len, void *cookie) -{ - int status = 0; - struct venc_dev *dvenc = (struct venc_dev *)cookie; - struct venc_msg_type *q6_msg = NULL; - struct venc_msg msg, msg1; - union venc_msg_data smsg1, smsg2; - unsigned long msg_code = 0; - struct venc_input_payload *pload1; - struct venc_output_payload *pload2; - uint32_t * tmp = (uint32_t *) data; - - if (dvenc == NULL) { - pr_err("%s: empty driver parameter\n", __func__); - return; - } - if (tmp[2] == sizeof(struct venc_msg_type)) { - q6_msg = (struct venc_msg_type *)&tmp[3]; - } else { - pr_err("%s: callback with empty message (%d, %d)\n", - __func__, tmp[2], sizeof(struct venc_msg_type)); - return; - } - msg.msg_data_size = 0; - status = venc_translate_error(q6_msg->status); - switch ((enum venc_event_type_enum)q6_msg->event) { - case VENC_EVENT_START_STATUS: - dvenc->state = VENC_STATE_START; - msg_code = VENC_MSG_START; - break; - case VENC_EVENT_STOP_STATUS: - venc_q6_stop(dvenc); - msg_code = VENC_MSG_STOP; - break; - case VENC_EVENT_SUSPEND_STATUS: - dvenc->state = VENC_STATE_PAUSE; - msg_code = VENC_MSG_PAUSE; - break; - case VENC_EVENT_RESUME_STATUS: - dvenc->state = VENC_STATE_START; - msg_code = VENC_MSG_RESUME; - break; - case VENC_EVENT_FLUSH_STATUS: - smsg1.flush_ret.flush_mode = VENC_FLUSH_INPUT; - msg1.status_code = status; - msg1.msg_code = VENC_MSG_FLUSH; - msg1.msg_data = smsg1; - msg1.msg_data_size = sizeof(union venc_msg_data); - venc_put_msg(dvenc, &msg1); - smsg2.flush_ret.flush_mode = VENC_FLUSH_OUTPUT; - msg_code = VENC_MSG_FLUSH; - msg.msg_data = smsg2; - msg.msg_data_size = sizeof(union venc_msg_data); - break; - case VENC_EVENT_RELEASE_INPUT: - pload1 = &((q6_msg->payload).input_payload); - TRACE("Release_input: data: 0x%x \n", pload1->data); - if (pload1 != NULL) { - msg.msg_data.buf.client_data = pload1->data; - msg_code = VENC_MSG_INPUT_BUFFER_DONE; - msg.msg_data_size = sizeof(union venc_msg_data); - } - break; - case VENC_EVENT_DELIVER_OUTPUT: - pload2 = &((q6_msg->payload).output_payload); - smsg1.buf.flags = 0; - if (pload2->flags & VENC_FLAG_SYNC_FRAME) - smsg1.buf.flags |= VENC_FLAG_SYNC_FRAME; - if (pload2->flags & VENC_FLAG_CODEC_CONFIG) - smsg1.buf.flags |= VENC_FLAG_CODEC_CONFIG; - if (pload2->flags & VENC_FLAG_END_OF_FRAME) - smsg1.buf.flags |= VENC_FLAG_END_OF_FRAME; - if (pload2->flags & VENC_FLAG_EOS) - smsg1.buf.flags |= VENC_FLAG_EOS; - smsg1.buf.len = pload2->size; - smsg1.buf.offset = 0; - smsg1.buf.time_stamp = pload2->time_stamp; - smsg1.buf.client_data = pload2->data; - msg_code = VENC_MSG_OUTPUT_BUFFER_DONE; - msg.msg_data = smsg1; - msg.msg_data_size = sizeof(union venc_msg_data); - break; - default: - pr_err("%s: invalid response from Q6 (%d)\n", __func__, - (int)q6_msg->event); - return; - } - msg.status_code = status; - msg.msg_code = msg_code; - venc_put_msg(dvenc, &msg); - return; -} - -static int venc_get_version(struct venc_dev *dvenc, void *argp) -{ - struct venc_version ver_info; - int ret = 0; - - ver_info.major = VENC_GET_MAJOR_VERSION(VENC_INTERFACE_VERSION); - ver_info.minor = VENC_GET_MINOR_VERSION(VENC_INTERFACE_VERSION); - - ret = copy_to_user(((struct venc_version *)argp), - &ver_info, sizeof(ver_info)); - if (ret) - pr_err("%s failed to copy_to_user\n", __func__); - - return ret; - -} - -static long q6venc_ioctl(struct file *file, u32 cmd, - unsigned long arg) -{ - long ret = 0; - void __user *argp = (void __user *)arg; - struct venc_dev *dvenc = file->private_data; - - if (!dvenc || !dvenc->is_active) - return -EPERM; - - switch (cmd) { - case VENC_IOCTL_SET_INPUT_BUFFER: - ret = venc_set_buffer(dvenc, argp, VENC_BUFFER_TYPE_INPUT); - break; - case VENC_IOCTL_SET_OUTPUT_BUFFER: - ret = venc_set_buffer(dvenc, argp, VENC_BUFFER_TYPE_OUTPUT); - break; - case VENC_IOCTL_GET_SEQUENCE_HDR: - ret = venc_get_sequence_hdr(dvenc, argp); - break; - case VENC_IOCTL_SET_QP_RANGE: - ret = venc_set_qp_range(dvenc, argp); - break; - case VENC_IOCTL_SET_INTRA_PERIOD: - ret = venc_set_intra_period(dvenc, argp); - break; - case VENC_IOCTL_SET_INTRA_REFRESH: - ret = venc_set_intra_refresh(dvenc, argp); - break; - case VENC_IOCTL_SET_FRAME_RATE: - ret = venc_set_frame_rate(dvenc, argp); - break; - case VENC_IOCTL_SET_TARGET_BITRATE: - ret = venc_set_target_bitrate(dvenc, argp); - break; - case VENC_IOCTL_CMD_REQUEST_IFRAME: - if (dvenc->state == VENC_STATE_START) - ret = venc_request_iframe(dvenc); - break; - case VENC_IOCTL_CMD_START: - ret = venc_start(dvenc, argp); - break; - case VENC_IOCTL_CMD_STOP: - ret = venc_stop(dvenc); - break; - case VENC_IOCTL_CMD_PAUSE: - ret = venc_pause(dvenc); - break; - case VENC_IOCTL_CMD_RESUME: - ret = venc_resume(dvenc); - break; - case VENC_IOCTL_CMD_ENCODE_FRAME: - ret = venc_encode_frame(dvenc, argp); - break; - case VENC_IOCTL_CMD_FILL_OUTPUT_BUFFER: - ret = venc_fill_output(dvenc, argp); - break; - case VENC_IOCTL_CMD_FLUSH: - ret = venc_flush(dvenc, argp); - break; - case VENC_IOCTL_CMD_READ_NEXT_MSG: - wait_event_interruptible(dvenc->venc_msg_evt, - venc_get_msg(dvenc, argp)); - break; - case VENC_IOCTL_CMD_STOP_READ_MSG: - ret = venc_stop_read_msg(dvenc); - break; - case VENC_IOCTL_GET_VERSION: - ret = venc_get_version(dvenc, argp); - break; - default: - pr_err("%s: invalid ioctl code (%d)\n", __func__, cmd); - ret = -ENOTTY; - break; - } - return ret; -} - -static int q6venc_open(struct inode *inode, struct file *file) -{ - int i; - int ret = 0; - struct venc_dev *dvenc; - struct venc_msg_list *plist, *tmp; - struct dal_info version_info; - - dvenc = kzalloc(sizeof(struct venc_dev), GFP_KERNEL); - if (!dvenc) { - pr_err("%s: unable to allocate memory for struct venc_dev\n", - __func__); - return -ENOMEM; - } - file->private_data = dvenc; - INIT_LIST_HEAD(&dvenc->venc_msg_list_head); - INIT_LIST_HEAD(&dvenc->venc_msg_list_free); - INIT_LIST_HEAD(&dvenc->venc_pmem_list_head); - init_waitqueue_head(&dvenc->venc_msg_evt); - spin_lock_init(&dvenc->venc_msg_list_lock); - spin_lock_init(&dvenc->venc_pmem_list_lock); - venc_ref++; - for (i = 0; i < VENC_MSG_MAX; i++) { - plist = kzalloc(sizeof(struct venc_msg_list), GFP_KERNEL); - if (!plist) { - pr_err("%s: kzalloc failed\n", __func__); - ret = -ENOMEM; - goto err_venc_create_msg_list; - } - list_add(&plist->list, &dvenc->venc_msg_list_free); - } - dvenc->q6_handle = - dal_attach(DALDEVICEID_VENC_DEVICE, DALDEVICEID_VENC_PORTNAME, 1, - venc_q6_callback, (void *)dvenc); - if (!(dvenc->q6_handle)) { - pr_err("%s: daldevice_attach failed (%d)\n", __func__, ret); - goto err_venc_dal_attach; - } - ret = dal_call_f9(dvenc->q6_handle, DAL_OP_INFO, &version_info, - sizeof(struct dal_info)); - if (ret) { - pr_err("%s: failed to get version\n", __func__); - goto err_venc_dal_open; - } - if (venc_check_version(VENC_INTERFACE_VERSION, version_info.version)) { - pr_err("%s: driver version mismatch\n", __func__); - goto err_venc_dal_open; - } - ret = dal_call_f0(dvenc->q6_handle, DAL_OP_OPEN, 1); - if (ret) { - pr_err("%s: dal_call_open failed (%d)\n", __func__, ret); - goto err_venc_dal_open; - } - dvenc->state = VENC_STATE_STOP; - dvenc->is_active = 1; - prevent_sleep(); - return ret; -err_venc_dal_open: - dal_detach(dvenc->q6_handle); -err_venc_dal_attach: - list_for_each_entry_safe(plist, tmp, &dvenc->venc_msg_list_free, list) { - list_del(&plist->list); - kfree(plist); - } -err_venc_create_msg_list: - kfree(dvenc); - venc_ref--; - return ret; -} - -static int q6venc_release(struct inode *inode, struct file *file) -{ - int ret = 0; - struct venc_msg_list *l, *n; - struct venc_pmem_list *plist, *m; - struct venc_dev *dvenc; - unsigned long flags; - - venc_ref--; - dvenc = file->private_data; - dvenc->is_active = 0; - wake_up_all(&dvenc->venc_msg_evt); - dal_call_f0(dvenc->q6_handle, VENC_DALRPC_STOP, 1); - dal_call_f0(dvenc->q6_handle, DAL_OP_CLOSE, 1); - dal_detach(dvenc->q6_handle); - list_for_each_entry_safe(l, n, &dvenc->venc_msg_list_free, list) { - list_del(&l->list); - kfree(l); - } - list_for_each_entry_safe(l, n, &dvenc->venc_msg_list_head, list) { - list_del(&l->list); - kfree(l); - } - spin_lock_irqsave(&dvenc->venc_pmem_list_lock, flags); - if (!dvenc->pmem_freed) { - list_for_each_entry(plist, &dvenc->venc_pmem_list_head, list) - put_pmem_file(plist->buf.file); - dvenc->pmem_freed = 1; - } - spin_unlock_irqrestore(&dvenc->venc_pmem_list_lock, flags); - - list_for_each_entry_safe(plist, m, &dvenc->venc_pmem_list_head, list) { - list_del(&plist->list); - kfree(plist); - } - kfree(dvenc); - allow_sleep(); - return ret; -} - -const struct file_operations q6venc_fops = { - .owner = THIS_MODULE, - .open = q6venc_open, - .release = q6venc_release, - .unlocked_ioctl = q6venc_ioctl, -}; - -static int __init q6venc_init(void) -{ - int ret = 0; - - pm_qos_add_request(&pm_qos_req, PM_QOS_CPU_DMA_LATENCY, - PM_QOS_DEFAULT_VALUE); - wake_lock_init(&wakelock, WAKE_LOCK_SUSPEND, "venc_suspend"); - - venc_device_p = kzalloc(sizeof(struct venc_dev), GFP_KERNEL); - if (!venc_device_p) { - pr_err("%s: unable to allocate memory for venc_device_p\n", - __func__); - return -ENOMEM; - } - ret = alloc_chrdev_region(&venc_dev_num, 0, 1, VENC_NAME); - if (ret < 0) { - pr_err("%s: alloc_chrdev_region failed (%d)\n", __func__, - ret); - return ret; - } - venc_class = class_create(THIS_MODULE, VENC_NAME); - if (IS_ERR(venc_class)) { - ret = PTR_ERR(venc_class); - pr_err("%s: failed to create venc_class (%d)\n", - __func__, ret); - goto err_venc_class_create; - } - venc_device_p->class_devp = - device_create(venc_class, NULL, venc_dev_num, NULL, - VENC_NAME); - if (IS_ERR(venc_device_p->class_devp)) { - ret = PTR_ERR(venc_device_p->class_devp); - pr_err("%s: failed to create class_device (%d)\n", __func__, - ret); - goto err_venc_class_device_create; - } - cdev_init(&cdev, &q6venc_fops); - cdev.owner = THIS_MODULE; - ret = cdev_add(&cdev, venc_dev_num, 1); - if (ret < 0) { - pr_err("%s: cdev_add failed (%d)\n", __func__, ret); - goto err_venc_cdev_add; - } - init_waitqueue_head(&venc_device_p->venc_msg_evt); - return ret; - -err_venc_cdev_add: - device_destroy(venc_class, venc_dev_num); -err_venc_class_device_create: - class_destroy(venc_class); -err_venc_class_create: - unregister_chrdev_region(venc_dev_num, 1); - return ret; -} - -static void __exit q6venc_exit(void) -{ - cdev_del(&(cdev)); - device_destroy(venc_class, venc_dev_num); - class_destroy(venc_class); - unregister_chrdev_region(venc_dev_num, 1); -} - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Video encoder driver for QDSP6"); -MODULE_VERSION("2.0"); -module_init(q6venc_init); -module_exit(q6venc_exit); diff --git a/arch/arm/mach-msm/qdsp6/pcm_in.c b/arch/arm/mach-msm/qdsp6/pcm_in.c deleted file mode 100644 index c6bddb883eae0b25ef89da062601d8475b73a6ac..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/pcm_in.c +++ /dev/null @@ -1,263 +0,0 @@ -/* arch/arm/mach-msm/qdsp6/pcm_in.c - * - * Copyright (C) 2009 Google, Inc. - * Copyright (C) 2009 HTC Corporation - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -struct pcm { - struct audio_client *ac; - uint32_t sample_rate; - uint32_t channel_count; - uint32_t buffer_size; - uint32_t rec_mode; -}; - -#define BUFSZ (256) - -void audio_client_dump(struct audio_client *ac); - -static long q6_in_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct pcm *pcm = file->private_data; - int rc = 0; - - switch (cmd) { - case AUDIO_SET_VOLUME: - pr_debug("[%s:%s] SET_VOLUME\n", __MM_FILE__, __func__); - break; - case AUDIO_GET_STATS: { - struct msm_audio_stats stats; - pr_debug("[%s:%s] GET_STATS\n", __MM_FILE__, __func__); - memset(&stats, 0, sizeof(stats)); - if (copy_to_user((void*) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - case AUDIO_START: { - uint32_t acdb_id; - pr_debug("[%s:%s] AUDIO_START\n", __MM_FILE__, __func__); - rc = 0; - - if (arg == 0) { - acdb_id = 0; - } else if (copy_from_user(&acdb_id, (void*) arg, sizeof(acdb_id))) { - rc = -EFAULT; - break; - } - - if (pcm->ac) { - pr_err("[%s:%s] active session already existing\n", - __MM_FILE__, __func__); - rc = -EBUSY; - } else { - pcm->ac = q6audio_open_pcm(pcm->buffer_size, - pcm->sample_rate, pcm->channel_count, - pcm->rec_mode, acdb_id); - if (!pcm->ac) { - pr_err("[%s:%s] pcm open session failed\n", - __MM_FILE__, __func__); - rc = -ENOMEM; - } - } - break; - } - case AUDIO_STOP: - pr_debug("[%s:%s] AUDIO_STOP\n", __MM_FILE__, __func__); - break; - case AUDIO_FLUSH: - break; - case AUDIO_SET_CONFIG: { - struct msm_audio_config config; - if (copy_from_user(&config, (void*) arg, sizeof(config))) { - rc = -EFAULT; - break; - } - pr_debug("[%s:%s] SET_CONFIG: samplerate = %d, channels = %d\n", - __MM_FILE__, __func__, config.sample_rate, - config.channel_count); - if (!config.channel_count || config.channel_count > 2) { - rc = -EINVAL; - pr_err("[%s:%s] invalid channelcount %d\n", - __MM_FILE__, __func__, config.channel_count); - break; - } - if (config.sample_rate < 8000 || config.sample_rate > 48000) { - rc = -EINVAL; - pr_err("[%s:%s] invalid samplerate %d\n", __MM_FILE__, - __func__, config.sample_rate); - break; - } - if (config.buffer_size < 128 || config.buffer_size > 8192) { - rc = -EINVAL; - pr_err("[%s:%s] invalid buffsize %d\n", __MM_FILE__, - __func__, config.buffer_size); - break; - } - - pcm->sample_rate = config.sample_rate; - pcm->channel_count = config.channel_count; - pcm->buffer_size = config.buffer_size; - break; - } - case AUDIO_SET_INCALL: { - struct msm_voicerec_mode voicerec_mode; - pr_debug("[%s:%s] SET_INCALL\n", __MM_FILE__, __func__); - if (copy_from_user(&voicerec_mode, (void *)arg, - sizeof(struct msm_voicerec_mode))) - return -EFAULT; - if (voicerec_mode.rec_mode != AUDIO_FLAG_READ && - voicerec_mode.rec_mode != AUDIO_FLAG_INCALL_MIXED) { - pcm->rec_mode = AUDIO_FLAG_READ; - pr_err("[%s:%s] invalid rec_mode\n", __MM_FILE__, - __func__); - rc = -EINVAL; - } else - pcm->rec_mode = voicerec_mode.rec_mode; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config config; - config.buffer_size = pcm->buffer_size; - config.buffer_count = 2; - config.sample_rate = pcm->sample_rate; - config.channel_count = pcm->channel_count; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void*) arg, &config, sizeof(config))) { - rc = -EFAULT; - } - pr_debug("[%s:%s] GET_CONFIG: samplerate = %d, channels = %d\n", - __MM_FILE__, __func__, config.sample_rate, - config.channel_count); - break; - } - default: - rc = -EINVAL; - } - pr_debug("[%s:%s] rc = %d\n", __MM_FILE__, __func__, rc); - return rc; -} - -static int q6_in_open(struct inode *inode, struct file *file) -{ - struct pcm *pcm; - - pr_info("[%s:%s] open\n", __MM_FILE__, __func__); - pcm = kzalloc(sizeof(struct pcm), GFP_KERNEL); - - if (!pcm) - return -ENOMEM; - - pcm->channel_count = 1; - pcm->sample_rate = 8000; - pcm->buffer_size = BUFSZ; - pcm->rec_mode = AUDIO_FLAG_READ; - file->private_data = pcm; - return 0; -} - -static ssize_t q6_in_read(struct file *file, char __user *buf, - size_t count, loff_t *pos) -{ - struct pcm *pcm = file->private_data; - struct audio_client *ac; - struct audio_buffer *ab; - const char __user *start = buf; - int xfer; - int res; - - pr_debug("[%s:%s] count = %d\n", __MM_FILE__, __func__, count); - ac = pcm->ac; - if (!ac) { - res = -ENODEV; - goto fail; - } - while (count > 0) { - ab = ac->buf + ac->cpu_buf; - - if (ab->used) - if (!wait_event_timeout(ac->wait, (ab->used == 0), 5*HZ)) { - audio_client_dump(ac); - pr_err("[%s:%s] timeout. dsp dead?\n", - __MM_FILE__, __func__); - q6audio_dsp_not_responding(); - } - pr_debug("[%s:%s] ab->data = %p, cpu_buf = %d", __MM_FILE__, - __func__, ab->data, ac->cpu_buf); - xfer = count; - if (xfer > ab->size) - xfer = ab->size; - - if (copy_to_user(buf, ab->data, xfer)) { - res = -EFAULT; - goto fail; - } - - buf += xfer; - count -= xfer; - - ab->used = 1; - q6audio_read(ac, ab); - ac->cpu_buf ^= 1; - } -fail: - res = buf - start; - return res; -} - -static int q6_in_release(struct inode *inode, struct file *file) -{ - - int rc = 0; - struct pcm *pcm = file->private_data; - if (pcm->ac) - rc = q6audio_close(pcm->ac); - kfree(pcm); - pr_info("[%s:%s] release\n", __MM_FILE__, __func__); - return rc; -} - -static struct file_operations q6_in_fops = { - .owner = THIS_MODULE, - .open = q6_in_open, - .read = q6_in_read, - .release = q6_in_release, - .unlocked_ioctl = q6_in_ioctl, -}; - -struct miscdevice q6_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_pcm_in", - .fops = &q6_in_fops, -}; - -static int __init q6_in_init(void) { - return misc_register(&q6_in_misc); -} - -device_initcall(q6_in_init); diff --git a/arch/arm/mach-msm/qdsp6/pcm_out.c b/arch/arm/mach-msm/qdsp6/pcm_out.c deleted file mode 100644 index 2e91cb2fed868336b5c4696496ef28c7e1d02e75..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/pcm_out.c +++ /dev/null @@ -1,276 +0,0 @@ -/* arch/arm/mach-msm/qdsp6/pcm_out.c - * - * Copyright (C) 2009 Google, Inc. - * Author: Brian Swetland - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -void audio_client_dump(struct audio_client *ac); - -#define BUFSZ (3072) - -struct pcm { - struct mutex lock; - struct audio_client *ac; - uint32_t sample_rate; - uint32_t channel_count; - size_t buffer_size; -}; - -static long pcm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct pcm *pcm = file->private_data; - int rc = 0; - - if (cmd == AUDIO_GET_STATS) { - struct msm_audio_stats stats; - memset(&stats, 0, sizeof(stats)); - if (copy_to_user((void*) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - - mutex_lock(&pcm->lock); - switch (cmd) { - case AUDIO_SET_VOLUME: { - int vol; - if (!pcm->ac) { - pr_err("%s: cannot set volume before AUDIO_START!\n", - __func__); - rc = -EINVAL; - break; - } - if (copy_from_user(&vol, (void*) arg, sizeof(vol))) { - rc = -EFAULT; - break; - } - pr_debug("[%s:%s] SET_VOLUME: vol = %d\n", __MM_FILE__, - __func__, vol); - rc = q6audio_set_stream_volume(pcm->ac, vol); - break; - } - case AUDIO_START: { - uint32_t acdb_id; - pr_debug("[%s:%s] AUDIO_START\n", __MM_FILE__, __func__); - if (arg == 0) { - acdb_id = 0; - } else if (copy_from_user(&acdb_id, (void*) arg, sizeof(acdb_id))) { - pr_info("[%s:%s] copy acdb_id from user failed\n", - __MM_FILE__, __func__); - rc = -EFAULT; - break; - } - if (pcm->ac) { - pr_err("[%s:%s] active session already existing\n", - __MM_FILE__, __func__); - rc = -EBUSY; - } else { - pcm->ac = q6audio_open_pcm(pcm->buffer_size, - pcm->sample_rate, - pcm->channel_count, - AUDIO_FLAG_WRITE, acdb_id); - if (!pcm->ac) { - pr_err("[%s:%s] pcm open session failed\n", - __MM_FILE__, __func__); - rc = -ENOMEM; - } - } - break; - } - case AUDIO_STOP: - pr_debug("[%s:%s] AUDIO_STOP\n", __MM_FILE__, __func__); - break; - case AUDIO_FLUSH: - break; - case AUDIO_SET_CONFIG: { - struct msm_audio_config config; - if (pcm->ac) { - rc = -EBUSY; - pr_err("[%s:%s] active session already existing\n", - __MM_FILE__, __func__); - break; - } - if (copy_from_user(&config, (void*) arg, sizeof(config))) { - rc = -EFAULT; - break; - } - pr_debug("[%s:%s] SET_CONFIG: samplerate = %d, channels = %d\n", - __MM_FILE__, __func__, config.sample_rate, - config.channel_count); - if (config.channel_count < 1 || config.channel_count > 2) { - rc = -EINVAL; - pr_err("[%s:%s] invalid channelcount %d\n", - __MM_FILE__, __func__, config.channel_count); - break; - } - if (config.sample_rate < 8000 || config.sample_rate > 48000) { - rc = -EINVAL; - pr_err("[%s:%s] invalid samplerate %d\n", __MM_FILE__, - __func__, config.sample_rate); - break; - } - if (config.buffer_size < 128 || config.buffer_size > 8192) { - rc = -EINVAL; - pr_err("[%s:%s] invalid buffsize %d\n", __MM_FILE__, - __func__, config.buffer_size); - break; - } - pcm->sample_rate = config.sample_rate; - pcm->channel_count = config.channel_count; - pcm->buffer_size = config.buffer_size; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config config; - config.buffer_size = pcm->buffer_size; - config.buffer_count = 2; - config.sample_rate = pcm->sample_rate; - config.channel_count = pcm->channel_count; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void*) arg, &config, sizeof(config))) { - rc = -EFAULT; - } - pr_debug("[%s:%s] GET_CONFIG: samplerate = %d, channels = %d\n", - __MM_FILE__, __func__, config.sample_rate, - config.channel_count); - break; - } - case AUDIO_SET_EQ: { - struct msm_audio_eq_stream_config eq_config; - pr_debug("[%s:%s] SET_EQ\n", __MM_FILE__, __func__); - if (copy_from_user(&eq_config, (void *) arg, - sizeof(eq_config))) { - rc = -EFAULT; - break; - } - rc = q6audio_set_stream_eq_pcm(pcm->ac, (void *) &eq_config); - break; - } - default: - rc = -EINVAL; - } - mutex_unlock(&pcm->lock); - pr_debug("[%s:%s] rc = %d\n", __MM_FILE__, __func__, rc); - return rc; -} - -static int pcm_open(struct inode *inode, struct file *file) -{ - struct pcm *pcm; - - pr_info("[%s:%s] open\n", __MM_FILE__, __func__); - pcm = kzalloc(sizeof(struct pcm), GFP_KERNEL); - - if (!pcm) - return -ENOMEM; - - mutex_init(&pcm->lock); - pcm->channel_count = 2; - pcm->sample_rate = 44100; - pcm->buffer_size = BUFSZ; - file->private_data = pcm; - return 0; -} - -static ssize_t pcm_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct pcm *pcm = file->private_data; - struct audio_client *ac; - struct audio_buffer *ab; - const char __user *start = buf; - int xfer; - - pr_debug("[%s:%s] count = %d\n", __MM_FILE__, __func__, count); - if (!pcm->ac) - pcm_ioctl(file, AUDIO_START, 0); - - ac = pcm->ac; - if (!ac) - return -ENODEV; - - while (count > 0) { - ab = ac->buf + ac->cpu_buf; - - if (ab->used) - if (!wait_event_timeout(ac->wait, (ab->used == 0), 5*HZ)) { - audio_client_dump(ac); - pr_err("[%s:%s] timeout. dsp dead?\n", - __MM_FILE__, __func__); - q6audio_dsp_not_responding(); - } - pr_debug("[%s:%s] ab->data = %p, cpu_buf = %d", __MM_FILE__, - __func__, ab->data, ac->cpu_buf); - xfer = count; - if (xfer > ab->size) - xfer = ab->size; - - if (copy_from_user(ab->data, buf, xfer)) - return -EFAULT; - - buf += xfer; - count -= xfer; - - ab->used = 1; - ab->actual_size = xfer; - q6audio_write(ac, ab); - ac->cpu_buf ^= 1; - } - - return buf - start; -} - -static int pcm_release(struct inode *inode, struct file *file) -{ - struct pcm *pcm = file->private_data; - if (pcm->ac) - q6audio_close(pcm->ac); - kfree(pcm); - pr_info("[%s:%s] release\n", __MM_FILE__, __func__); - return 0; -} - -static struct file_operations pcm_fops = { - .owner = THIS_MODULE, - .open = pcm_open, - .write = pcm_write, - .release = pcm_release, - .unlocked_ioctl = pcm_ioctl, -}; - -struct miscdevice pcm_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_pcm_out", - .fops = &pcm_fops, -}; - -static int __init pcm_init(void) { - return misc_register(&pcm_misc); -} - -device_initcall(pcm_init); diff --git a/arch/arm/mach-msm/qdsp6/q6audio.c b/arch/arm/mach-msm/qdsp6/q6audio.c deleted file mode 100644 index f660bdcf6d4b6135bffd2dd2aa6a5e2b05ebc944..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/q6audio.c +++ /dev/null @@ -1,2158 +0,0 @@ -/* - * Copyright (C) 2009 Google, Inc. - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * Author: Brian Swetland - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dal.h" -#include "dal_audio.h" -#include "dal_audio_format.h" -#include "dal_acdb.h" -#include "dal_adie.h" -#include -#include - -#include - -#include - -#include "q6audio_devices.h" -#include - - -struct q6_hw_info { - int min_gain; - int max_gain; -}; - -/* TODO: provide mechanism to configure from board file */ - -static struct q6_hw_info q6_audio_hw[Q6_HW_COUNT] = { - [Q6_HW_HANDSET] = { - .min_gain = -400, - .max_gain = 1100, - }, - [Q6_HW_HEADSET] = { - .min_gain = -1100, - .max_gain = 400, - }, - [Q6_HW_SPEAKER] = { - .min_gain = -1000, - .max_gain = 500, - }, - [Q6_HW_TTY] = { - .min_gain = 0, - .max_gain = 0, - }, - [Q6_HW_BT_SCO] = { - .min_gain = -1100, - .max_gain = 400, - }, - [Q6_HW_BT_A2DP] = { - .min_gain = -1100, - .max_gain = 400, - }, -}; - -static struct wake_lock wakelock; -static struct pm_qos_request pm_qos_req; -static int idlecount; -static DEFINE_MUTEX(idlecount_lock); - -void audio_prevent_sleep(void) -{ - mutex_lock(&idlecount_lock); - if (++idlecount == 1) { - wake_lock(&wakelock); - pm_qos_update_request(&pm_qos_req, - msm_cpuidle_get_deep_idle_latency()); - } - mutex_unlock(&idlecount_lock); -} - -void audio_allow_sleep(void) -{ - mutex_lock(&idlecount_lock); - if (--idlecount == 0) { - pm_qos_update_request(&pm_qos_req, PM_QOS_DEFAULT_VALUE); - wake_unlock(&wakelock); - } - mutex_unlock(&idlecount_lock); -} - -static struct clk *icodec_rx_clk; -static struct clk *icodec_tx_clk; -static struct clk *ecodec_clk; -static struct clk *sdac_clk; - -static struct q6audio_analog_ops default_analog_ops; -static struct q6audio_analog_ops *analog_ops = &default_analog_ops; -static uint32_t tx_clk_freq = 8000; -static int tx_mute_status = 0; -static int rx_vol_level = 100; -static uint32_t tx_acdb = 0; -static uint32_t rx_acdb = 0; - -void q6audio_register_analog_ops(struct q6audio_analog_ops *ops) -{ - analog_ops = ops; -} - -static struct q6_device_info *q6_lookup_device(uint32_t device_id, - uint32_t acdb_id) -{ - struct q6_device_info *di = q6_audio_devices; - - pr_debug("[%s:%s] device_id = 0x%x, acdb_id = %d\n", __MM_FILE__, - __func__, device_id, acdb_id); - if (acdb_id) { - for (;;) { - if (di->cad_id == acdb_id && di->id == device_id) - return di; - if (di->id == 0) { - pr_err("[%s:%s] bogus id 0x%08x\n", - __MM_FILE__, __func__, device_id); - return di; - } - di++; - } - } else { - for (;;) { - if (di->id == device_id) - return di; - if (di->id == 0) { - pr_err("[%s:%s] bogus id 0x%08x\n", - __MM_FILE__, __func__, device_id); - return di; - } - di++; - } - } -} - -static uint32_t q6_device_to_codec(uint32_t device_id) -{ - struct q6_device_info *di = q6_lookup_device(device_id, 0); - return di->codec; -} - -static uint32_t q6_device_to_dir(uint32_t device_id) -{ - struct q6_device_info *di = q6_lookup_device(device_id, 0); - return di->dir; -} - -static uint32_t q6_device_to_cad_id(uint32_t device_id) -{ - struct q6_device_info *di = q6_lookup_device(device_id, 0); - return di->cad_id; -} - -static uint32_t q6_device_to_path(uint32_t device_id, uint32_t acdb_id) -{ - struct q6_device_info *di = q6_lookup_device(device_id, acdb_id); - return di->path; -} - -static uint32_t q6_device_to_rate(uint32_t device_id) -{ - struct q6_device_info *di = q6_lookup_device(device_id, 0); - return di->rate; -} - -int q6_device_volume(uint32_t device_id, int level) -{ - struct q6_device_info *di = q6_lookup_device(device_id, 0); - struct q6_hw_info *hw; - - hw = &q6_audio_hw[di->hw]; - - return hw->min_gain + ((hw->max_gain - hw->min_gain) * level) / 100; -} - -static inline int adie_open(struct dal_client *client) -{ - pr_debug("[%s:%s]\n", __MM_FILE__, __func__); - return dal_call_f0(client, DAL_OP_OPEN, 0); -} - -static inline int adie_close(struct dal_client *client) -{ - pr_debug("[%s:%s]\n", __MM_FILE__, __func__); - return dal_call_f0(client, DAL_OP_CLOSE, 0); -} - -static inline int adie_set_path(struct dal_client *client, - uint32_t id, uint32_t path_type) -{ - pr_debug("[%s:%s] id = 0x%x, path_type = %d\n", __MM_FILE__, - __func__, id, path_type); - return dal_call_f1(client, ADIE_OP_SET_PATH, id, path_type); -} - -static inline int adie_set_path_freq_plan(struct dal_client *client, - uint32_t path_type, uint32_t plan) -{ - pr_debug("[%s:%s] path_type = %d, plan = %d\n", __MM_FILE__, - __func__, path_type, plan); - return dal_call_f1(client, ADIE_OP_SET_PATH_FREQUENCY_PLAN, - path_type, plan); -} - -static inline int adie_proceed_to_stage(struct dal_client *client, - uint32_t path_type, uint32_t stage) -{ - pr_debug("[%s:%s] path_type = %d, stage = 0x%x\n", __MM_FILE__, - __func__, path_type, stage); - return dal_call_f1(client, ADIE_OP_PROCEED_TO_STAGE, - path_type, stage); -} - -static inline int adie_mute_path(struct dal_client *client, - uint32_t path_type, uint32_t mute_state) -{ - pr_debug("[%s:%s] path_type = %d, mute = %d\n", __MM_FILE__, __func__, - path_type, mute_state); - return dal_call_f1(client, ADIE_OP_MUTE_PATH, path_type, mute_state); -} - -static int adie_refcount; - -static struct dal_client *adie; -static struct dal_client *adsp; -static struct dal_client *acdb; - -static int adie_enable(void) -{ - adie_refcount++; - if (adie_refcount == 1) - adie_open(adie); - return 0; -} - -static int adie_disable(void) -{ - adie_refcount--; - if (adie_refcount == 0) - adie_close(adie); - return 0; -} - -/* 4k PMEM used for exchanging acdb device config tables - * and stream format descriptions with the DSP. - */ -static char *audio_data; -static int32_t audio_phys; - -#define SESSION_MIN 0 -#define SESSION_MAX 64 - -static DEFINE_MUTEX(session_lock); -static DEFINE_MUTEX(audio_lock); - -static struct audio_client *session[SESSION_MAX]; - -static int session_alloc(struct audio_client *ac) -{ - int n; - - mutex_lock(&session_lock); - for (n = SESSION_MIN; n < SESSION_MAX; n++) { - if (!session[n]) { - session[n] = ac; - mutex_unlock(&session_lock); - pr_debug("[%s:%s] session = %d\n", __MM_FILE__, - __func__, n); - return n; - } - } - mutex_unlock(&session_lock); - return -ENOMEM; -} - -static void session_free(int n, struct audio_client *ac) -{ - mutex_lock(&session_lock); - if (session[n] == ac) { - session[n] = 0; - pr_debug("[%s:%s] session = %d\n", __MM_FILE__, __func__, n); - } - mutex_unlock(&session_lock); -} - -static void audio_client_free(struct audio_client *ac) -{ - pr_debug("[%s:%s] ac = %p\n", __MM_FILE__, __func__, ac); - session_free(ac->session, ac); - - if (ac->buf[0].data) { - iounmap(ac->buf[0].data); - pmem_kfree(ac->buf[0].phys); - } - if (ac->buf[1].data) { - iounmap(ac->buf[1].data); - pmem_kfree(ac->buf[1].phys); - } - kfree(ac); -} - -static struct audio_client *audio_client_alloc(unsigned bufsz) -{ - struct audio_client *ac; - int n; - - pr_debug("[%s:%s] bufsz = %d\n", __MM_FILE__, __func__, bufsz); - ac = kzalloc(sizeof(*ac), GFP_KERNEL); - if (!ac) - return 0; - - n = session_alloc(ac); - if (n < 0) - goto fail_session; - ac->session = n; - - if (bufsz > 0) { - ac->buf[0].phys = pmem_kalloc(bufsz, - PMEM_MEMTYPE_EBI1|PMEM_ALIGNMENT_4K); - ac->buf[0].data = ioremap(ac->buf[0].phys, bufsz); - if (!ac->buf[0].data) - goto fail; - ac->buf[1].phys = pmem_kalloc(bufsz, - PMEM_MEMTYPE_EBI1|PMEM_ALIGNMENT_4K); - ac->buf[1].data = ioremap(ac->buf[1].phys, bufsz); - if (!ac->buf[1].data) - goto fail; - - ac->buf[0].size = bufsz; - ac->buf[1].size = bufsz; - } - - init_waitqueue_head(&ac->wait); - ac->client = adsp; - - return ac; - -fail: - session_free(n, ac); -fail_session: - audio_client_free(ac); - return 0; -} - -void audio_client_dump(struct audio_client *ac) -{ - dal_trace_dump(ac->client); -} - -static int audio_ioctl(struct audio_client *ac, void *ptr, uint32_t len) -{ - struct adsp_command_hdr *hdr = ptr; - uint32_t tmp; - int r; - - hdr->size = len - sizeof(u32); - hdr->dst = AUDIO_ADDR(ac->session, 0, AUDIO_DOMAIN_DSP); - hdr->src = AUDIO_ADDR(ac->session, 0, AUDIO_DOMAIN_APP); - hdr->context = ac->session; - ac->cb_status = -EBUSY; - r = dal_call(ac->client, AUDIO_OP_CONTROL, 5, ptr, len, &tmp, sizeof(tmp)); - if (r != 4) - return -EIO; - if (!wait_event_timeout(ac->wait, (ac->cb_status != -EBUSY), 5*HZ)) { - dal_trace_dump(ac->client); - pr_err("[%s:%s] timeout. dsp dead?\n", __MM_FILE__, __func__); - q6audio_dsp_not_responding(); - } - return ac->cb_status; -} - -static int audio_command(struct audio_client *ac, uint32_t cmd) -{ - struct adsp_command_hdr rpc; - memset(&rpc, 0, sizeof(rpc)); - rpc.opcode = cmd; - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -static int audio_open_control(struct audio_client *ac) -{ - struct adsp_open_command rpc; - - pr_debug("[%s:%s] ac = %p\n", __MM_FILE__, __func__, ac); - memset(&rpc, 0, sizeof(rpc)); - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_DEVICE; - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -static int audio_out_open(struct audio_client *ac, uint32_t bufsz, - uint32_t rate, uint32_t channels) -{ - struct adsp_open_command rpc; - - memset(&rpc, 0, sizeof(rpc)); - - rpc.format.standard.format = ADSP_AUDIO_FORMAT_PCM; - rpc.format.standard.channels = channels; - rpc.format.standard.bits_per_sample = 16; - rpc.format.standard.sampling_rate = rate; - rpc.format.standard.is_signed = 1; - rpc.format.standard.is_interleaved = 1; - - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_WRITE; - rpc.device = ADSP_AUDIO_DEVICE_ID_DEFAULT; - rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_PLAYBACK; - rpc.buf_max_size = bufsz; - - pr_debug("[%s:%s]ac = %p\n", __MM_FILE__, __func__, ac); - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -static int audio_in_open(struct audio_client *ac, uint32_t bufsz, - uint32_t flags, uint32_t rate, uint32_t channels) -{ - struct adsp_open_command rpc; - - memset(&rpc, 0, sizeof(rpc)); - - rpc.format.standard.format = ADSP_AUDIO_FORMAT_PCM; - rpc.format.standard.channels = channels; - rpc.format.standard.bits_per_sample = 16; - rpc.format.standard.sampling_rate = rate; - rpc.format.standard.is_signed = 1; - rpc.format.standard.is_interleaved = 1; - - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_READ; - rpc.device = ADSP_AUDIO_DEVICE_ID_DEFAULT; - if (flags == AUDIO_FLAG_READ) - rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_RECORD; - else - rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_MIXED_RECORD; - - rpc.buf_max_size = bufsz; - - pr_debug("[%s:%s] ac = %p\n", __MM_FILE__, __func__, ac); - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -static int audio_auxpcm_out_open(struct audio_client *ac, - uint32_t rate, uint32_t channels) -{ - struct adsp_open_command rpc; - - memset(&rpc, 0, sizeof(rpc)); - - rpc.format.standard.format = ADSP_AUDIO_FORMAT_PCM; - rpc.format.standard.channels = channels; - rpc.format.standard.bits_per_sample = 16; - rpc.format.standard.sampling_rate = rate; - rpc.format.standard.is_signed = 1; - rpc.format.standard.is_interleaved = 1; - - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_READ; - rpc.device = ADSP_AUDIO_DEVICE_ID_DEFAULT; - rpc.mode = ADSP_AUDIO_OPEN_STREAM_MODE_AUX_PCM; - rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_RECORD; - - pr_debug("[%s:%s] ac = %p\n", __MM_FILE__, __func__, ac); - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -static int audio_auxpcm_in_open(struct audio_client *ac, uint32_t rate, - uint32_t channels) -{ - struct adsp_open_command rpc; - - memset(&rpc, 0, sizeof(rpc)); - - rpc.format.standard.format = ADSP_AUDIO_FORMAT_PCM; - rpc.format.standard.channels = channels; - rpc.format.standard.bits_per_sample = 16; - rpc.format.standard.sampling_rate = rate; - rpc.format.standard.is_signed = 1; - rpc.format.standard.is_interleaved = 1; - - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_WRITE; - rpc.device = ADSP_AUDIO_DEVICE_ID_DEFAULT; - rpc.mode = ADSP_AUDIO_OPEN_STREAM_MODE_AUX_PCM; - rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_PLAYBACK; - - pr_debug("[%s:%s] ac = %p\n", __MM_FILE__, __func__, ac); - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -static int audio_mp3_open(struct audio_client *ac, uint32_t bufsz, - uint32_t rate, uint32_t channels) -{ - struct adsp_open_command rpc; - - memset(&rpc, 0, sizeof(rpc)); - - rpc.format.standard.format = ADSP_AUDIO_FORMAT_MP3; - rpc.format.standard.channels = channels; - rpc.format.standard.bits_per_sample = 16; - rpc.format.standard.sampling_rate = rate; - rpc.format.standard.is_signed = 1; - rpc.format.standard.is_interleaved = 0; - - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_WRITE; - rpc.device = ADSP_AUDIO_DEVICE_ID_DEFAULT; - rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_PLAYBACK; - rpc.buf_max_size = bufsz; - - pr_debug("[%s:%s] ac = %p\n", __MM_FILE__, __func__, ac); - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -static int audio_dtmf_open(struct audio_client *ac, - uint32_t rate, uint32_t channels) -{ - struct adsp_open_command rpc; - - memset(&rpc, 0, sizeof(rpc)); - - rpc.format.standard.format = ADSP_AUDIO_FORMAT_DTMF; - rpc.format.standard.channels = channels; - rpc.format.standard.bits_per_sample = 16; - rpc.format.standard.sampling_rate = rate; - rpc.format.standard.is_signed = 1; - rpc.format.standard.is_interleaved = 0; - - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_WRITE; - rpc.device = ADSP_AUDIO_DEVICE_ID_DEFAULT; - rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_PLAYBACK; - - pr_debug("[%s:%s] ac = %p\n", __MM_FILE__, __func__, ac); - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -static int audio_aac_open(struct audio_client *ac, uint32_t bufsz, - uint32_t sample_rate, uint32_t channels, - uint32_t bit_rate, uint32_t flags, - uint32_t stream_format) -{ - struct adsp_open_command rpc; - int audio_object_type; - int index = sizeof(u32); - u32 *aac_type = NULL; - - memset(&rpc, 0, sizeof(rpc)); - - rpc.format.binary.format = ADSP_AUDIO_FORMAT_MPEG4_AAC; - /* only 48k sample rate is supported */ - sample_rate = 3; - /* AAC OBJECT LC */ - audio_object_type = 2; - - aac_type = (u32 *)rpc.format.binary.data; - switch (stream_format) { - case AUDIO_AAC_FORMAT_ADTS: - /* AAC Encoder expect MPEG4_ADTS media type */ - *aac_type = ADSP_AUDIO_AAC_MPEG4_ADTS; - break; - case AUDIO_AAC_FORMAT_RAW: - /* for ADIF recording */ - *aac_type = ADSP_AUDIO_AAC_RAW; - break; - } - - rpc.format.binary.data[index++] = (u8)( - ((audio_object_type & 0x1F) << 3) | - ((sample_rate >> 1) & 0x7)); - rpc.format.binary.data[index] = (u8)( - ((sample_rate & 0x1) << 7) | - ((channels & 0x7) << 3)); - rpc.format.binary.num_bytes = index + 1; - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_READ; - rpc.device = ADSP_AUDIO_DEVICE_ID_DEFAULT; - - if (flags == AUDIO_FLAG_READ) - rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_RECORD; - else - rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_MIXED_RECORD; - - rpc.buf_max_size = bufsz; - rpc.config.aac.bit_rate = bit_rate; - rpc.config.aac.encoder_mode = ADSP_AUDIO_ENC_AAC_LC_ONLY_MODE; - pr_debug("[%s:%s] ac = %p\n", __MM_FILE__, __func__, ac); - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -static int audio_qcp_open(struct audio_client *ac, uint32_t bufsz, - uint32_t min_rate, uint32_t max_rate, - uint32_t flags, uint32_t format) -{ - struct adsp_open_command rpc; - - memset(&rpc, 0, sizeof(rpc)); - - rpc.format.standard.format = format; - rpc.format.standard.channels = 1; - rpc.format.standard.bits_per_sample = 16; - rpc.format.standard.sampling_rate = 8000; - rpc.format.standard.is_signed = 1; - rpc.format.standard.is_interleaved = 0; - - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_READ; - rpc.device = ADSP_AUDIO_DEVICE_ID_DEFAULT; - - if (flags == AUDIO_FLAG_READ) - rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_RECORD; - else - rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_MIXED_RECORD; - rpc.buf_max_size = bufsz; - rpc.config.evrc.min_rate = min_rate; - rpc.config.evrc.max_rate = max_rate; - - pr_debug("[%s:%s] ac = %p\n", __MM_FILE__, __func__, ac); - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -static int audio_amrnb_open(struct audio_client *ac, uint32_t bufsz, - uint32_t enc_mode, uint32_t flags, - uint32_t dtx_enable) -{ - struct adsp_open_command rpc; - - memset(&rpc, 0, sizeof(rpc)); - - rpc.format.standard.format = ADSP_AUDIO_FORMAT_AMRNB_FS; - rpc.format.standard.channels = 1; - rpc.format.standard.bits_per_sample = 16; - rpc.format.standard.sampling_rate = 8000; - rpc.format.standard.is_signed = 1; - rpc.format.standard.is_interleaved = 0; - - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_OPEN_READ; - rpc.device = ADSP_AUDIO_DEVICE_ID_DEFAULT; - - if (flags == AUDIO_FLAG_READ) - rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_RECORD; - else - rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_MIXED_RECORD; - - rpc.buf_max_size = bufsz; - rpc.config.amr.mode = enc_mode; - rpc.config.amr.dtx_mode = dtx_enable; - rpc.config.amr.enable = 1; - - pr_debug("[%s:%s] ac = %p\n", __MM_FILE__, __func__, ac); - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - - - -static int audio_close(struct audio_client *ac) -{ - pr_debug("[%s:%s] ac = %p\n", __MM_FILE__, __func__, ac); - audio_command(ac, ADSP_AUDIO_IOCTL_CMD_STREAM_STOP); - audio_command(ac, ADSP_AUDIO_IOCTL_CMD_CLOSE); - return 0; -} - -static int audio_set_table(struct audio_client *ac, - uint32_t device_id, int size) -{ - struct adsp_set_dev_cfg_table_command rpc; - - memset(&rpc, 0, sizeof(rpc)); - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_SET_DEVICE_CONFIG_TABLE; - if (q6_device_to_dir(device_id) == Q6_TX) { - if (tx_clk_freq > 16000) - rpc.hdr.data = 48000; - else if (tx_clk_freq > 8000) - rpc.hdr.data = 16000; - else - rpc.hdr.data = 8000; - } - rpc.device_id = device_id; - rpc.phys_addr = audio_phys; - rpc.phys_size = size; - rpc.phys_used = size; - - pr_debug("[%s:%s] ac = %p, device_id = 0x%x, size = %d\n", __MM_FILE__, - __func__, ac, device_id, size); - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -int q6audio_read(struct audio_client *ac, struct audio_buffer *ab) -{ - struct adsp_buffer_command rpc; - uint32_t res; - int r; - - memset(&rpc, 0, sizeof(rpc)); - rpc.hdr.size = sizeof(rpc) - sizeof(u32); - rpc.hdr.dst = AUDIO_ADDR(ac->session, 0, AUDIO_DOMAIN_DSP); - rpc.hdr.src = AUDIO_ADDR(ac->session, 0, AUDIO_DOMAIN_APP); - rpc.hdr.context = ac->session; - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_DATA_TX; - rpc.buffer.addr = ab->phys; - rpc.buffer.max_size = ab->size; - rpc.buffer.actual_size = ab->actual_size; - - pr_debug("[%s:%s] ac = %p\n", __MM_FILE__, __func__, ac); - r = dal_call(ac->client, AUDIO_OP_DATA, 5, &rpc, sizeof(rpc), - &res, sizeof(res)); - return 0; -} - -int q6audio_write(struct audio_client *ac, struct audio_buffer *ab) -{ - struct adsp_buffer_command rpc; - uint32_t res; - int r; - - memset(&rpc, 0, sizeof(rpc)); - rpc.hdr.size = sizeof(rpc) - sizeof(u32); - rpc.hdr.dst = AUDIO_ADDR(ac->session, 0, AUDIO_DOMAIN_DSP); - rpc.hdr.src = AUDIO_ADDR(ac->session, 0, AUDIO_DOMAIN_APP); - rpc.hdr.context = ac->session; - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_DATA_RX; - rpc.buffer.addr = ab->phys; - rpc.buffer.max_size = ab->size; - rpc.buffer.actual_size = ab->actual_size; - - pr_debug("[%s:%s] ac = %p\n", __MM_FILE__, __func__, ac); - r = dal_call(ac->client, AUDIO_OP_DATA, 5, &rpc, sizeof(rpc), - &res, sizeof(res)); - return 0; -} - -static int audio_rx_volume(struct audio_client *ac, uint32_t dev_id, int32_t volume) -{ - struct adsp_set_dev_volume_command rpc; - - pr_debug("[%s:%s] volume = %d\n", __MM_FILE__, __func__, volume); - memset(&rpc, 0, sizeof(rpc)); - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_SET_DEVICE_VOL; - rpc.device_id = dev_id; - rpc.path = ADSP_PATH_RX; - rpc.volume = volume; - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -static int audio_rx_mute(struct audio_client *ac, uint32_t dev_id, int mute) -{ - struct adsp_set_dev_mute_command rpc; - - pr_debug("[%s:%s] mute = %d, dev_id = 0x%x\n", __MM_FILE__, - __func__, mute, dev_id); - memset(&rpc, 0, sizeof(rpc)); - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_SET_DEVICE_MUTE; - rpc.device_id = dev_id; - rpc.path = ADSP_PATH_RX; - rpc.mute = !!mute; - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -static int audio_tx_mute(struct audio_client *ac, uint32_t dev_id, int mute) -{ - struct adsp_set_dev_mute_command rpc; - - pr_debug("[%s:%s] mute = %d\n", __MM_FILE__, __func__, mute); - if (mute < 0 || mute > 3) { - pr_err("[%s:%s] invalid mute status %d\n", __MM_FILE__, - __func__, mute); - return -EINVAL; - } - - memset(&rpc, 0, sizeof(rpc)); - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_SET_DEVICE_MUTE; - if ((mute == STREAM_UNMUTE) || (mute == STREAM_MUTE)) { - rpc.device_id = ADSP_AUDIO_DEVICE_ID_VOICE; - rpc.path = ADSP_PATH_TX_CNG_DIS; - } else { - rpc.device_id = dev_id; - rpc.path = ADSP_PATH_TX; - } - mute &= 0x01; - rpc.mute = !!mute; - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -static int audio_stream_volume(struct audio_client *ac, int volume) -{ - struct adsp_set_volume_command rpc; - int rc; - - pr_debug("[%s:%s] volume = %d\n", __MM_FILE__, __func__, volume); - memset(&rpc, 0, sizeof(rpc)); - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_SET_STREAM_VOL; - rpc.volume = volume; - rc = audio_ioctl(ac, &rpc, sizeof(rpc)); - return rc; -} - -static int audio_stream_mute(struct audio_client *ac, int mute) -{ - struct adsp_set_mute_command rpc; - int rc; - - pr_debug("[%s:%s] mute = %d\n", __MM_FILE__, __func__, mute); - memset(&rpc, 0, sizeof(rpc)); - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_SET_STREAM_MUTE; - rpc.mute = mute; - rc = audio_ioctl(ac, &rpc, sizeof(rpc)); - return rc; -} - -static void callback(void *data, int len, void *cookie) -{ - struct adsp_event_hdr *e = data; - struct audio_client *ac; - struct adsp_buffer_event *abe = data; - - if (e->context >= SESSION_MAX) { - pr_err("[%s:%s] bogus session %d\n", __MM_FILE__, __func__, - e->context); - return; - } - ac = session[e->context]; - if (!ac) { - pr_err("[%s:%s] unknown session %d\n", __MM_FILE__, __func__, - e->context); - return; - } - - if (e->event_id == ADSP_AUDIO_IOCTL_CMD_STREAM_EOS) { - pr_debug("[%s:%s] CB Stream eos, ac = %p\n", - __MM_FILE__, __func__, ac); - if (e->status) - pr_err("[%s:%s] playback status %d\n", __MM_FILE__, - __func__, e->status); - if (ac->cb_status == -EBUSY) { - ac->cb_status = e->status; - wake_up(&ac->wait); - } - return; - } - - if (e->event_id == ADSP_AUDIO_EVT_STATUS_BUF_DONE) { - pr_debug("[%s:%s] CB done, ac = %p, status = %d\n", - __MM_FILE__, __func__, ac, e->status); - if (e->status) - pr_err("[%s:%s] buffer status %d\n", __MM_FILE__, - __func__, e->status); - - ac->buf[ac->dsp_buf].actual_size = abe->buffer.actual_size; - ac->buf[ac->dsp_buf].used = 0; - ac->dsp_buf ^= 1; - wake_up(&ac->wait); - return; - } - - pr_debug("[%s:%s] ac = %p, event_id = 0x%x, status = %d\n", - __MM_FILE__, __func__, ac, e->event_id, e->status); - if (e->status) - pr_warning("audio_cb: s=%d e=%08x status=%d\n", - e->context, e->event_id, e->status); - if (ac->cb_status == -EBUSY) { - ac->cb_status = e->status; - wake_up(&ac->wait); - } -} - -static void audio_init(struct dal_client *client) -{ - u32 tmp[3]; - - pr_debug("[%s:%s]\n", __MM_FILE__, __func__); - tmp[0] = 2 * sizeof(u32); - tmp[1] = 0; - tmp[2] = 0; - dal_call(client, AUDIO_OP_INIT, 5, tmp, sizeof(tmp), - tmp, sizeof(u32)); -} - -static struct audio_client *ac_control; - -static int q6audio_init(void) -{ - struct audio_client *ac = 0; - int res; - - pr_debug("[%s:%s]\n", __MM_FILE__, __func__); - mutex_lock(&audio_lock); - if (ac_control) { - res = 0; - goto done; - } - - pr_info("[%s:%s] codecs\n", __MM_FILE__, __func__); - icodec_rx_clk = clk_get(0, "icodec_rx_clk"); - icodec_tx_clk = clk_get(0, "icodec_tx_clk"); - ecodec_clk = clk_get(0, "ecodec_clk"); - sdac_clk = clk_get(0, "sdac_clk"); - audio_phys = pmem_kalloc(4096, PMEM_MEMTYPE_EBI1|PMEM_ALIGNMENT_4K); - audio_data = ioremap(audio_phys, 4096); - - pr_info("[%s:%s] attach ADSP\n", __MM_FILE__, __func__); - adsp = dal_attach(AUDIO_DAL_DEVICE, AUDIO_DAL_PORT, 1, - callback, 0); - if (!adsp) { - pr_err("[%s:%s] cannot attach to adsp\n", __MM_FILE__, - __func__); - res = -ENODEV; - goto done; - } - pr_info("[%s:%s] INIT\n", __MM_FILE__, __func__); - audio_init(adsp); - dal_trace(adsp); - - ac = audio_client_alloc(0); - if (!ac) { - pr_err("[%s:%s] cannot allocate client\n", - __MM_FILE__, __func__); - res = -ENOMEM; - goto done; - } - - pr_info("[%s:%s] OPEN control\n", __MM_FILE__, __func__); - if (audio_open_control(ac)) { - pr_err("[%s:%s] cannot open control channel\n", - __MM_FILE__, __func__); - res = -ENODEV; - goto done; - } - - pr_info("[%s:%s] attach ACDB\n", __MM_FILE__, __func__); - acdb = dal_attach(ACDB_DAL_DEVICE, ACDB_DAL_PORT, 0, 0, 0); - if (!acdb) { - pr_err("[%s:%s] cannot attach to acdb channel\n", - __MM_FILE__, __func__); - res = -ENODEV; - goto done; - } - - pr_info("[%s:%s] attach ADIE\n", __MM_FILE__, __func__); - adie = dal_attach(ADIE_DAL_DEVICE, ADIE_DAL_PORT, 0, 0, 0); - if (!adie) { - pr_err("[%s:%s] cannot attach to adie\n", - __MM_FILE__, __func__); - res = -ENODEV; - goto done; - } - if (analog_ops->init) - analog_ops->init(); - - res = 0; - ac_control = ac; - - pm_qos_add_request(&pm_qos_req, PM_QOS_CPU_DMA_LATENCY, - PM_QOS_DEFAULT_VALUE); - wake_lock_init(&wakelock, WAKE_LOCK_SUSPEND, "audio_pcm_suspend"); -done: - if ((res < 0) && ac) - audio_client_free(ac); - mutex_unlock(&audio_lock); - - pr_debug("[%s:%s] res = %d\n", __MM_FILE__, __func__, res); - return res; -} - -struct audio_config_data { - uint32_t device_id; - uint32_t sample_rate; - uint32_t offset; - uint32_t length; -}; - -struct audio_config_database { - uint8_t magic[8]; - uint32_t entry_count; - uint32_t unused; - struct audio_config_data entry[0]; -}; - -void *acdb_data; -const struct firmware *acdb_fw; -extern struct miscdevice q6_control_device; - -static int acdb_get_config_table(uint32_t device_id, uint32_t sample_rate) -{ - struct acdb_cmd_device_table rpc; - struct acdb_result res; - int r; - - pr_debug("[%s:%s] device_id = 0x%x, samplerate = %d\n", __MM_FILE__, - __func__, device_id, sample_rate); - if (q6audio_init()) - return 0; - - memset(audio_data, 0, 4096); - memset(&rpc, 0, sizeof(rpc)); - - rpc.size = sizeof(rpc) - (2 * sizeof(uint32_t)); - rpc.command_id = ACDB_GET_DEVICE_TABLE; - rpc.device_id = device_id; - rpc.sample_rate_id = sample_rate; - rpc.total_bytes = 4096; - rpc.unmapped_buf = audio_phys; - rpc.res_size = sizeof(res) - (2 * sizeof(uint32_t)); - - r = dal_call(acdb, ACDB_OP_IOCTL, 8, &rpc, sizeof(rpc), - &res, sizeof(res)); - - if ((r == sizeof(res)) && (res.dal_status == 0)) - return res.used_bytes; - - return -EIO; -} - -static uint32_t audio_rx_path_id = ADIE_PATH_HANDSET_RX; -static uint32_t audio_rx_device_id = ADSP_AUDIO_DEVICE_ID_HANDSET_SPKR; -static uint32_t audio_rx_device_group = -1; -static uint32_t audio_tx_path_id = ADIE_PATH_HANDSET_TX; -static uint32_t audio_tx_device_id = ADSP_AUDIO_DEVICE_ID_HANDSET_MIC; -static uint32_t audio_tx_device_group = -1; - -static int qdsp6_devchg_notify(struct audio_client *ac, - uint32_t dev_type, uint32_t dev_id) -{ - struct adsp_device_switch_command rpc; - - if (dev_type != ADSP_AUDIO_RX_DEVICE && - dev_type != ADSP_AUDIO_TX_DEVICE) - return -EINVAL; - - memset(&rpc, 0, sizeof(rpc)); - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_DEVICE_SWITCH_PREPARE; - if (dev_type == ADSP_AUDIO_RX_DEVICE) { - rpc.old_device = audio_rx_device_id; - rpc.new_device = dev_id; - } else { - rpc.old_device = audio_tx_device_id; - rpc.new_device = dev_id; - } - rpc.device_class = 0; - rpc.device_type = dev_type; - pr_debug("[%s:%s] dev_id = 0x%x\n", __MM_FILE__, __func__, dev_id); - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -static int qdsp6_standby(struct audio_client *ac) -{ - pr_debug("[%s:%s]\n", __MM_FILE__, __func__); - return audio_command(ac, ADSP_AUDIO_IOCTL_CMD_DEVICE_SWITCH_STANDBY); -} - -static int qdsp6_start(struct audio_client *ac) -{ - pr_debug("[%s:%s]\n", __MM_FILE__, __func__); - return audio_command(ac, ADSP_AUDIO_IOCTL_CMD_DEVICE_SWITCH_COMMIT); -} - -static void audio_rx_analog_enable(int en) -{ - pr_debug("[%s:%s] audio_rx_device_id = 0x%x, en = %d\n", __MM_FILE__, - __func__, audio_rx_device_id, en); - switch (audio_rx_device_id) { - case ADSP_AUDIO_DEVICE_ID_HEADSET_SPKR_MONO: - case ADSP_AUDIO_DEVICE_ID_HEADSET_SPKR_STEREO: - case ADSP_AUDIO_DEVICE_ID_TTY_HEADSET_SPKR: - if (analog_ops->headset_enable) - analog_ops->headset_enable(en); - break; - case ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO_W_MONO_HEADSET: - case ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO_W_STEREO_HEADSET: - case ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO_W_MONO_HEADSET: - case ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO_W_STEREO_HEADSET: - if (analog_ops->headset_enable) - analog_ops->headset_enable(en); - if (analog_ops->speaker_enable) - analog_ops->speaker_enable(en); - break; - case ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO: - case ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO: - if (analog_ops->speaker_enable) - analog_ops->speaker_enable(en); - break; - case ADSP_AUDIO_DEVICE_ID_BT_SCO_SPKR: - if (analog_ops->bt_sco_enable) - analog_ops->bt_sco_enable(en); - break; - case ADSP_AUDIO_DEVICE_ID_HANDSET_SPKR: - if (analog_ops->receiver_enable) - analog_ops->receiver_enable(en); - break; - } -} - -static void audio_tx_analog_enable(int en) -{ - pr_debug("[%s:%s] audio_tx_device_id = 0x%x, en = %d\n", __MM_FILE__, - __func__, audio_tx_device_id, en); - switch (audio_tx_device_id) { - case ADSP_AUDIO_DEVICE_ID_HANDSET_MIC: - case ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MIC: - if (analog_ops->int_mic_enable) - analog_ops->int_mic_enable(en); - break; - case ADSP_AUDIO_DEVICE_ID_HEADSET_MIC: - case ADSP_AUDIO_DEVICE_ID_TTY_HEADSET_MIC: - case ADSP_AUDIO_DEVICE_ID_HANDSET_DUAL_MIC: - case ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_DUAL_MIC: - if (analog_ops->ext_mic_enable) - analog_ops->ext_mic_enable(en); - break; - case ADSP_AUDIO_DEVICE_ID_BT_SCO_MIC: - if (analog_ops->bt_sco_enable) - analog_ops->bt_sco_enable(en); - break; - } -} - -static int audio_update_acdb(uint32_t adev, uint32_t acdb_id) -{ - uint32_t sample_rate; - int sz; - - pr_debug("[%s:%s] adev = 0x%x, acdb_id = 0x%x\n", __MM_FILE__, - __func__, adev, acdb_id); - if (q6_device_to_dir(adev) == Q6_RX) { - rx_acdb = acdb_id; - sample_rate = q6_device_to_rate(adev); - } else { - - tx_acdb = acdb_id; - if (tx_clk_freq > 16000) - sample_rate = 48000; - else if (tx_clk_freq > 8000) - sample_rate = 16000; - else - sample_rate = 8000; - } - - if (acdb_id == 0) - acdb_id = q6_device_to_cad_id(adev); - - sz = acdb_get_config_table(acdb_id, sample_rate); - audio_set_table(ac_control, adev, sz); - - return 0; -} - -static void adie_rx_path_enable(uint32_t acdb_id) -{ - pr_debug("[%s:%s]\n", __MM_FILE__, __func__); - if (audio_rx_path_id) { - adie_enable(); - adie_set_path(adie, audio_rx_path_id, ADIE_PATH_RX); - adie_set_path_freq_plan(adie, ADIE_PATH_RX, 48000); - - adie_proceed_to_stage(adie, ADIE_PATH_RX, - ADIE_STAGE_DIGITAL_READY); - adie_proceed_to_stage(adie, ADIE_PATH_RX, - ADIE_STAGE_DIGITAL_ANALOG_READY); - } -} - -static void q6_rx_path_enable(int reconf, uint32_t acdb_id) -{ - pr_debug("[%s:%s]\n", __MM_FILE__, __func__); - if (!reconf) - qdsp6_devchg_notify(ac_control, ADSP_AUDIO_RX_DEVICE, audio_rx_device_id); - audio_update_acdb(audio_rx_device_id, acdb_id); - qdsp6_standby(ac_control); - qdsp6_start(ac_control); -} - -static void _audio_rx_path_enable(int reconf, uint32_t acdb_id) -{ - pr_debug("[%s:%s] reconf = %d\n", __MM_FILE__, __func__, reconf); - q6_rx_path_enable(reconf, acdb_id); - if (audio_rx_path_id) - adie_rx_path_enable(acdb_id); - audio_rx_analog_enable(1); -} - -static void _audio_tx_path_enable(int reconf, uint32_t acdb_id) -{ - pr_debug("[%s:%s] reconf = %d, tx_clk_freq = %d\n", __MM_FILE__, - __func__, reconf, tx_clk_freq); - audio_tx_analog_enable(1); - - if (audio_tx_path_id) { - adie_enable(); - adie_set_path(adie, audio_tx_path_id, ADIE_PATH_TX); - - if (tx_clk_freq > 16000) - adie_set_path_freq_plan(adie, ADIE_PATH_TX, 48000); - else if (tx_clk_freq > 8000) - adie_set_path_freq_plan(adie, ADIE_PATH_TX, 16000); - else - adie_set_path_freq_plan(adie, ADIE_PATH_TX, 8000); - - adie_proceed_to_stage(adie, ADIE_PATH_TX, - ADIE_STAGE_DIGITAL_READY); - adie_proceed_to_stage(adie, ADIE_PATH_TX, - ADIE_STAGE_DIGITAL_ANALOG_READY); - } - - - if (!reconf) - qdsp6_devchg_notify(ac_control, ADSP_AUDIO_TX_DEVICE, - audio_tx_device_id); - audio_update_acdb(audio_tx_device_id, acdb_id); - qdsp6_standby(ac_control); - qdsp6_start(ac_control); - - audio_tx_mute(ac_control, audio_tx_device_id, tx_mute_status); -} - -static void _audio_rx_path_disable(void) -{ - pr_debug("[%s:%s]\n", __MM_FILE__, __func__); - audio_rx_analog_enable(0); - - if (audio_rx_path_id) { - adie_proceed_to_stage(adie, ADIE_PATH_RX, - ADIE_STAGE_ANALOG_OFF); - adie_proceed_to_stage(adie, ADIE_PATH_RX, - ADIE_STAGE_DIGITAL_OFF); - adie_disable(); - } -} - -static void _audio_tx_path_disable(void) -{ - pr_debug("[%s:%s]\n", __MM_FILE__, __func__); - audio_tx_analog_enable(0); - - if (audio_tx_path_id) { - adie_proceed_to_stage(adie, ADIE_PATH_TX, - ADIE_STAGE_ANALOG_OFF); - adie_proceed_to_stage(adie, ADIE_PATH_TX, - ADIE_STAGE_DIGITAL_OFF); - adie_disable(); - } -} - -static int icodec_rx_clk_refcount; -static int icodec_tx_clk_refcount; -static int ecodec_clk_refcount; -static int sdac_clk_refcount; - -static void ecodec_clk_enable(void) -{ - ecodec_clk_refcount++; - if (ecodec_clk_refcount == 1) { - clk_set_rate(ecodec_clk, 2048000); - clk_enable(ecodec_clk); - } -} -static void ecodec_clk_disable(int group_reset, int path) -{ - ecodec_clk_refcount--; - if (ecodec_clk_refcount == 0) { - clk_disable(ecodec_clk); - if (group_reset) { - if (path == ADSP_PATH_TX) - audio_tx_device_group = -1; - else - audio_rx_device_group = -1; - } - } -} -static void _audio_rx_clk_enable(void) -{ - uint32_t device_group = q6_device_to_codec(audio_rx_device_id); - - pr_debug("[%s:%s] rx_clk_refcount = %d\n", __MM_FILE__, __func__, - icodec_rx_clk_refcount); - switch(device_group) { - case Q6_ICODEC_RX: - icodec_rx_clk_refcount++; - if (icodec_rx_clk_refcount == 1) { - clk_set_rate(icodec_rx_clk, 12288000); - clk_enable(icodec_rx_clk); - } - break; - case Q6_ECODEC_RX: - ecodec_clk_enable(); - break; - case Q6_SDAC_RX: - sdac_clk_refcount++; - if (sdac_clk_refcount == 1) { - clk_set_rate(sdac_clk, 12288000); - clk_enable(sdac_clk); - } - break; - default: - return; - } - audio_rx_device_group = device_group; -} - -static void _audio_tx_clk_enable(void) -{ - uint32_t device_group = q6_device_to_codec(audio_tx_device_id); - uint32_t icodec_tx_clk_rate; - - pr_debug("[%s:%s] tx_clk_refcount = %d\n", __MM_FILE__, __func__, - icodec_tx_clk_refcount); - switch (device_group) { - case Q6_ICODEC_TX: - icodec_tx_clk_refcount++; - if (icodec_tx_clk_refcount == 1) { - if (tx_clk_freq > 16000) - icodec_tx_clk_rate = 48000; - else if (tx_clk_freq > 8000) - icodec_tx_clk_rate = 16000; - else - icodec_tx_clk_rate = 8000; - - clk_set_rate(icodec_tx_clk, icodec_tx_clk_rate * 256); - clk_enable(icodec_tx_clk); - } - break; - case Q6_ECODEC_TX: - ecodec_clk_enable(); - break; - case Q6_SDAC_TX: - /* TODO: In QCT BSP, clk rate was set to 20480000 */ - sdac_clk_refcount++; - if (sdac_clk_refcount == 1) { - clk_set_rate(sdac_clk, 12288000); - clk_enable(sdac_clk); - } - break; - default: - return; - } - audio_tx_device_group = device_group; -} - -static void _audio_rx_clk_disable(void) -{ - pr_debug("[%s:%s] rx_clk_refcount = %d\n", __MM_FILE__, __func__, - icodec_rx_clk_refcount); - switch (audio_rx_device_group) { - case Q6_ICODEC_RX: - icodec_rx_clk_refcount--; - if (icodec_rx_clk_refcount == 0) { - clk_disable(icodec_rx_clk); - audio_rx_device_group = -1; - } - break; - case Q6_ECODEC_RX: - ecodec_clk_disable(1, ADSP_PATH_RX); - break; - case Q6_SDAC_RX: - sdac_clk_refcount--; - if (sdac_clk_refcount == 0) { - clk_disable(sdac_clk); - audio_rx_device_group = -1; - } - break; - default: - pr_err("[%s:%s] invalid rx device group %d\n", __MM_FILE__, - __func__, audio_rx_device_group); - break; - } -} - -static void _audio_tx_clk_disable(void) -{ - pr_debug("[%s:%s] tx_clk_refcount = %d\n", __MM_FILE__, __func__, - icodec_tx_clk_refcount); - switch (audio_tx_device_group) { - case Q6_ICODEC_TX: - icodec_tx_clk_refcount--; - if (icodec_tx_clk_refcount == 0) { - clk_disable(icodec_tx_clk); - audio_tx_device_group = -1; - } - break; - case Q6_ECODEC_TX: - ecodec_clk_disable(1, ADSP_PATH_TX); - break; - case Q6_SDAC_TX: - sdac_clk_refcount--; - if (sdac_clk_refcount == 0) { - clk_disable(sdac_clk); - audio_tx_device_group = -1; - } - break; - default: - pr_err("[%s:%s] invalid tx device group %d\n", - __MM_FILE__, __func__, audio_tx_device_group); - break; - } -} - -static void _audio_rx_clk_reinit(uint32_t rx_device, uint32_t acdb_id) -{ - uint32_t device_group = q6_device_to_codec(rx_device); - - pr_debug("[%s:%s] rx_device = 0x%x\n", __MM_FILE__, __func__, - rx_device); - if (device_group != audio_rx_device_group) - _audio_rx_clk_disable(); - - audio_rx_device_id = rx_device; - audio_rx_path_id = q6_device_to_path(rx_device, acdb_id); - - if (device_group != audio_rx_device_group) - _audio_rx_clk_enable(); - -} - -static void _audio_tx_clk_reinit(uint32_t tx_device, uint32_t acdb_id) -{ - uint32_t device_group = q6_device_to_codec(tx_device); - - pr_debug("[%s:%s] tx_device = 0x%x\n", __MM_FILE__, __func__, - tx_device); - if (device_group != audio_tx_device_group) - _audio_tx_clk_disable(); - - audio_tx_device_id = tx_device; - audio_tx_path_id = q6_device_to_path(tx_device, acdb_id); - - if (device_group != audio_tx_device_group) - _audio_tx_clk_enable(); -} - -static DEFINE_MUTEX(audio_path_lock); -static int audio_rx_path_refcount; -static int audio_tx_path_refcount; - -static int audio_rx_path_enable(int en, uint32_t acdb_id) -{ - pr_debug("[%s:%s] en = %d\n", __MM_FILE__, __func__, en); - mutex_lock(&audio_path_lock); - if (en) { - audio_rx_path_refcount++; - if (audio_rx_path_refcount == 1) { - _audio_rx_clk_enable(); - _audio_rx_path_enable(0, acdb_id); - } - } else { - audio_rx_path_refcount--; - if (audio_rx_path_refcount == 0) { - _audio_rx_path_disable(); - _audio_rx_clk_disable(); - } - } - mutex_unlock(&audio_path_lock); - return 0; -} - -static int audio_tx_path_enable(int en, uint32_t acdb_id) -{ - pr_debug("[%s:%s] en = %d\n", __MM_FILE__, __func__, en); - mutex_lock(&audio_path_lock); - if (en) { - audio_tx_path_refcount++; - if (audio_tx_path_refcount == 1) { - _audio_tx_clk_enable(); - _audio_tx_path_enable(0, acdb_id); - } - } else { - audio_tx_path_refcount--; - if (audio_tx_path_refcount == 0) { - _audio_tx_path_disable(); - _audio_tx_clk_disable(); - } - } - mutex_unlock(&audio_path_lock); - return 0; -} - -int q6audio_update_acdb(uint32_t id_src, uint32_t id_dst) -{ - int res; - - pr_debug("[%s:%s] id_src = 0x%x\n, id_dst = 0x%x\n", __MM_FILE__, - __func__, id_src, id_dst); - if (q6audio_init()) - return 0; - - mutex_lock(&audio_path_lock); - - if (q6_device_to_dir(id_dst) == Q6_RX) - qdsp6_devchg_notify(ac_control, ADSP_AUDIO_RX_DEVICE, id_dst); - else - qdsp6_devchg_notify(ac_control, ADSP_AUDIO_TX_DEVICE, id_dst); - res = audio_update_acdb(id_dst, id_src); - if (res) - goto done; - - qdsp6_standby(ac_control); - qdsp6_start(ac_control); -done: - mutex_unlock(&audio_path_lock); - return res; -} - -int q6audio_set_tx_mute(int mute) -{ - uint32_t adev; - int rc; - - if (q6audio_init()) - return 0; - - mutex_lock(&audio_path_lock); - - if (mute == tx_mute_status) { - mutex_unlock(&audio_path_lock); - return 0; - } - - adev = audio_tx_device_id; - rc = audio_tx_mute(ac_control, adev, mute); - - /* DSP caches the requested MUTE state when it cannot apply the state - immediately. In that case, it returns EUNSUPPORTED and applies the - cached state later */ - if ((rc == ADSP_AUDIO_STATUS_SUCCESS) || - (rc == ADSP_AUDIO_STATUS_EUNSUPPORTED)) { - pr_debug("[%s:%s] return status = %d\n", - __MM_FILE__, __func__, rc); - tx_mute_status = mute; - } - mutex_unlock(&audio_path_lock); - return 0; -} - -int q6audio_set_stream_volume(struct audio_client *ac, int vol) -{ - if (vol > 1200 || vol < -4000) { - pr_err("[%s:%s] unsupported volume level %d\n", __MM_FILE__, - __func__, vol); - return -EINVAL; - } - mutex_lock(&audio_path_lock); - audio_stream_mute(ac, 0); - audio_stream_volume(ac, vol); - mutex_unlock(&audio_path_lock); - return 0; -} - -int q6audio_set_rx_volume(int level) -{ - uint32_t adev; - int vol; - - pr_debug("[%s:%s] level = %d\n", __MM_FILE__, __func__, level); - if (q6audio_init()) - return 0; - - if (level < 0 || level > 100) - return -EINVAL; - - mutex_lock(&audio_path_lock); - adev = ADSP_AUDIO_DEVICE_ID_VOICE; - - if (level) { - vol = q6_device_volume(audio_rx_device_id, level); - audio_rx_mute(ac_control, adev, 0); - audio_rx_volume(ac_control, adev, vol); - } else - audio_rx_mute(ac_control, adev, 1); - - rx_vol_level = level; - mutex_unlock(&audio_path_lock); - return 0; -} - -static void do_rx_routing(uint32_t device_id, uint32_t acdb_id) -{ - pr_debug("[%s:%s] device_id = 0x%x, acdb_id = 0x%x\n", __MM_FILE__, - __func__, device_id, acdb_id); - if (device_id == audio_rx_device_id && - audio_rx_path_id == q6_device_to_path(device_id, acdb_id)) { - if (acdb_id != rx_acdb) { - qdsp6_devchg_notify(ac_control, ADSP_AUDIO_RX_DEVICE, device_id); - audio_update_acdb(device_id, acdb_id); - qdsp6_standby(ac_control); - qdsp6_start(ac_control); - } - return; - } - - if (audio_rx_path_refcount > 0) { - qdsp6_devchg_notify(ac_control, ADSP_AUDIO_RX_DEVICE, device_id); - _audio_rx_path_disable(); - _audio_rx_clk_reinit(device_id, acdb_id); - _audio_rx_path_enable(1, acdb_id); - } else { - qdsp6_devchg_notify(ac_control, ADSP_AUDIO_RX_DEVICE, - device_id); - audio_update_acdb(device_id, acdb_id); - qdsp6_standby(ac_control); - qdsp6_start(ac_control); - audio_rx_device_id = device_id; - audio_rx_path_id = q6_device_to_path(device_id, acdb_id); - } -} - -static void do_tx_routing(uint32_t device_id, uint32_t acdb_id) -{ - pr_debug("[%s:%s] device_id = 0x%x, acdb_id = 0x%x\n", __MM_FILE__, - __func__, device_id, acdb_id); - if (device_id == audio_tx_device_id && - audio_tx_path_id == q6_device_to_path(device_id, acdb_id)) { - if (acdb_id != tx_acdb) { - qdsp6_devchg_notify(ac_control, ADSP_AUDIO_TX_DEVICE, - device_id); - audio_update_acdb(device_id, acdb_id); - qdsp6_standby(ac_control); - qdsp6_start(ac_control); - } - return; - } - - if (audio_tx_path_refcount > 0) { - qdsp6_devchg_notify(ac_control, ADSP_AUDIO_TX_DEVICE, device_id); - _audio_tx_path_disable(); - _audio_tx_clk_reinit(device_id, acdb_id); - _audio_tx_path_enable(1, acdb_id); - } else { - qdsp6_devchg_notify(ac_control, ADSP_AUDIO_TX_DEVICE, - device_id); - audio_update_acdb(device_id, acdb_id); - qdsp6_standby(ac_control); - qdsp6_start(ac_control); - audio_tx_device_id = device_id; - audio_tx_path_id = q6_device_to_path(device_id, acdb_id); - tx_acdb = acdb_id; - } -} - -int q6audio_do_routing(uint32_t device_id, uint32_t acdb_id) -{ - if (q6audio_init()) - return 0; - - mutex_lock(&audio_path_lock); - - switch(q6_device_to_dir(device_id)) { - case Q6_RX: - do_rx_routing(device_id, acdb_id); - break; - case Q6_TX: - do_tx_routing(device_id, acdb_id); - break; - } - - mutex_unlock(&audio_path_lock); - return 0; -} - -int q6audio_set_route(const char *name) -{ - uint32_t route; - if (!strcmp(name, "speaker")) { - route = ADIE_PATH_SPEAKER_STEREO_RX; - } else if (!strcmp(name, "headphones")) { - route = ADIE_PATH_HEADSET_STEREO_RX; - } else if (!strcmp(name, "handset")) { - route = ADIE_PATH_HANDSET_RX; - } else { - return -EINVAL; - } - - mutex_lock(&audio_path_lock); - if (route == audio_rx_path_id) - goto done; - - audio_rx_path_id = route; - - if (audio_rx_path_refcount > 0) { - _audio_rx_path_disable(); - _audio_rx_path_enable(1, 0); - } - if (audio_tx_path_refcount > 0) { - _audio_tx_path_disable(); - _audio_tx_path_enable(1, 0); - } -done: - mutex_unlock(&audio_path_lock); - return 0; -} - -static int audio_stream_equalizer(struct audio_client *ac, void *eq_config) -{ - int i; - struct adsp_set_equalizer_command rpc; - struct adsp_audio_eq_stream_config *eq_cfg; - eq_cfg = (struct adsp_audio_eq_stream_config *) eq_config; - - memset(&rpc, 0, sizeof(rpc)); - - rpc.hdr.opcode = ADSP_AUDIO_IOCTL_SET_SESSION_EQ_CONFIG; - rpc.enable = eq_cfg->enable; - rpc.num_bands = eq_cfg->num_bands; - for (i = 0; i < eq_cfg->num_bands; i++) { - rpc.eq_bands[i].band_idx = eq_cfg->eq_bands[i].band_idx; - rpc.eq_bands[i].filter_type = eq_cfg->eq_bands[i].filter_type; - rpc.eq_bands[i].center_freq_hz = - eq_cfg->eq_bands[i].center_freq_hz; - rpc.eq_bands[i].filter_gain = eq_cfg->eq_bands[i].filter_gain; - rpc.eq_bands[i].q_factor = eq_cfg->eq_bands[i].q_factor; - } - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} - -int q6audio_set_stream_eq_pcm(struct audio_client *ac, void *eq_config) -{ - int rc = 0; - mutex_lock(&audio_path_lock); - rc = audio_stream_equalizer(ac, eq_config); - mutex_unlock(&audio_path_lock); - return rc; -} - -struct audio_client *q6audio_open_auxpcm(uint32_t rate, - uint32_t channels, uint32_t flags, uint32_t acdb_id) -{ - int rc, retry = 5; - struct audio_client *ac; - - pr_debug("[%s:%s] rate = %d, channels = %d\n", __MM_FILE__, __func__, - rate, channels); - if (q6audio_init()) - return NULL; - ac = audio_client_alloc(0); - if (!ac) - return NULL; - - ac->flags = flags; - - mutex_lock(&audio_path_lock); - - if (ac->flags & AUDIO_FLAG_WRITE) { - audio_tx_path_refcount++; - if (audio_tx_path_refcount == 1) { - tx_clk_freq = rate; - _audio_tx_clk_enable(); - _audio_tx_path_enable(0, acdb_id); - } - } else { - audio_rx_path_refcount++; - if (audio_rx_path_refcount == 1) { - _audio_rx_clk_enable(); - _audio_rx_path_enable(0, acdb_id); - } - } - - ecodec_clk_enable(); - - for (retry = 5;; retry--) { - if (ac->flags & AUDIO_FLAG_WRITE) - rc = audio_auxpcm_out_open(ac, rate, channels); - else - rc = audio_auxpcm_in_open(ac, rate, channels); - if (rc == 0) - break; - if (retry == 0) - q6audio_dsp_not_responding(); - - pr_err("[%s:%s] open pcm error %d, retrying\n", - __MM_FILE__, __func__, rc); - msleep(1); - } - - mutex_unlock(&audio_path_lock); - - for (retry = 5;; retry--) { - rc = audio_command(ac, ADSP_AUDIO_IOCTL_CMD_SESSION_START); - if (rc == 0) - break; - if (retry == 0) - q6audio_dsp_not_responding(); - - pr_err("[%s:%s] stream start error %d, retrying\n", - __MM_FILE__, __func__, rc); - } - audio_prevent_sleep(); - return ac; - -} - -struct audio_client *q6audio_open_pcm(uint32_t bufsz, uint32_t rate, - uint32_t channels, uint32_t flags, uint32_t acdb_id) -{ - int rc, retry = 5; - struct audio_client *ac; - - pr_debug("[%s:%s] bufsz = %d, rate = %d, channels = %d\n", __MM_FILE__, - __func__, bufsz, rate, channels); - if (q6audio_init()) - return 0; - - ac = audio_client_alloc(bufsz); - if (!ac) - return 0; - - ac->flags = flags; - - mutex_lock(&audio_path_lock); - - if (ac->flags & AUDIO_FLAG_WRITE) { - audio_rx_path_refcount++; - if (audio_rx_path_refcount == 1) { - _audio_rx_clk_enable(); - q6_rx_path_enable(0, acdb_id); - adie_rx_path_enable(acdb_id); - } - } else { - /* TODO: consider concurrency with voice call */ - audio_tx_path_refcount++; - if (audio_tx_path_refcount == 1) { - tx_clk_freq = rate; - _audio_tx_clk_enable(); - _audio_tx_path_enable(0, acdb_id); - } - } - - for (retry = 5;;retry--) { - if (ac->flags & AUDIO_FLAG_WRITE) - rc = audio_out_open(ac, bufsz, rate, channels); - else - rc = audio_in_open(ac, bufsz, flags, rate, channels); - if (rc == 0) - break; - if (retry == 0) - q6audio_dsp_not_responding(); - - pr_err("[%s:%s] open pcm error %d, retrying\n", - __MM_FILE__, __func__, rc); - msleep(1); - } - - if (ac->flags & AUDIO_FLAG_WRITE) { - if (audio_rx_path_refcount == 1) - audio_rx_analog_enable(1); - } - mutex_unlock(&audio_path_lock); - - for (retry = 5;;retry--) { - rc = audio_command(ac, ADSP_AUDIO_IOCTL_CMD_SESSION_START); - if (rc == 0) - break; - if (retry == 0) - q6audio_dsp_not_responding(); - - pr_err("[%s:%s] stream start error %d, retrying\n", - __MM_FILE__, __func__, rc); - } - - if (!(ac->flags & AUDIO_FLAG_WRITE)) { - ac->buf[0].used = 1; - ac->buf[1].used = 1; - q6audio_read(ac, &ac->buf[0]); - q6audio_read(ac, &ac->buf[1]); - } - - audio_prevent_sleep(); - return ac; -} - -int q6audio_close(struct audio_client *ac) -{ - audio_close(ac); - if (ac->flags & AUDIO_FLAG_WRITE) - audio_rx_path_enable(0, 0); - else - audio_tx_path_enable(0, 0); - audio_client_free(ac); - audio_allow_sleep(); - pr_debug("[%s:%s] ac = %p\n", __MM_FILE__, __func__, ac); - return 0; -} - -int q6audio_auxpcm_close(struct audio_client *ac) -{ - audio_close(ac); - if (ac->flags & AUDIO_FLAG_WRITE) { - audio_tx_path_enable(0, 0); - ecodec_clk_disable(0, ADSP_PATH_RX); - } else { - audio_rx_path_enable(0, 0); - ecodec_clk_disable(0, ADSP_PATH_TX); - } - - audio_client_free(ac); - audio_allow_sleep(); - pr_debug("[%s:%s] ac = %p\n", __MM_FILE__, __func__, ac); - return 0; -} -struct audio_client *q6voice_open(uint32_t flags) -{ - struct audio_client *ac; - - pr_debug("[%s:%s] flags = %d\n", __MM_FILE__, __func__, flags); - if (q6audio_init()) - return 0; - - ac = audio_client_alloc(0); - if (!ac) - return 0; - - ac->flags = flags; - if (ac->flags & AUDIO_FLAG_WRITE) - audio_rx_path_enable(1, rx_acdb); - else { - if (!audio_tx_path_refcount) - tx_clk_freq = 8000; - audio_tx_path_enable(1, tx_acdb); - } - - return ac; -} - -int q6voice_close(struct audio_client *ac) -{ - if (ac->flags & AUDIO_FLAG_WRITE) - audio_rx_path_enable(0, 0); - else - audio_tx_path_enable(0, 0); - - tx_mute_status = 0; - audio_client_free(ac); - pr_debug("[%s:%s]\n", __MM_FILE__, __func__); - return 0; -} - -struct audio_client *q6audio_open_mp3(uint32_t bufsz, uint32_t rate, - uint32_t channels, uint32_t acdb_id) -{ - struct audio_client *ac; - - pr_debug("[%s:%s] bufsz = %d, rate = %d\n, channels = %d", - __MM_FILE__, __func__, bufsz, rate, channels); - - if (q6audio_init()) - return 0; - - ac = audio_client_alloc(bufsz); - if (!ac) - return 0; - - ac->flags = AUDIO_FLAG_WRITE; - audio_rx_path_enable(1, acdb_id); - - audio_mp3_open(ac, bufsz, rate, channels); - audio_command(ac, ADSP_AUDIO_IOCTL_CMD_SESSION_START); - - mutex_lock(&audio_path_lock); - audio_rx_mute(ac_control, audio_rx_device_id, 0); - audio_rx_volume(ac_control, audio_rx_device_id, - q6_device_volume(audio_rx_device_id, rx_vol_level)); - mutex_unlock(&audio_path_lock); - return ac; -} - -struct audio_client *q6audio_open_dtmf(uint32_t rate, - uint32_t channels, uint32_t acdb_id) -{ - struct audio_client *ac; - - pr_debug("[%s:%s] rate = %d\n, channels = %d", __MM_FILE__, __func__, - rate, channels); - if (q6audio_init()) - return 0; - - ac = audio_client_alloc(0); - if (!ac) - return 0; - - ac->flags = AUDIO_FLAG_WRITE; - audio_rx_path_enable(1, acdb_id); - - audio_dtmf_open(ac, rate, channels); - audio_command(ac, ADSP_AUDIO_IOCTL_CMD_SESSION_START); - - mutex_lock(&audio_path_lock); - audio_rx_mute(ac_control, audio_rx_device_id, 0); - audio_rx_volume(ac_control, audio_rx_device_id, - q6_device_volume(audio_rx_device_id, rx_vol_level)); - mutex_unlock(&audio_path_lock); - - return ac; -} - -int q6audio_play_dtmf(struct audio_client *ac, uint16_t dtmf_hi, - uint16_t dtmf_low, uint16_t duration, uint16_t rx_gain) -{ - struct adsp_audio_dtmf_start_command dtmf_cmd; - - pr_debug("[%s:%s] high = %d, low = %d\n", __MM_FILE__, __func__, - dtmf_hi, dtmf_low); - - dtmf_cmd.hdr.opcode = ADSP_AUDIO_IOCTL_CMD_SESSION_DTMF_START; - dtmf_cmd.hdr.response_type = ADSP_AUDIO_RESPONSE_COMMAND; - dtmf_cmd.tone1_hz = dtmf_hi; - dtmf_cmd.tone2_hz = dtmf_low; - dtmf_cmd.duration_usec = duration * 1000; - dtmf_cmd.gain_mb = rx_gain; - - return audio_ioctl(ac, &dtmf_cmd, - sizeof(struct adsp_audio_dtmf_start_command)); - -} - -int q6audio_mp3_close(struct audio_client *ac) -{ - pr_debug("[%s:%s]\n", __MM_FILE__, __func__); - audio_close(ac); - audio_rx_path_enable(0, 0); - audio_client_free(ac); - return 0; -} - - -struct audio_client *q6audio_open_aac(uint32_t bufsz, uint32_t samplerate, - uint32_t channels, uint32_t bitrate, - uint32_t stream_format, uint32_t flags, - uint32_t acdb_id) -{ - struct audio_client *ac; - - pr_debug("[%s:%s] bufsz = %d, samplerate = %d, channels = %d\n", - __MM_FILE__, __func__, bufsz, samplerate, channels); - - if (q6audio_init()) - return 0; - - ac = audio_client_alloc(bufsz); - if (!ac) - return 0; - - ac->flags = flags; - - if (ac->flags & AUDIO_FLAG_WRITE) - audio_rx_path_enable(1, acdb_id); - else{ - if (!audio_tx_path_refcount) - tx_clk_freq = 48000; - audio_tx_path_enable(1, acdb_id); - } - - audio_aac_open(ac, bufsz, samplerate, channels, bitrate, flags, - stream_format); - audio_command(ac, ADSP_AUDIO_IOCTL_CMD_SESSION_START); - - if (!(ac->flags & AUDIO_FLAG_WRITE)) { - ac->buf[0].used = 1; - ac->buf[1].used = 1; - q6audio_read(ac, &ac->buf[0]); - q6audio_read(ac, &ac->buf[1]); - } - audio_prevent_sleep(); - return ac; -} - - -struct audio_client *q6audio_open_qcp(uint32_t bufsz, uint32_t min_rate, - uint32_t max_rate, uint32_t flags, - uint32_t format, uint32_t acdb_id) -{ - struct audio_client *ac; - - pr_debug("[%s:%s] bufsz = %d\n", __MM_FILE__, __func__, bufsz); - - if (q6audio_init()) - return 0; - - ac = audio_client_alloc(bufsz); - if (!ac) - return 0; - - ac->flags = flags; - - if (ac->flags & AUDIO_FLAG_WRITE) - audio_rx_path_enable(1, acdb_id); - else{ - if (!audio_tx_path_refcount) - tx_clk_freq = 8000; - audio_tx_path_enable(1, acdb_id); - } - - audio_qcp_open(ac, bufsz, min_rate, max_rate, flags, format); - audio_command(ac, ADSP_AUDIO_IOCTL_CMD_SESSION_START); - - if (!(ac->flags & AUDIO_FLAG_WRITE)) { - ac->buf[0].used = 1; - ac->buf[1].used = 1; - q6audio_read(ac, &ac->buf[0]); - q6audio_read(ac, &ac->buf[1]); - } - audio_prevent_sleep(); - return ac; -} - -struct audio_client *q6audio_open_amrnb(uint32_t bufsz, uint32_t enc_mode, - uint32_t dtx_mode_enable, - uint32_t flags, uint32_t acdb_id) -{ - struct audio_client *ac; - - pr_debug("[%s:%s] bufsz = %d, dtx_mode = %d\n", __MM_FILE__, - __func__, bufsz, dtx_mode_enable); - - if (q6audio_init()) - return 0; - - ac = audio_client_alloc(bufsz); - if (!ac) - return 0; - - ac->flags = flags; - if (ac->flags & AUDIO_FLAG_WRITE) - audio_rx_path_enable(1, acdb_id); - else{ - if (!audio_tx_path_refcount) - tx_clk_freq = 8000; - audio_tx_path_enable(1, acdb_id); - } - - audio_amrnb_open(ac, bufsz, enc_mode, flags, dtx_mode_enable); - audio_command(ac, ADSP_AUDIO_IOCTL_CMD_SESSION_START); - - if (!(ac->flags & AUDIO_FLAG_WRITE)) { - ac->buf[0].used = 1; - ac->buf[1].used = 1; - q6audio_read(ac, &ac->buf[0]); - q6audio_read(ac, &ac->buf[1]); - } - audio_prevent_sleep(); - return ac; -} - -int q6audio_async(struct audio_client *ac) -{ - struct adsp_command_hdr rpc; - pr_debug("[%s:%s] ac = %p\n", __MM_FILE__, __func__, ac); - memset(&rpc, 0, sizeof(rpc)); - rpc.opcode = ADSP_AUDIO_IOCTL_CMD_STREAM_EOS; - rpc.response_type = ADSP_AUDIO_RESPONSE_ASYNC; - return audio_ioctl(ac, &rpc, sizeof(rpc)); -} diff --git a/arch/arm/mach-msm/qdsp6/q6audio_devices.h b/arch/arm/mach-msm/qdsp6/q6audio_devices.h deleted file mode 100644 index d316ab0e0de96eef684221c7bf39bb321b83f140..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/q6audio_devices.h +++ /dev/null @@ -1,334 +0,0 @@ -/* arch/arm/mach-msm/qdsp6/q6audio_devices.h - * - * Copyright (C) 2009 Google, Inc. - * Author: Brian Swetland - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -struct q6_device_info { - uint32_t id; - uint32_t cad_id; - uint32_t path; - uint32_t rate; - uint8_t dir; - uint8_t codec; - uint8_t hw; -}; - -#define Q6_ICODEC_RX 0 -#define Q6_ICODEC_TX 1 -#define Q6_ECODEC_RX 2 -#define Q6_ECODEC_TX 3 -#define Q6_SDAC_RX 6 -#define Q6_SDAC_TX 7 -#define Q6_CODEC_NONE 255 - -#define Q6_TX 1 -#define Q6_RX 2 -#define Q6_TX_RX 3 - -#define Q6_HW_HANDSET 0 -#define Q6_HW_HEADSET 1 -#define Q6_HW_SPEAKER 2 -#define Q6_HW_TTY 3 -#define Q6_HW_BT_SCO 4 -#define Q6_HW_BT_A2DP 5 - -#define Q6_HW_COUNT 6 - -#define CAD_HW_DEVICE_ID_HANDSET_MIC 0x01 -#define CAD_HW_DEVICE_ID_HANDSET_SPKR 0x02 -#define CAD_HW_DEVICE_ID_HEADSET_MIC 0x03 -#define CAD_HW_DEVICE_ID_HEADSET_SPKR_MONO 0x04 -#define CAD_HW_DEVICE_ID_HEADSET_SPKR_STEREO 0x05 -#define CAD_HW_DEVICE_ID_SPKR_PHONE_MIC 0x06 -#define CAD_HW_DEVICE_ID_SPKR_PHONE_MONO 0x07 -#define CAD_HW_DEVICE_ID_SPKR_PHONE_STEREO 0x08 -#define CAD_HW_DEVICE_ID_BT_SCO_MIC 0x09 -#define CAD_HW_DEVICE_ID_BT_SCO_SPKR 0x0A -#define CAD_HW_DEVICE_ID_BT_A2DP_SPKR 0x0B -#define CAD_HW_DEVICE_ID_TTY_HEADSET_MIC 0x0C -#define CAD_HW_DEVICE_ID_TTY_HEADSET_SPKR 0x0D - -#define CAD_HW_DEVICE_ID_DEFAULT_TX 0x0E -#define CAD_HW_DEVICE_ID_DEFAULT_RX 0x0F - - -#define CAD_HW_DEVICE_ID_SPKR_PHONE_DUAL_MIC_BROADSIDE 0x2B -#define CAD_HW_DEVICE_ID_SPKR_PHONE_DUAL_MIC_ENDFIRE 0x2D -#define CAD_HW_DEVICE_ID_HANDSET_DUAL_MIC_BROADSIDE 0x2C -#define CAD_HW_DEVICE_ID_HANDSET_DUAL_MIC_ENDFIRE 0x2E - -/* Logical Device to indicate A2DP routing */ -#define CAD_HW_DEVICE_ID_BT_A2DP_TX 0x10 -#define CAD_HW_DEVICE_ID_HEADSET_MONO_PLUS_SPKR_MONO_RX 0x11 -#define CAD_HW_DEVICE_ID_HEADSET_MONO_PLUS_SPKR_STEREO_RX 0x12 -#define CAD_HW_DEVICE_ID_HEADSET_STEREO_PLUS_SPKR_MONO_RX 0x13 -#define CAD_HW_DEVICE_ID_HEADSET_STEREO_PLUS_SPKR_STEREO_RX 0x14 - -#define CAD_HW_DEVICE_ID_VOICE 0x15 - -#define CAD_HW_DEVICE_ID_I2S_RX 0x20 -#define CAD_HW_DEVICE_ID_I2S_TX 0x21 - -/* AUXPGA */ -#define CAD_HW_DEVICE_ID_HEADSET_SPKR_STEREO_LB 0x22 -#define CAD_HW_DEVICE_ID_HEADSET_SPKR_MONO_LB 0x23 -#define CAD_HW_DEVICE_ID_SPEAKER_SPKR_STEREO_LB 0x24 -#define CAD_HW_DEVICE_ID_SPEAKER_SPKR_MONO_LB 0x25 - -#define CAD_HW_DEVICE_ID_NULL_RX 0x2A - -#define CAD_HW_DEVICE_ID_MAX_NUM 0x2F - -#define CAD_HW_DEVICE_ID_INVALID 0xFF - -#define CAD_RX_DEVICE 0x00 -#define CAD_TX_DEVICE 0x01 - -static struct q6_device_info q6_audio_devices[] = { - { - .id = ADSP_AUDIO_DEVICE_ID_HANDSET_SPKR, - .cad_id = CAD_HW_DEVICE_ID_HANDSET_SPKR, - .path = ADIE_PATH_HANDSET_RX, - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ICODEC_RX, - .hw = Q6_HW_HANDSET, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_HEADSET_SPKR_MONO, - .cad_id = CAD_HW_DEVICE_ID_HEADSET_SPKR_MONO, - .path = ADIE_PATH_HEADSET_MONO_RX, - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ICODEC_RX, - .hw = Q6_HW_HEADSET, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_HEADSET_SPKR_STEREO, - .cad_id = CAD_HW_DEVICE_ID_HEADSET_SPKR_STEREO, - .path = ADIE_PATH_HEADSET_STEREO_RX, - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ICODEC_RX, - .hw = Q6_HW_HEADSET, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO, - .cad_id = CAD_HW_DEVICE_ID_SPKR_PHONE_MONO, - .path = ADIE_PATH_SPEAKER_RX, - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ICODEC_RX, - .hw = Q6_HW_SPEAKER, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO, - .cad_id = CAD_HW_DEVICE_ID_SPKR_PHONE_STEREO, - .path = ADIE_PATH_SPEAKER_STEREO_RX, - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ICODEC_RX, - .hw = Q6_HW_SPEAKER, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO_W_MONO_HEADSET, - .cad_id = CAD_HW_DEVICE_ID_HEADSET_MONO_PLUS_SPKR_MONO_RX, - .path = ADIE_PATH_SPKR_MONO_HDPH_MONO_RX, - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ICODEC_RX, - .hw = Q6_HW_SPEAKER, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MONO_W_STEREO_HEADSET, - .cad_id = CAD_HW_DEVICE_ID_HEADSET_STEREO_PLUS_SPKR_MONO_RX, - .path = ADIE_PATH_SPKR_MONO_HDPH_STEREO_RX, - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ICODEC_RX, - .hw = Q6_HW_SPEAKER, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO_W_MONO_HEADSET, - .cad_id = CAD_HW_DEVICE_ID_HEADSET_MONO_PLUS_SPKR_STEREO_RX, - .path = ADIE_PATH_SPKR_STEREO_HDPH_MONO_RX, - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ICODEC_RX, - .hw = Q6_HW_SPEAKER, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_STEREO_W_STEREO_HEADSET, - .cad_id = CAD_HW_DEVICE_ID_HEADSET_STEREO_PLUS_SPKR_STEREO_RX, - .path = ADIE_PATH_SPKR_STEREO_HDPH_STEREO_RX, - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ICODEC_RX, - .hw = Q6_HW_SPEAKER, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_TTY_HEADSET_SPKR, - .cad_id = CAD_HW_DEVICE_ID_TTY_HEADSET_SPKR, - .path = ADIE_PATH_TTY_HEADSET_RX, - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ICODEC_RX, - .hw = Q6_HW_TTY, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_HANDSET_MIC, - .cad_id = CAD_HW_DEVICE_ID_HANDSET_MIC, - .path = ADIE_PATH_HANDSET_TX, - .rate = 8000, - .dir = Q6_TX, - .codec = Q6_ICODEC_TX, - .hw = Q6_HW_HANDSET, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_HEADSET_MIC, - .cad_id = CAD_HW_DEVICE_ID_HEADSET_MIC, - .path = ADIE_PATH_HEADSET_MONO_TX, - .rate = 8000, - .dir = Q6_TX, - .codec = Q6_ICODEC_TX, - .hw = Q6_HW_HEADSET, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_MIC, - .cad_id = CAD_HW_DEVICE_ID_SPKR_PHONE_MIC, - .path = ADIE_PATH_SPEAKER_TX, - .rate = 8000, - .dir = Q6_TX, - .codec = Q6_ICODEC_TX, - .hw = Q6_HW_SPEAKER, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_HANDSET_DUAL_MIC, - .cad_id = CAD_HW_DEVICE_ID_HANDSET_DUAL_MIC_ENDFIRE, - .path = ADIE_CODEC_HANDSET_SPKR_EF_TX, - .rate = 8000, - .dir = Q6_TX, - .codec = Q6_ICODEC_TX, - .hw = Q6_HW_HANDSET, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_HANDSET_DUAL_MIC, - .cad_id = CAD_HW_DEVICE_ID_HANDSET_DUAL_MIC_BROADSIDE, - .path = ADIE_CODEC_HANDSET_SPKR_BS_TX, - .rate = 8000, - .dir = Q6_TX, - .codec = Q6_ICODEC_TX, - .hw = Q6_HW_HANDSET, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_DUAL_MIC, - .cad_id = CAD_HW_DEVICE_ID_SPKR_PHONE_DUAL_MIC_ENDFIRE, - .path = ADIE_CODEC_HANDSET_SPKR_EF_TX, - .rate = 8000, - .dir = Q6_TX, - .codec = Q6_ICODEC_TX, - .hw = Q6_HW_SPEAKER, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_SPKR_PHONE_DUAL_MIC, - .cad_id = CAD_HW_DEVICE_ID_SPKR_PHONE_DUAL_MIC_BROADSIDE, - .path = ADIE_CODEC_HANDSET_SPKR_BS_TX, - .rate = 8000, - .dir = Q6_TX, - .codec = Q6_ICODEC_TX, - .hw = Q6_HW_SPEAKER, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_TTY_HEADSET_MIC, - .cad_id = CAD_HW_DEVICE_ID_TTY_HEADSET_MIC, - .path = ADIE_PATH_TTY_HEADSET_TX, - .rate = 8000, - .dir = Q6_TX, - .codec = Q6_ICODEC_TX, - .hw = Q6_HW_HEADSET, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_BT_SCO_SPKR, - .cad_id = CAD_HW_DEVICE_ID_BT_SCO_SPKR, - .path = 0, /* XXX */ - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ECODEC_RX, - .hw = Q6_HW_BT_SCO, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_BT_A2DP_SPKR, - .cad_id = CAD_HW_DEVICE_ID_BT_A2DP_SPKR, - .path = 0, /* XXX */ - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_ECODEC_RX, - .hw = Q6_HW_BT_A2DP, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_BT_SCO_MIC, - .cad_id = CAD_HW_DEVICE_ID_BT_SCO_MIC, - .path = 0, /* XXX */ - .rate = 8000, - .dir = Q6_TX, - .codec = Q6_ECODEC_TX, - .hw = Q6_HW_BT_SCO, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_I2S_SPKR, - .cad_id = CAD_HW_DEVICE_ID_I2S_RX, - .path = 0, /* XXX */ - .rate = 48000, - .dir = Q6_RX, - .codec = Q6_SDAC_RX, - .hw = Q6_HW_SPEAKER, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_I2S_MIC, - .cad_id = CAD_HW_DEVICE_ID_I2S_TX, - .path = 0, /* XXX */ - .rate = 16000, - .dir = Q6_TX, - .codec = Q6_SDAC_TX, - .hw = Q6_HW_SPEAKER, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_AUXPCM_RX, - .cad_id = CAD_HW_DEVICE_ID_BT_SCO_SPKR, - .path = 0, /* XXX */ - .rate = 8000, - .dir = Q6_RX, - .codec = Q6_ECODEC_RX, - .hw = Q6_HW_BT_SCO, - }, - { - .id = ADSP_AUDIO_DEVICE_ID_AUXPCM_TX, - .cad_id = CAD_HW_DEVICE_ID_BT_SCO_MIC, - .path = 0, /* XXX */ - .rate = 8000, - .dir = Q6_TX, - .codec = Q6_ECODEC_TX, - .hw = Q6_HW_BT_SCO, - }, - { - .id = 0, - .cad_id = 0, - .path = 0, - .rate = 8000, - .dir = 0, - .codec = Q6_CODEC_NONE, - .hw = 0, - }, -}; - diff --git a/arch/arm/mach-msm/qdsp6/qcelp_in.c b/arch/arm/mach-msm/qdsp6/qcelp_in.c deleted file mode 100644 index 42896123a3326a7a21e0d93a3fa9d3a8e1b260c6..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/qcelp_in.c +++ /dev/null @@ -1,475 +0,0 @@ -/* - * Copyright (C) 2009 Google, Inc. - * Copyright (C) 2009 HTC Corporation - * Copyright (c) 2010, The Linux Foundation. All rights reserved. - * - * Author: Brian Swetland - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "dal_audio_format.h" -#include - -#define QCELP_FC_BUFF_CNT 10 -#define QCELP_READ_TIMEOUT 2000 -struct qcelp_fc_buff { - struct mutex lock; - int empty; - void *data; - int size; - int actual_size; -}; - -struct qcelp_fc { - struct task_struct *task; - wait_queue_head_t fc_wq; - struct qcelp_fc_buff fc_buff[QCELP_FC_BUFF_CNT]; - int buff_index; -}; - -struct qcelp { - struct mutex lock; - struct msm_audio_qcelp_enc_config cfg; - struct msm_audio_stream_config str_cfg; - struct audio_client *audio_client; - struct msm_voicerec_mode voicerec_mode; - struct qcelp_fc *qcelp_fc; -}; - - -static int q6_qcelp_flowcontrol(void *data) -{ - struct audio_client *ac; - struct audio_buffer *ab; - struct qcelp *qcelp = data; - int buff_index = 0; - int xfer = 0; - struct qcelp_fc *fc; - - - ac = qcelp->audio_client; - fc = qcelp->qcelp_fc; - if (!ac) { - pr_err("[%s:%s] audio_client is NULL\n", __MM_FILE__, __func__); - return 0; - } - - while (!kthread_should_stop()) { - ab = ac->buf + ac->cpu_buf; - if (ab->used) - wait_event(ac->wait, (ab->used == 0)); - - pr_debug("[%s:%s] ab->data = %p, cpu_buf = %d", __MM_FILE__, - __func__, ab->data, ac->cpu_buf); - xfer = ab->actual_size; - - - mutex_lock(&(fc->fc_buff[buff_index].lock)); - if (!fc->fc_buff[buff_index].empty) { - pr_err("[%s:%s] flow control buffer[%d] not read!\n", - __MM_FILE__, __func__, buff_index); - } - - if (fc->fc_buff[buff_index].size < xfer) { - pr_err("[%s:%s] buffer %d too small\n", __MM_FILE__, - __func__, buff_index); - memcpy(fc->fc_buff[buff_index].data, ab->data, - fc->fc_buff[buff_index].size); - fc->fc_buff[buff_index].empty = 0; - fc->fc_buff[buff_index].actual_size = - fc->fc_buff[buff_index].size; - } else { - memcpy(fc->fc_buff[buff_index].data, ab->data, xfer); - fc->fc_buff[buff_index].empty = 0; - fc->fc_buff[buff_index].actual_size = xfer; - } - mutex_unlock(&(fc->fc_buff[buff_index].lock)); - /*wake up client, if any*/ - wake_up(&fc->fc_wq); - - buff_index++; - if (buff_index >= QCELP_FC_BUFF_CNT) - buff_index = 0; - - ab->used = 1; - - q6audio_read(ac, ab); - ac->cpu_buf ^= 1; - } - - return 0; -} -static long q6_qcelp_in_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct qcelp *qcelp = file->private_data; - int rc = 0; - int i = 0; - struct qcelp_fc *fc; - int size = 0; - - mutex_lock(&qcelp->lock); - switch (cmd) { - case AUDIO_SET_VOLUME: - pr_debug("[%s:%s] SET_VOLUME\n", __MM_FILE__, __func__); - break; - case AUDIO_GET_STATS: - { - struct msm_audio_stats stats; - pr_debug("[%s:%s] GET_STATS\n", __MM_FILE__, __func__); - memset(&stats, 0, sizeof(stats)); - if (copy_to_user((void *) arg, &stats, - sizeof(stats))) - return -EFAULT; - return 0; - } - case AUDIO_START: - { - uint32_t acdb_id; - pr_debug("[%s:%s] AUDIO_START\n", __MM_FILE__, __func__); - if (arg == 0) { - acdb_id = 0; - } else { - if (copy_from_user(&acdb_id, - (void *) arg, sizeof(acdb_id))) { - rc = -EFAULT; - break; - } - } - if (qcelp->audio_client) { - pr_err("[%s:%s] active session already existing\n", - __MM_FILE__, __func__); - rc = -EBUSY; - break; - } else { - qcelp->audio_client = q6audio_open_qcp( - qcelp->str_cfg.buffer_size, - qcelp->cfg.min_bit_rate, - qcelp->cfg.max_bit_rate, - qcelp->voicerec_mode.rec_mode, - ADSP_AUDIO_FORMAT_V13K_FS, - acdb_id); - - if (!qcelp->audio_client) { - pr_err("[%s:%s] qcelp open session failed\n", - __MM_FILE__, __func__); - kfree(qcelp); - rc = -ENOMEM; - break; - } - } - - /*allocate flow control buffers*/ - fc = qcelp->qcelp_fc; - size = qcelp->str_cfg.buffer_size; - for (i = 0; i < QCELP_FC_BUFF_CNT; ++i) { - mutex_init(&(fc->fc_buff[i].lock)); - fc->fc_buff[i].empty = 1; - fc->fc_buff[i].data = kmalloc(size, GFP_KERNEL); - if (fc->fc_buff[i].data == NULL) { - pr_err("[%s:%s] No memory for FC buffers\n", - __MM_FILE__, __func__); - rc = -ENOMEM; - goto fc_fail; - } - fc->fc_buff[i].size = size; - fc->fc_buff[i].actual_size = 0; - } - - /*create flow control thread*/ - fc->task = kthread_run(q6_qcelp_flowcontrol, - qcelp, "qcelp_flowcontrol"); - if (IS_ERR(fc->task)) { - rc = PTR_ERR(fc->task); - pr_err("[%s:%s] error creating flow control thread\n", - __MM_FILE__, __func__); - goto fc_fail; - } - break; -fc_fail: - /*free flow control buffers*/ - --i; - for (; i >= 0; i--) { - kfree(fc->fc_buff[i].data); - fc->fc_buff[i].data = NULL; - } - break; - } - case AUDIO_STOP: - pr_debug("[%s:%s] AUDIO_STOP\n", __MM_FILE__, __func__); - break; - case AUDIO_FLUSH: - break; - case AUDIO_SET_INCALL: { - pr_debug("[%s:%s] SET_INCALL\n", __MM_FILE__, __func__); - if (copy_from_user(&qcelp->voicerec_mode, - (void *)arg, sizeof(struct msm_voicerec_mode))) - rc = -EFAULT; - - if (qcelp->voicerec_mode.rec_mode != AUDIO_FLAG_READ - && qcelp->voicerec_mode.rec_mode != - AUDIO_FLAG_INCALL_MIXED) { - qcelp->voicerec_mode.rec_mode = AUDIO_FLAG_READ; - pr_err("[%s:%s] Invalid rec_mode\n", __MM_FILE__, - __func__); - rc = -EINVAL; - } - break; - } - case AUDIO_GET_STREAM_CONFIG: - if (copy_to_user((void *)arg, &qcelp->str_cfg, - sizeof(struct msm_audio_stream_config))) - rc = -EFAULT; - pr_debug("[%s:%s] GET_STREAM_CONFIG: buffsz=%d, buffcnt=%d\n", - __MM_FILE__, __func__, qcelp->str_cfg.buffer_size, - qcelp->str_cfg.buffer_count); - break; - case AUDIO_SET_STREAM_CONFIG: - if (copy_from_user(&qcelp->str_cfg, (void *)arg, - sizeof(struct msm_audio_stream_config))) { - rc = -EFAULT; - break; - } - pr_debug("[%s:%s] SET_STREAM_CONFIG: buffsz=%d, buffcnt=%d\n", - __MM_FILE__, __func__, qcelp->str_cfg.buffer_size, - qcelp->str_cfg.buffer_count); - - if (qcelp->str_cfg.buffer_size < 35) { - pr_err("[%s:%s] Buffer size too small\n", __MM_FILE__, - __func__); - rc = -EINVAL; - break; - } - - if (qcelp->str_cfg.buffer_count != 2) - pr_info("[%s:%s] Buffer count set to 2\n", __MM_FILE__, - __func__); - break; - case AUDIO_SET_QCELP_ENC_CONFIG: - if (copy_from_user(&qcelp->cfg, (void *) arg, - sizeof(struct msm_audio_qcelp_enc_config))) - rc = -EFAULT; - pr_debug("[%s:%s] SET_QCELP_ENC_CONFIG\n", __MM_FILE__, - __func__); - - if (qcelp->cfg.min_bit_rate > 4 || - qcelp->cfg.min_bit_rate < 1) { - - pr_err("[%s:%s] invalid min bitrate\n", __MM_FILE__, - __func__); - rc = -EINVAL; - } - if (qcelp->cfg.max_bit_rate > 4 || - qcelp->cfg.max_bit_rate < 1) { - - pr_err("[%s:%s] invalid max bitrate\n", __MM_FILE__, - __func__); - rc = -EINVAL; - } - - break; - case AUDIO_GET_QCELP_ENC_CONFIG: - if (copy_to_user((void *) arg, &qcelp->cfg, - sizeof(struct msm_audio_qcelp_enc_config))) - rc = -EFAULT; - pr_debug("[%s:%s] GET_QCELP_ENC_CONFIG\n", __MM_FILE__, - __func__); - break; - - default: - rc = -EINVAL; - } - mutex_unlock(&qcelp->lock); - pr_debug("[%s:%s] rc = %d\n", __MM_FILE__, __func__, rc); - return rc; -} - -static int q6_qcelp_in_open(struct inode *inode, struct file *file) -{ - struct qcelp *qcelp; - struct qcelp_fc *fc; - int i; - pr_info("[%s:%s] open\n", __MM_FILE__, __func__); - qcelp = kmalloc(sizeof(struct qcelp), GFP_KERNEL); - if (qcelp == NULL) { - pr_err("[%s:%s] Could not allocate memory for qcelp driver\n", - __MM_FILE__, __func__); - return -ENOMEM; - } - - mutex_init(&qcelp->lock); - file->private_data = qcelp; - qcelp->audio_client = NULL; - qcelp->str_cfg.buffer_size = 35; - qcelp->str_cfg.buffer_count = 2; - qcelp->cfg.cdma_rate = CDMA_RATE_FULL; - qcelp->cfg.min_bit_rate = 1; - qcelp->cfg.max_bit_rate = 4; - qcelp->voicerec_mode.rec_mode = AUDIO_FLAG_READ; - - qcelp->qcelp_fc = kmalloc(sizeof(struct qcelp_fc), GFP_KERNEL); - if (qcelp->qcelp_fc == NULL) { - pr_err("[%s:%s] Could not allocate memory for qcelp_fc\n", - __MM_FILE__, __func__); - kfree(qcelp); - return -ENOMEM; - } - fc = qcelp->qcelp_fc; - fc->task = NULL; - fc->buff_index = 0; - for (i = 0; i < QCELP_FC_BUFF_CNT; ++i) { - fc->fc_buff[i].data = NULL; - fc->fc_buff[i].size = 0; - fc->fc_buff[i].actual_size = 0; - } - /*initialize wait queue head*/ - init_waitqueue_head(&fc->fc_wq); - return 0; -} - -static ssize_t q6_qcelp_in_read(struct file *file, char __user *buf, - size_t count, loff_t *pos) -{ - struct audio_client *ac; - const char __user *start = buf; - struct qcelp *qcelp = file->private_data; - struct qcelp_fc *fc; - int xfer = 0; - int res = 0; - - pr_debug("[%s:%s] count = %d\n", __MM_FILE__, __func__, count); - mutex_lock(&qcelp->lock); - ac = qcelp->audio_client; - if (!ac) { - res = -ENODEV; - goto fail; - } - fc = qcelp->qcelp_fc; - while (count > xfer) { - /*wait for buffer to full*/ - if (fc->fc_buff[fc->buff_index].empty != 0) { - res = wait_event_interruptible_timeout(fc->fc_wq, - (fc->fc_buff[fc->buff_index].empty == 0), - msecs_to_jiffies(QCELP_READ_TIMEOUT)); - - pr_debug("[%s:%s] buff_index = %d\n", __MM_FILE__, - __func__, fc->buff_index); - if (res == 0) { - pr_err("[%s:%s] Timeout!\n", __MM_FILE__, - __func__); - res = -ETIMEDOUT; - goto fail; - } else if (res < 0) { - pr_err("[%s:%s] Returning on Interrupt\n", - __MM_FILE__, __func__); - goto fail; - } - } - /*lock the buffer*/ - mutex_lock(&(fc->fc_buff[fc->buff_index].lock)); - xfer = fc->fc_buff[fc->buff_index].actual_size; - - if (xfer > count) { - mutex_unlock(&(fc->fc_buff[fc->buff_index].lock)); - pr_err("[%s:%s] read failed! byte count too small\n", - __MM_FILE__, __func__); - res = -EINVAL; - goto fail; - } - - if (copy_to_user(buf, fc->fc_buff[fc->buff_index].data, xfer)) { - mutex_unlock(&(fc->fc_buff[fc->buff_index].lock)); - pr_err("[%s:%s] copy_to_user failed at index %d\n", - __MM_FILE__, __func__, fc->buff_index); - res = -EFAULT; - goto fail; - } - buf += xfer; - count -= xfer; - - fc->fc_buff[fc->buff_index].empty = 1; - fc->fc_buff[fc->buff_index].actual_size = 0; - - mutex_unlock(&(fc->fc_buff[fc->buff_index].lock)); - ++(fc->buff_index); - if (fc->buff_index >= QCELP_FC_BUFF_CNT) - fc->buff_index = 0; - } - res = buf - start; - -fail: - mutex_unlock(&qcelp->lock); - - return res; -} - -static int q6_qcelp_in_release(struct inode *inode, struct file *file) -{ - int rc = 0; - struct qcelp *qcelp = file->private_data; - int i = 0; - struct qcelp_fc *fc; - - mutex_lock(&qcelp->lock); - fc = qcelp->qcelp_fc; - kthread_stop(fc->task); - fc->task = NULL; - - /*free flow control buffers*/ - for (i = 0; i < QCELP_FC_BUFF_CNT; ++i) { - kfree(fc->fc_buff[i].data); - fc->fc_buff[i].data = NULL; - } - kfree(fc); - - if (qcelp->audio_client) - rc = q6audio_close(qcelp->audio_client); - mutex_unlock(&qcelp->lock); - kfree(qcelp); - pr_info("[%s:%s] release\n", __MM_FILE__, __func__); - return rc; -} - -static const struct file_operations q6_qcelp_in_fops = { - .owner = THIS_MODULE, - .open = q6_qcelp_in_open, - .read = q6_qcelp_in_read, - .release = q6_qcelp_in_release, - .unlocked_ioctl = q6_qcelp_in_ioctl, -}; - -struct miscdevice q6_qcelp_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_qcelp_in", - .fops = &q6_qcelp_in_fops, -}; - -static int __init q6_qcelp_in_init(void) -{ - return misc_register(&q6_qcelp_in_misc); -} - -device_initcall(q6_qcelp_in_init); diff --git a/arch/arm/mach-msm/qdsp6/routing.c b/arch/arm/mach-msm/qdsp6/routing.c deleted file mode 100644 index f6533a40c2bf838be5900cb76727c9b223ddecf1..0000000000000000000000000000000000000000 --- a/arch/arm/mach-msm/qdsp6/routing.c +++ /dev/null @@ -1,78 +0,0 @@ -/* arch/arm/mach-msm/qdsp6/routing.c - * - * Copyright (C) 2009 Google, Inc. - * Author: Brian Swetland - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include - -extern int q6audio_set_route(const char *name); - -static int q6_open(struct inode *inode, struct file *file) -{ - pr_debug("[%s:%s]\n", __MM_FILE__, __func__); - return 0; -} - -static ssize_t q6_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - char cmd[32]; - - pr_debug("[%s:%s] count = %d", __MM_FILE__, __func__, count); - if (count >= sizeof(cmd)) { - pr_err("[%s:%s] invalid count %d\n", __MM_FILE__, - __func__, count); - return -EINVAL; - } - if (copy_from_user(cmd, buf, count)) - return -EFAULT; - cmd[count] = 0; - - if ((count > 1) && (cmd[count-1] == '\n')) - cmd[count-1] = 0; - - q6audio_set_route(cmd); - - return count; -} - -static int q6_release(struct inode *inode, struct file *file) -{ - pr_debug("[%s:%s]\n", __MM_FILE__, __func__); - return 0; -} - -static struct file_operations q6_fops = { - .owner = THIS_MODULE, - .open = q6_open, - .write = q6_write, - .release = q6_release, -}; - -static struct miscdevice q6_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_audio_route", - .fops = &q6_fops, -}; - - -static int __init q6_init(void) { - return misc_register(&q6_misc); -} - -device_initcall(q6_init);