<commit_before>/* 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 <asm/atomic.h>
#include <asm/ioctls.h>

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#include <linux/kthread.h>
#include <linux/wait.h>
#include <linux/dma-mapping.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/list.h>
#include <linux/earlysuspend.h>
#include <linux/slab.h>
#include <linux/msm_audio.h>
#include <linux/memory_alloc.h>
#include <linux/msm_audio_ac3.h>
#include <linux/msm_ion.h>

#include <mach/msm_adsp.h>
#include <mach/iommu.h>
#include <mach/iommu_domains.h>
#include <mach/qdsp5/qdsp5audppcmdi.h>
#include <mach/qdsp5/qdsp5audppmsg.h>
#include <mach/qdsp5/qdsp5audpp.h>
#include <mach/qdsp5/qdsp5audplaycmdi.h>
#include <mach/qdsp5/qdsp5audplaymsg.h>
#include <mach/qdsp5/qdsp5rmtcmdi.h>
#include <mach/debug_mm.h>
#include <mach/msm_memtypes.h>

#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;<commit_msg>qdsp5: audio: Check for earlysuspend support.<commit_after>/* arch/arm/mach-msm/audio_ac3.c
 *
 * Copyright (c) 2008-2009, 2011-2013 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 <asm/atomic.h>
#include <asm/ioctls.h>

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#include <linux/kthread.h>
#include <linux/wait.h>
#include <linux/dma-mapping.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/list.h>
#include <linux/earlysuspend.h>
#include <linux/slab.h>
#include <linux/msm_audio.h>
#include <linux/memory_alloc.h>
#include <linux/msm_audio_ac3.h>
#include <linux/msm_ion.h>

#include <mach/msm_adsp.h>
#include <mach/iommu.h>
#include <mach/iommu_domains.h>
#include <mach/qdsp5/qdsp5audppcmdi.h>
#include <mach/qdsp5/qdsp5audppmsg.h>
#include <mach/qdsp5/qdsp5audpp.h>
#include <mach/qdsp5/qdsp5audplaycmdi.h>
#include <mach/qdsp5/qdsp5audplaymsg.h>
#include <mach/qdsp5/qdsp5rmtcmdi.h>
#include <mach/debug_mm.h>
#include <mach/msm_memtypes.h>

#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);
#ifdef CONFIG_HAS_EARLYSUSPEND
static void audac3_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_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;
{'fraction_non_alphanumeric': 0.0872875921769798, 'fraction_numerical': 0.019477396601474833, 'mean_word_length': 4.852251407129456, 'pattern_counts': {'":': 0, '<': 65, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4992950', 'n_tokens_mistral': 4713, 'n_tokens_neox': 4565, 'n_words': 1301}