/* must be called with audio->lock held */
static int audio_enable(struct audio *audio)
{
	struct audmgr_config cfg;
	int rc;

	pr_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) {
		pr_err("audio_mp3: audmgr_enable() failed\n");
		audio_allow_sleep(audio);
		return rc;
	}

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

	if (msm_adsp_enable(audio->audplay)) {
		pr_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)) {
		pr_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;
}
/* 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;
}
/* 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;
}
/* must be called with audio->lock held */
static int audio_disable(struct audio *audio)
{
	if (audio->enabled) {
		pr_info("audio_mp3_disable()\n");
		audio->enabled = 0;
		auddec_dsp_config(audio, 0);
		wake_up(&audio->wait);
		audpp_disable(audio->dec_id, audio);
		msm_adsp_disable(audio->audplay);
		msm_adsp_put(audio->audplay);
		audmgr_disable(&audio->audmgr);
		atomic_set(&audio->image_swap, 0);
		audio->sent_bytes = 0;
		audio->consumed_bytes = 0;
		audio->total_consumed_bytes = 0;
		audio->out_needed = 0;
		audio->paused = 0;
		audio_allow_sleep(audio);
		htc_pwrsink_audio_set(PWRSINK_AUDIO_MP3, 0);
	}
	return 0;
}