예제 #1
0
static void process_audmgr_callback(struct audmgr *am,
				   struct rpc_audmgr_cb_func_ptr *args,
				   int len)
{
	if (len < (sizeof(uint32_t) * 3))
		return;

	if (len == (sizeof(uint32_t) * 3)) {
		am->state = STATE_DISABLING;
		wake_up(&am->wait);
		if (am->cb)
			am->cb();
		return;
	}
	if (be32_to_cpu(args->set_to_one) != 1)
		return;

	switch (be32_to_cpu(args->status)) {
	case RPC_AUDMGR_STATUS_READY:
		if (len < sizeof(uint32_t) * 4)
			break;
		am->handle = be32_to_cpu(args->u.handle);
		MM_AUD_INFO("audmgr: rpc READY handle=0x%08x\n", am->handle);
		break;
	case RPC_AUDMGR_STATUS_CODEC_CONFIG: {
		uint32_t volume;
		if (len < sizeof(uint32_t) * 4)
			break;
		volume = be32_to_cpu(args->u.volume);
		MM_AUD_INFO("audmgr: rpc CODEC_CONFIG volume=0x%08x\n", volume);
		am->state = STATE_ENABLED;
		wake_up(&am->wait);
		if (am->cb)
			am->cb();
		break;
	}
	case RPC_AUDMGR_STATUS_PENDING:
		MM_AUD_ERR("audmgr: PENDING?\n");
		break;
	case RPC_AUDMGR_STATUS_SUSPEND:
		MM_AUD_ERR("audmgr: SUSPEND?\n");
		break;
	case RPC_AUDMGR_STATUS_FAILURE:
		MM_AUD_ERR("audmgr: FAILURE\n");
		break;
	case RPC_AUDMGR_STATUS_VOLUME_CHANGE:
		MM_AUD_ERR("audmgr: VOLUME_CHANGE?\n");
		break;
	case RPC_AUDMGR_STATUS_DISABLED:
		MM_AUD_INFO("audmgr: DISABLED\n");
		am->state = STATE_DISABLED;
		wake_up(&am->wait);
		break;
	case RPC_AUDMGR_STATUS_ERROR:
		MM_AUD_ERR("audmgr: ERROR?\n");
		break;
	default:
		break;
	}
}
예제 #2
0
파일: adsp.c 프로젝트: bsmitty83/B-Team4.3
void msm_adsp_put(struct msm_adsp_module *module)
{
	unsigned long flags;

	mutex_lock(&module->lock);
	if (module->ops) {
		MM_AUD_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_AUD_INFO("disabling module %s\n", module->name);
			mutex_unlock(&module->lock);
			msm_adsp_disable(module);
			return;
		}
	} else {
		MM_AUD_INFO("module %s is already closed\n", module->name);
	}
	mutex_unlock(&module->lock);
}
예제 #3
0
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_AUD_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_AUD_INFO("unexpected message from afe \n");
	}

	return;
}
예제 #4
0
/* ------------------- 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_AUD_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;
	}
	case ADSP_MESSAGE_ID:
		MM_AUD_INFO("audpre: enable/disable done\n");
		break;
	default:
		MM_AUD_INFO("Unknown Event id %d\n", id);
	}
}
예제 #5
0
static void __exit afe_exit(void)
{
	MM_AUD_INFO("AFE driver exit\n");
	if (the_afe_state.mod)
		msm_adsp_put(the_afe_state.mod);
	return;
}
예제 #6
0
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));

	switch (id) {
	case AUDPLAY_MSG_STREAM_INFO:
		/* only for AAC playback */
		break;
	case AUDPLAY_MSG_DEC_NEEDS_DATA:
		if (!atomic_read(&audio->curr_img)) {
			audplay_send_data(audio, 1);
		} else {
			audio->dsp_free_len = msg[3] - 2;
			audio->dsp_write_ptr = (uint16_t *)
						adsp_rtos_phy_to_vir(msg[4],
								MSM_AD5_BASE);
			audio->dsp_start_ptr = (uint16_t *)
						adsp_rtos_phy_to_vir(msg[5],
								MSM_AD5_BASE);
			audio->dsp_buf_size = msg[6];
			audplay_send_lp_data(audio, 1);
		}
		break;
	case ADSP_MESSAGE_ID:
		MM_AUD_INFO("audplay: module enabled\n");
		break;
	default:
		MM_AUD_ERR("mp3: unexpected message from decoder\n");
		break;
	}
}
예제 #7
0
int afe_enable(u8 path_id, struct msm_afe_config *config)
{
	struct msm_afe_state *afe = &the_afe_state;
	int rc;

	if (path_id < AFE_HW_PATH_CODEC_RX ||
	    path_id > AFE_HW_PATH_MI2S_TX) {
		MM_AUD_ERR("invalid path id %d\n", path_id);
		return -EINVAL;
	}

	MM_AUD_INFO("%s: path %d\n", __func__, path_id);
	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_AUD_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_AUD_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;
			}
		}

	} else {
		rc = 0;
		afe->in_use++;
	}

	mutex_unlock(&afe->lock);
	return rc;

error_adsp_enable:
	msm_adsp_put(afe->mod);
error_adsp_get:
	mutex_unlock(&afe->lock);
	return rc;
}
예제 #8
0
/* must be called with audio->lock held */
static int audio_enable(struct audio *audio)
{
	struct audmgr_config cfg;
	int rc;

	MM_AUD_INFO("audio_mp3_enable()\n");

	if (audio->enabled)
		return 0;

	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_MP3;
	cfg.snd_method = RPC_SND_METHOD_MIDI;

	audio_prevent_sleep(audio);
	audio->audmgr.cb = audio_mp3_audmgr_cb;
	rc = audmgr_enable(&audio->audmgr, &cfg);
	if (rc < 0) {
		MM_AUD_ERR("audio_mp3: audmgr_enable() failed\n");
		audio_allow_sleep(audio);
		return rc;
	}

	if (msm_adsp_get("AUDPLAY0TASK", &audio->audplay,
				&audplay_adsp_ops, audio)) {
		MM_AUD_ERR("audio_mp3: failed to get audplay0 dsp module\n");
		goto err_get_adsp;
	}

	if (msm_adsp_enable(audio->audplay)) {
		MM_AUD_ERR("audio_mp3: msm_adsp_enable(audplay) failed\n");
		goto err_enable_adsp;
	}

	if (audpp_enable(audio->dec_id, audio_dsp_event,
				audio_modem_event, audio)) {
		MM_AUD_ERR("audio_mp3: audpp_enable() failed\n");
		goto err_enable_audpp;
	}

	atomic_set(&audio->image_swap, 0);
	audio->enabled = 1;
	htc_pwrsink_audio_set(PWRSINK_AUDIO_MP3, 100);
	return 0;

err_enable_audpp:
	msm_adsp_disable(audio->audplay);
err_enable_adsp:
	msm_adsp_put(audio->audplay);
err_get_adsp:
	audmgr_disable(&audio->audmgr);
	audio_allow_sleep(audio);
	return -ENODEV;
}
예제 #9
0
int lpa_cmd_enable_codec(struct lpa_drv *lpa, bool enable)
{
	u32 val;
	struct lpa_mem_bank_select mem_bank;

	MM_AUD_INFO(" %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_AUD_INFO("LPA codec is enabled\n");
	} else {
		if (val & LPA_OBUF_CODEC_CODEC_INTF_EN_BMSK) {
			lpa_enable_codec(lpa, 0);
			MM_AUD_INFO("LPA codec is disabled\n");
		} else
			MM_AUD_ERR("LPA codec is already disable\n");
	}
	return 0;
}
예제 #10
0
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_AUD_INFO("audpre: CFG ENABLED\n");
				audio_dsp_set_agc(audio);
				audio_dsp_set_ns(audio);
				audio_dsp_set_tx_iir(audio);
				audio_in_encoder_config(audio);
			} else {
				MM_AUD_INFO("audrec: CFG SLEEP\n");
				audio->running = 0;
			}
		} else {
			MM_AUD_INFO("audrec: CMD_CFG_DONE %x\n", msg[0]);
		}
		break;
	case AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG: {
		MM_AUD_INFO("audrec: PARAM CFG DONE\n");
		audio->running = 1;
		break;
	}
	case AUDREC_MSG_FATAL_ERR_MSG:
		MM_AUD_ERR("audrec: 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_AUD_INFO("audrec: module enabled\n");
		break;
	default:
		MM_AUD_ERR("audrec: unknown event %d\n", id);
	}
}
예제 #11
0
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_AUD_INFO("%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_AUD_INFO("%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));
}
예제 #12
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];
	MM_AUD_INFO("%s %d\n", __func__, id);
	getevent(msg, sizeof(msg));

	switch (id) {
	case AUDPREPROC_MSG_CMD_CFG_DONE_MSG:
		MM_AUD_INFO("audpre: type %d, status_flag %d\n", msg[0], msg[1]);
		break;
	case AUDPREPROC_MSG_ERROR_MSG_ID:
		MM_AUD_INFO("audpre: err_index %d\n", msg[0]);
		break;
	case ADSP_MESSAGE_ID:
		MM_AUD_INFO("audpre: module enabled\n");
		break;
	default:
		MM_AUD_ERR("audpre: unknown event %d\n", id);
	}
}
예제 #13
0
static int audio_dsp_set_tx_iir(struct audio_in *audio)
{
	struct audpre_cmd_iir_config_type cmd;

	memset(&cmd, 0, sizeof(cmd));
	cmd.cmd_id = AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS;

	if (audio->iir_enable) {
		cmd.active_flag = AUDPREPROC_CMD_IIR_ACTIVE_FLAG_ENA;
		cmd.num_bands = audio->iir.num_bands;
		memcpy(&cmd.iir_params, &audio->iir.iir_params,
				sizeof(audio->iir.iir_params));
	} else {
		cmd.active_flag = AUDPREPROC_CMD_IIR_ACTIVE_FLAG_DIS;
	}
#if DEBUG
	MM_AUD_INFO("cmd_id = 0x%04x\n", cmd.cmd_id);
	MM_AUD_INFO("active_flag = 0x%04x\n", cmd.active_flag);
#endif
	return audio_send_queue_pre(audio, &cmd, sizeof(cmd));
}
예제 #14
0
static int audio_dsp_set_iir(struct audio_in *audio)
{
	audpreproc_cmd_cfg_iir_tuning_filter_params cmd;

	memset(&cmd, 0, sizeof(cmd));

	cmd.cmd_id = AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS;

	if (audio->iir_enable)
		
		cmd.active_flag = AUDPREPROC_CMD_IIR_ACTIVE_FLAG_ENA;
	else
		cmd.active_flag = AUDPREPROC_CMD_IIR_ACTIVE_FLAG_DIS;

#if DEBUG
	MM_AUD_INFO("cmd_id = 0x%04x\n", cmd.cmd_id);
	MM_AUD_INFO("active_flag = 0x%04x\n", cmd.active_flag);
#endif

	return audpreproc_dsp_set_iir(&cmd, sizeof(cmd));
}
예제 #15
0
파일: adsp.c 프로젝트: bsmitty83/B-Team4.3
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_AUD_INFO("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_AUD_ERR("REGISTER_APP failed\n");
		mutex_unlock(&module->lock);
		goto done;
	}

	MM_AUD_INFO("module %s has been registered\n", module->name);

done:
	return rc;
}
예제 #16
0
static void audpre_dsp_event(void *data, unsigned id,  void *event_data)
{

	uint16_t *msg = event_data;

	if (!msg)
		return;

	switch (id) {
	case AUDPREPROC_MSG_CMD_CFG_DONE_MSG:
		MM_AUD_INFO("audpre: type %d, status_flag %d\n", msg[0], msg[1]);
		break;
	case AUDPREPROC_MSG_ERROR_MSG_ID:
		MM_AUD_INFO("audpre: err_index %d\n", msg[0]);
		break;
	case ADSP_MESSAGE_ID:
		MM_AUD_INFO("audpre: module enabled\n");
		break;
	default:
		MM_AUD_ERR("audpre: unknown event %d\n", id);
	}
}
예제 #17
0
static int __init afe_init(void)
{
	struct msm_afe_state *afe = &the_afe_state;

	MM_AUD_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);

	return 0;
}
예제 #18
0
int msm_set_voice_mute(int dir, int mute)
{
	MM_AUD_INFO("dir %x mute %x\n", dir, mute);
	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{
		routing_info.rx_mute = mute;
		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG,
			routing_info.voice_rx_dev_id, SESSION_IGNORE);
	}
	return 0;
}
예제 #19
0
int afe_disable(u8 path_id)
{
	struct msm_afe_state *afe = &the_afe_state;
	int rc;

	if (path_id < AFE_HW_PATH_CODEC_RX ||
	    path_id > AFE_HW_PATH_MI2S_TX) {
		MM_AUD_ERR("invalid path id %d\n", path_id);
		return -EINVAL;
	}

	mutex_lock(&afe->lock);

	BUG_ON(!afe->in_use);
	MM_AUD_INFO("%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_AUD_ERR("AFE failed to respond within %d ms\n",
				AFE_MAX_TIMEOUT);
		rc = -1;
	} else
		rc = 0;
	afe->in_use--;
	MM_AUD_INFO("%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;
	}
	mutex_unlock(&afe->lock);
	return rc;
}
예제 #20
0
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_AUD_INFO("%s : device not intilized.\n", __func__);
		return  -EINVAL;
	}

	icodec = dev_info->private_data;

	if (!(icodec->data->dev_vol_type & (SNDDEV_DEV_VOL_DIGITAL
				| SNDDEV_DEV_VOL_ANALOG))) {

		MM_AUD_INFO("%s : device %s does not support device volume "
				"control.", __func__, dev_info->name);
		return -EPERM;
	}
	dev_info->dev_volume =  volume;

	if (icodec->data->capability & SNDDEV_CAP_RX)
		lock = &drv->rx_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;
}
예제 #21
0
파일: adsp.c 프로젝트: bsmitty83/B-Team4.3
int msm_adsp_write(struct msm_adsp_module *module, unsigned dsp_queue_addr,
			void *cmd_buf, size_t cmd_size)
{
	int rc, retries = 0;
	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_AUD_INFO("%s command took %d attempts: rc %d\n",
			module->name, retries, rc);
	return rc;
}
예제 #22
0
/* ------------------- 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_AUD_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("audrec: enable/disable done\n");
		break;
	default:
		MM_AUD_INFO("Unknown Event id %d\n", id);
	}
}
예제 #23
0
static int audio_dsp_set_ns(struct audio_in *audio)
{
	audpreproc_cmd_cfg_ns_params cmd;

	memset(&cmd, 0, sizeof(cmd));
	cmd.cmd_id = AUDPREPROC_CMD_CFG_NS_PARAMS;

	if (audio->ns_enable) {
		/* cmd.ec_mode_new is fixed as
		0x0064 when enable from sample code */
		cmd.ec_mode_new =
			AUDPREPROC_CMD_EC_MODE_NEW_NS_ENA |
			AUDPREPROC_CMD_EC_MODE_NEW_HB_ENA |
			AUDPREPROC_CMD_EC_MODE_NEW_VA_ENA;
		memcpy(&cmd.dens_gamma_n, &audio->ns.ns_params,
				sizeof(audio->ns.ns_params));
	} else {
		cmd.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;
	}
#if DEBUG
	MM_AUD_INFO("cmd_id = 0x%04x\n", cmd.cmd_id);
	MM_AUD_INFO("ec_mode_new = 0x%04x\n", cmd.ec_mode_new);
	MM_AUD_INFO("dens_gamma_n = 0x%04x\n", cmd.dens_gamma_n);
	MM_AUD_INFO("dens_nfe_block_size = 0x%04x\n", cmd.dens_nfe_block_size);
	MM_AUD_INFO("dens_limit_ns = 0x%04x\n", cmd.dens_limit_ns);
	MM_AUD_INFO("dens_limit_ns_d = 0x%04x\n", cmd.dens_limit_ns_d);
	MM_AUD_INFO("wb_gamma_e = 0x%04x\n", cmd.wb_gamma_e);
	MM_AUD_INFO("wb_gamma_n = 0x%04x\n", cmd.wb_gamma_n);
#endif
	return audio_send_queue_pre(audio, &cmd, sizeof(cmd));
}
예제 #24
0
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_AUD_INFO("%s: Unsupported Frequency:%d\n", __func__,
								req_freq);
		}
		return rc;
}
예제 #25
0
int msm_set_voice_mute(int dir, int mute)
{
	MM_AUD_INFO("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{
		routing_info.rx_mute = mute;
		pr_aud_info("%s, rx_mute=%d\n", __func__, routing_info.rx_mute);
		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG,
			routing_info.voice_rx_dev_id, SESSION_IGNORE);
	}
	return 0;
}
/* must be called with audio->lock held */
static int audio_enable(struct audio *audio)
{
	struct audmgr_config cfg;
	int rc;

	MM_AUD_INFO("audio_enable()\n");

	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_AUD_ERR("audio: audpp_enable() failed\n");
		audmgr_disable(&audio->audmgr);
		audio_allow_sleep(audio);
		return -ENODEV;
	}

	audio->enabled = 1;
	htc_pwrsink_audio_set(PWRSINK_AUDIO_PCM, 100);
	return 0;
}
예제 #27
0
파일: adsp.c 프로젝트: bsmitty83/B-Team4.3
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_AUD_INFO("q_idx: %d is not a valid queue \
					for module %x\n", q_idx, mod_id);
				return -EINVAL;
			}
	MM_AUD_INFO("cmd_buf size is more than allowed size\n");
	return -EINVAL;
}
/* 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) {
		MM_AUD_INFO("audio_disable()\n");
		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);
		htc_pwrsink_audio_set(PWRSINK_AUDIO_PCM, 0);
	}
	return 0;
}
예제 #29
0
static int lpa_probe(struct platform_device *pdev)
{
	int rc = 0;
	struct resource *mem_src;
	struct msm_lpa_platform_data *pdata;

	MM_AUD_INFO("lpa probe\n");

	if (!pdev || !pdev->dev.platform_data) {
		MM_AUD_ERR("no plaform data\n");
		rc = -ENODEV;
		goto error;
	}

	mem_src = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpa");
	if (!mem_src) {
		MM_AUD_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;

}
예제 #30
0
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;
	MM_AUD_INFO("snddev_icodec_close: device %s\n", dev_info->name);

	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 {
		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;
}