/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <alsa/asoundlib.h>
#include <limits.h>
#include <stdlib.h>
#include <syslog.h>

#include "cras_alsa_helpers.h"
#include "cras_audio_format.h"
#include "cras_util.h"

/* Macro to convert between snd_pcm_chmap_position(defined in
 * alsa-lib since 1.0.27) and CRAS_CHANNEL, values of which are
 * of the same order but shifted by 3.
 */
#define CH_TO_ALSA(ch) ((ch) + (3))
#define CH_TO_CRAS(ch) ((ch) - (3))

/* Assert the channel is defined in CRAS_CHANNELS. */
#define ALSA_CH_VALID(ch) ((ch >= SND_CHMAP_FL) && (ch <= SND_CHMAP_FRC))

/* Time difference between two consecutive underrun logs. */
#define UNDERRUN_LOG_TIME_SECS 30

/* Limit the number of channels supported for devices: b/158509536 */
#define TEMP_CHANNEL_LIMIT 20

/* Chances to give mmap_begin to work. */
static const size_t MAX_MMAP_BEGIN_ATTEMPTS = 3;
/* Time to sleep between resume attempts. */
static const size_t ALSA_SUSPENDED_SLEEP_TIME_US = 250000;

/* What rates should we check for on this dev?
 * Listed in order of preference. 0 terminalted. */
static const size_t test_sample_rates[] = {
	44100, 48000, 32000, 96000, 22050, 16000, 8000, 4000, 192000, 0,
};

/* What channel counts shoud be checked on this dev?
 * Listed in order of preference. 0 terminalted. */
static const size_t test_channel_counts[] = { 10, 6, 4, 2, 1, 8, 0 };

static const snd_pcm_format_t test_formats[] = {
	SND_PCM_FORMAT_S16_LE, SND_PCM_FORMAT_S24_LE, SND_PCM_FORMAT_S32_LE,
	SND_PCM_FORMAT_S24_3LE, (snd_pcm_format_t)0
};

/* Looks up the list of channel map for the one can exactly matches
 * the layout specified in fmt.
 */
static snd_pcm_chmap_query_t *
cras_chmap_caps_match(snd_pcm_chmap_query_t **chmaps,
		      struct cras_audio_format *fmt)
{
	size_t ch, i;
	int idx, matches;
	snd_pcm_chmap_query_t **chmap;

	/* Search for channel map that already matches the order */
	for (chmap = chmaps; *chmap; chmap++) {
		if ((*chmap)->map.channels != fmt->num_channels)
			continue;

		matches = 1;
		for (ch = 0; ch < CRAS_CH_MAX; ch++) {
			idx = fmt->channel_layout[ch];
			if (idx == -1)
				continue;
			if ((unsigned)idx >= (*chmap)->map.channels)
				continue;
			if ((*chmap)->map.pos[idx] != CH_TO_ALSA(ch)) {
				matches = 0;
				break;
			}
		}
		if (matches)
			return *chmap;
	}

	/* Search for channel map that can arbitrarily swap order */
	for (chmap = chmaps; *chmap; chmap++) {
		if ((*chmap)->type == SND_CHMAP_TYPE_FIXED ||
		    (*chmap)->map.channels != fmt->num_channels)
			continue;

		matches = 1;
		for (ch = 0; ch < CRAS_CH_MAX; ch++) {
			idx = fmt->channel_layout[ch];
			if (idx == -1)
				continue;
			int found = 0;
			for (i = 0; i < fmt->num_channels; i++) {
				if ((*chmap)->map.pos[i] == CH_TO_ALSA(ch)) {
					found = 1;
					break;
				}
			}
			if (found == 0) {
				matches = 0;
				break;
			}
		}
		if (matches && (*chmap)->type == SND_CHMAP_TYPE_VAR)
			return *chmap;

		/* Check if channel map is a match by arbitrarily swap
		 * pair order */
		matches = 1;
		for (i = 0; i < fmt->num_channels; i += 2) {
			ch = CH_TO_CRAS((*chmap)->map.pos[i]);
			if (fmt->channel_layout[ch] & 0x01) {
				matches = 0;
				break;
			}

			if (fmt->channel_layout[ch] + 1 !=
			    fmt->channel_layout[CH_TO_CRAS(
				    (*chmap)->map.pos[i + 1])]) {
				matches = 0;
				break;
			}
		}
		if (matches)
			return *chmap;
	}

	return NULL;
}

/* When the exact match does not exist, select the best valid
 * channel map which can be supported by means of channel conversion
 * matrix.
 */
static snd_pcm_chmap_query_t *
cras_chmap_caps_conv_matrix(snd_pcm_chmap_query_t **chmaps,
			    struct cras_audio_format *fmt)
{
	float **conv_mtx;
	size_t i;
	snd_pcm_chmap_query_t **chmap;
	struct cras_audio_format *conv_fmt;

	conv_fmt = cras_audio_format_create(fmt->format, fmt->frame_rate,
					    fmt->num_channels);

	for (chmap = chmaps; *chmap; chmap++) {
		if ((*chmap)->map.channels != fmt->num_channels)
			continue;
		for (i = 0; i < CRAS_CH_MAX; i++)
			conv_fmt->channel_layout[i] = -1;
		for (i = 0; i < conv_fmt->num_channels; i++) {
			if (!ALSA_CH_VALID((*chmap)->map.pos[i]))
				continue;
			conv_fmt->channel_layout[CH_TO_CRAS(
				(*chmap)->map.pos[i])] = i;
		}

		/* Examine channel map by test creating a conversion matrix
		 * for each candidate. Once a non-null matrix is created,
		 * that channel map is considered supported and select it as
		 * the best match one.
		 */
		conv_mtx = cras_channel_conv_matrix_create(fmt, conv_fmt);
		if (conv_mtx) {
			cras_channel_conv_matrix_destroy(
				conv_mtx, conv_fmt->num_channels);
			cras_audio_format_destroy(conv_fmt);
			return *chmap;
		}
	}

	cras_audio_format_destroy(conv_fmt);
	return NULL;
}

/* Finds the best channel map for given format and list of channel
 * map capability.
 */
static snd_pcm_chmap_query_t *
cras_chmap_caps_best(snd_pcm_t *handle, snd_pcm_chmap_query_t **chmaps,
		     struct cras_audio_format *fmt)
{
	snd_pcm_chmap_query_t **chmap;
	snd_pcm_chmap_query_t *match;

	match = cras_chmap_caps_match(chmaps, fmt);
	if (match)
		return match;

	match = cras_chmap_caps_conv_matrix(chmaps, fmt);
	if (match)
		return match;

	/* For capture stream, choose the first chmap matching channel
	 * count. Channel positions reported in this chmap will be used
	 * to fill correspond channels into client stream.
	 */
	if (snd_pcm_stream(handle) == SND_PCM_STREAM_CAPTURE)
		for (chmap = chmaps; *chmap; chmap++)
			if ((*chmap)->map.channels == fmt->num_channels)
				return *chmap;
	return NULL;
}

int cras_alsa_pcm_open(snd_pcm_t **handle, const char *dev,
		       snd_pcm_stream_t stream)
{
	int rc;
	int retries = 3;
	static const unsigned int OPEN_RETRY_DELAY_US = 100000;

retry_open:
	rc = snd_pcm_open(handle, dev, stream,
			  SND_PCM_NONBLOCK | SND_PCM_NO_AUTO_RESAMPLE |
				  SND_PCM_NO_AUTO_CHANNELS |
				  SND_PCM_NO_AUTO_FORMAT);
	if (rc == -EBUSY && --retries) {
		usleep(OPEN_RETRY_DELAY_US);
		goto retry_open;
	}

	return rc;
}

int cras_alsa_pcm_close(snd_pcm_t *handle)
{
	return snd_pcm_close(handle);
}

int cras_alsa_pcm_start(snd_pcm_t *handle)
{
	return snd_pcm_start(handle);
}

int cras_alsa_pcm_drain(snd_pcm_t *handle)
{
	return snd_pcm_drain(handle);
}

int cras_alsa_resume_appl_ptr(snd_pcm_t *handle, snd_pcm_uframes_t ahead)
{
	int rc;
	snd_pcm_uframes_t period_frames, buffer_frames;
	snd_pcm_sframes_t to_move, avail_frames;
	rc = snd_pcm_avail(handle);
	if (rc == -EPIPE || rc == -ESTRPIPE) {
		cras_alsa_attempt_resume(handle);
		avail_frames = 0;
	} else if (rc < 0) {
		syslog(LOG_ERR, "Fail to get avail frames: %s",
		       snd_strerror(rc));
		return rc;
	} else {
		avail_frames = rc;
	}

	rc = snd_pcm_get_params(handle, &buffer_frames, &period_frames);
	if (rc < 0) {
		syslog(LOG_ERR, "Fail to get buffer size: %s",
		       snd_strerror(rc));
		return rc;
	}

	to_move = avail_frames - buffer_frames + ahead;
	if (to_move > 0) {
		rc = snd_pcm_forward(handle, to_move);
	} else if (to_move < 0) {
		rc = snd_pcm_rewind(handle, -to_move);
	} else {
		return 0;
	}

	if (rc < 0) {
		syslog(LOG_ERR, "Fail to resume appl_ptr: %s",
		       snd_strerror(rc));
		return rc;
	}
	return 0;
}

int cras_alsa_set_channel_map(snd_pcm_t *handle, struct cras_audio_format *fmt)
{
	size_t i, ch;
	snd_pcm_chmap_query_t **chmaps;
	snd_pcm_chmap_query_t *match;

	if (fmt->num_channels <= 2)
		return 0;

	chmaps = snd_pcm_query_chmaps(handle);
	if (chmaps == NULL) {
		syslog(LOG_WARNING, "No chmap queried! Skip chmap set");
		goto done;
	}

	match = cras_chmap_caps_best(handle, chmaps, fmt);
	if (!match) {
		syslog(LOG_ERR, "Unable to find the best channel map");
		goto done;
	}

	/* A channel map could match the layout after channels
	 * pair/arbitrary swapped. Modified the channel positions
	 * before set to HW.
	 */
	for (i = 0; i < fmt->num_channels; i++) {
		for (ch = 0; ch < CRAS_CH_MAX; ch++)
			if (fmt->channel_layout[ch] == (int)i)
				break;
		if (ch != CRAS_CH_MAX)
			match->map.pos[i] = CH_TO_ALSA(ch);
	}
	if (snd_pcm_set_chmap(handle, &match->map) != 0)
		syslog(LOG_ERR, "Unable to set channel map");

done:
	snd_pcm_free_chmaps(chmaps);
	return 0;
}

int cras_alsa_get_channel_map(snd_pcm_t *handle, struct cras_audio_format *fmt)
{
	snd_pcm_chmap_query_t **chmaps;
	snd_pcm_chmap_query_t *match;
	int rc = 0;
	size_t i;

	chmaps = snd_pcm_query_chmaps(handle);
	if (chmaps == NULL) {
		rc = -EINVAL;
		goto done;
	}

	match = cras_chmap_caps_best(handle, chmaps, fmt);
	if (!match) {
		syslog(LOG_ERR, "Unable to find the best channel map");
		rc = -1;
		goto done;
	}

	/* Fill back the selected channel map so channel converter can
	 * handle it. */
	for (i = 0; i < CRAS_CH_MAX; i++)
		fmt->channel_layout[i] = -1;
	for (i = 0; i < fmt->num_channels; i++) {
		if (!ALSA_CH_VALID(match->map.pos[i]))
			continue;
		fmt->channel_layout[CH_TO_CRAS(match->map.pos[i])] = i;
	}

	/* Handle the special channel map {SND_CHMAP_MONO} */
	if (match->map.channels == 1 && match->map.pos[0] == SND_CHMAP_MONO)
		fmt->channel_layout[CRAS_CH_FC] = 0;

done:
	snd_pcm_free_chmaps(chmaps);
	return rc;
}

int cras_alsa_fill_properties(snd_pcm_t *handle, size_t **rates,
			      size_t **channel_counts,
			      snd_pcm_format_t **formats)
{
	int rc;
	size_t i, num_found;
	snd_pcm_hw_params_t *params;

	snd_pcm_hw_params_alloca(&params);

	rc = snd_pcm_hw_params_any(handle, params);
	if (rc < 0) {
		syslog(LOG_ERR, "snd_pcm_hw_params_any: %s", snd_strerror(rc));
		return rc;
	}

	*rates = (size_t *)malloc(sizeof(test_sample_rates));
	if (*rates == NULL)
		return -ENOMEM;
	*channel_counts = (size_t *)malloc(sizeof(test_channel_counts));
	if (*channel_counts == NULL) {
		free(*rates);
		return -ENOMEM;
	}
	*formats = (snd_pcm_format_t *)malloc(sizeof(test_formats));
	if (*formats == NULL) {
		free(*channel_counts);
		free(*rates);
		return -ENOMEM;
	}

	num_found = 0;
	for (i = 0; test_sample_rates[i] != 0; i++) {
		rc = snd_pcm_hw_params_test_rate(handle, params,
						 test_sample_rates[i], 0);
		if (rc == 0)
			(*rates)[num_found++] = test_sample_rates[i];
	}
	(*rates)[num_found] = 0;
	if (num_found == 0) {
		syslog(LOG_WARNING, "No valid sample rates.");
		return -EINVAL;
	}

	num_found = 0;
	for (i = 0; test_channel_counts[i] != 0; i++) {
		rc = snd_pcm_hw_params_test_channels(handle, params,
						     test_channel_counts[i]);
		if (rc == 0)
			(*channel_counts)[num_found++] = test_channel_counts[i];
	}
	(*channel_counts)[num_found] = 0;
	if (num_found == 0) {
		// Pull the max channel count and use that.
		unsigned int max_channels = 0;
		rc = snd_pcm_hw_params_get_channels_max(params, &max_channels);
		if (rc < 0) {
			syslog(LOG_WARNING, "No valid channel counts found.");
			return -EINVAL;
		} else if (max_channels > TEMP_CHANNEL_LIMIT) {
			syslog(LOG_WARNING, "Can't support so many channels.");
			return -EINVAL;
		} else {
			(*channel_counts)[0] = (size_t)max_channels;
			(*channel_counts)[1] = 0;
		}
	}

	num_found = 0;
	for (i = 0; test_formats[i] != 0; i++) {
		rc = snd_pcm_hw_params_test_format(handle, params,
						   test_formats[i]);
		if (rc == 0)
			(*formats)[num_found++] = test_formats[i];
	}
	(*formats)[num_found] = (snd_pcm_format_t)0;
	if (num_found == 0) {
		syslog(LOG_WARNING, "No valid sample formats.");
		return -EINVAL;
	}

	return 0;
}

int cras_alsa_set_hwparams(snd_pcm_t *handle, struct cras_audio_format *format,
			   snd_pcm_uframes_t *buffer_frames, int period_wakeup,
			   unsigned int dma_period_time)
{
	unsigned int rate, ret_rate;
	int err;
	snd_pcm_hw_params_t *hwparams;

	rate = format->frame_rate;
	snd_pcm_hw_params_alloca(&hwparams);

	err = snd_pcm_hw_params_any(handle, hwparams);
	if (err < 0) {
		syslog(LOG_ERR, "hw_params_any failed %s\n", snd_strerror(err));
		return err;
	}
	/* Disable hardware resampling. */
	err = snd_pcm_hw_params_set_rate_resample(handle, hwparams, 0);
	if (err < 0) {
		syslog(LOG_ERR, "Disabling resampling %s\n", snd_strerror(err));
		return err;
	}
	/* Always interleaved. */
	err = snd_pcm_hw_params_set_access(handle, hwparams,
					   SND_PCM_ACCESS_MMAP_INTERLEAVED);
	if (err < 0) {
		syslog(LOG_ERR, "Setting interleaved %s\n", snd_strerror(err));
		return err;
	}
	/* If period_wakeup flag is not set, try to disable ALSA wakeups,
	 * we'll keep a timer. */
	if (!period_wakeup &&
	    snd_pcm_hw_params_can_disable_period_wakeup(hwparams)) {
		err = snd_pcm_hw_params_set_period_wakeup(handle, hwparams, 0);
		if (err < 0)
			syslog(LOG_WARNING, "disabling wakeups %s\n",
			       snd_strerror(err));
	}
	/* Setup the period time so that the hardware pulls the right amount
	 * of data at the right time. */
	if (dma_period_time) {
		int dir = 0;
		unsigned int original = dma_period_time;

		err = snd_pcm_hw_params_set_period_time_near(
			handle, hwparams, &dma_period_time, &dir);
		if (err < 0) {
			syslog(LOG_ERR, "could not set period time: %s",
			       snd_strerror(err));
			return err;
		} else if (original != dma_period_time) {
			syslog(LOG_DEBUG, "period time set to: %u",
			       dma_period_time);
		}
	}
	/* Set the sample format. */
	err = snd_pcm_hw_params_set_format(handle, hwparams, format->format);
	if (err < 0) {
		syslog(LOG_ERR, "set format %s\n", snd_strerror(err));
		return err;
	}
	/* Set the stream rate. */
	ret_rate = rate;
	err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &ret_rate, 0);
	if (err < 0) {
		syslog(LOG_ERR, "set_rate_near %iHz %s\n", rate,
		       snd_strerror(err));
		return err;
	}
	if (ret_rate != rate) {
		syslog(LOG_ERR, "tried for %iHz, settled for %iHz)\n", rate,
		       ret_rate);
		return -EINVAL;
	}
	/* Set the count of channels. */
	err = snd_pcm_hw_params_set_channels(handle, hwparams,
					     format->num_channels);
	if (err < 0) {
		syslog(LOG_ERR, "set_channels %s\n", snd_strerror(err));
		return err;
	}

	/* Make sure buffer frames is even, or snd_pcm_hw_params will
	 * return invalid argument error. */
	err = snd_pcm_hw_params_get_buffer_size_max(hwparams, buffer_frames);
	if (err < 0)
		syslog(LOG_WARNING, "get buffer max %s\n", snd_strerror(err));

	*buffer_frames &= ~0x01;
	err = snd_pcm_hw_params_set_buffer_size_max(handle, hwparams,
						    buffer_frames);
	if (err < 0) {
		syslog(LOG_ERR, "set_buffer_size_max %s", snd_strerror(err));
		return err;
	}

	syslog(LOG_DEBUG, "buffer size set to %u\n",
	       (unsigned int)*buffer_frames);

	/* Finally, write the parameters to the device. */
	err = snd_pcm_hw_params(handle, hwparams);
	if (err < 0) {
		syslog(LOG_ERR,
		       "hw_params: %s: rate: %u, ret_rate: %u, "
		       "channel: %zu, format: %u\n",
		       snd_strerror(err), rate, ret_rate, format->num_channels,
		       format->format);
		return err;
	}
	return 0;
}

int cras_alsa_set_swparams(snd_pcm_t *handle)
{
	int err;
	snd_pcm_sw_params_t *swparams;
	snd_pcm_uframes_t boundary;

	snd_pcm_sw_params_alloca(&swparams);

	err = snd_pcm_sw_params_current(handle, swparams);
	if (err < 0) {
		syslog(LOG_ERR, "sw_params_current: %s\n", snd_strerror(err));
		return err;
	}
	err = snd_pcm_sw_params_get_boundary(swparams, &boundary);
	if (err < 0) {
		syslog(LOG_ERR, "get_boundary: %s\n", snd_strerror(err));
		return err;
	}
	err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, boundary);
	if (err < 0) {
		syslog(LOG_ERR, "set_stop_threshold: %s\n", snd_strerror(err));
		return err;
	}
	/* Don't auto start. */
	err = snd_pcm_sw_params_set_start_threshold(handle, swparams, LONG_MAX);
	if (err < 0) {
		syslog(LOG_ERR, "set_stop_threshold: %s\n", snd_strerror(err));
		return err;
	}

	/* Disable period events. */
	err = snd_pcm_sw_params_set_period_event(handle, swparams, 0);
	if (err < 0) {
		syslog(LOG_ERR, "set_period_event: %s\n", snd_strerror(err));
		return err;
	}

	err = snd_pcm_sw_params(handle, swparams);

	if (err < 0) {
		syslog(LOG_ERR, "sw_params: %s\n", snd_strerror(err));
		return err;
	}
	return 0;
}

int cras_alsa_get_avail_frames(snd_pcm_t *handle, snd_pcm_uframes_t buf_size,
			       snd_pcm_uframes_t severe_underrun_frames,
			       const char *dev_name, snd_pcm_uframes_t *avail,
			       struct timespec *tstamp)
{
	snd_pcm_sframes_t frames;
	int rc = 0;
	static struct timespec tstamp_last_underrun_log = { .tv_sec = 0,
							    .tv_nsec = 0 };

	/* Use snd_pcm_avail still to ensure that the hardware pointer is
	 * up to date. Otherwise, we could use the deprecated snd_pcm_hwsync().
	 * IMO this is a deficiency in the ALSA API.
	 */
	frames = snd_pcm_avail(handle);
	if (frames >= 0)
		rc = snd_pcm_htimestamp(handle, avail, tstamp);
	else
		rc = frames;
	if (rc == -EPIPE || rc == -ESTRPIPE) {
		cras_alsa_attempt_resume(handle);
		rc = 0;
		goto error;
	} else if (rc < 0) {
		syslog(LOG_ERR, "pcm_avail error %s, %s\n", dev_name,
		       snd_strerror(rc));
		goto error;
	} else if (frames > (snd_pcm_sframes_t)buf_size) {
		struct timespec tstamp_now;
		clock_gettime(CLOCK_MONOTONIC_RAW, &tstamp_now);
		/* Limit the log rate. */
		if ((tstamp_now.tv_sec - tstamp_last_underrun_log.tv_sec) >
		    UNDERRUN_LOG_TIME_SECS) {
			syslog(LOG_ERR,
			       "pcm_avail returned frames larger than buf_size: "
			       "%s: %ld > %lu\n",
			       dev_name, frames, buf_size);
			tstamp_last_underrun_log.tv_sec = tstamp_now.tv_sec;
			tstamp_last_underrun_log.tv_nsec = tstamp_now.tv_nsec;
		}
		if ((frames - (snd_pcm_sframes_t)buf_size) >
		    (snd_pcm_sframes_t)severe_underrun_frames) {
			rc = -EPIPE;
			goto error;
		} else {
			frames = buf_size;
		}
	}
	*avail = frames;
	return 0;

error:
	*avail = 0;
	tstamp->tv_sec = 0;
	tstamp->tv_nsec = 0;
	return rc;
}

int cras_alsa_get_delay_frames(snd_pcm_t *handle, snd_pcm_uframes_t buf_size,
			       snd_pcm_sframes_t *delay)
{
	int rc;

	rc = snd_pcm_delay(handle, delay);
	if (rc < 0)
		return rc;
	if (*delay > (snd_pcm_sframes_t)buf_size)
		*delay = buf_size;
	if (*delay < 0)
		*delay = 0;
	return 0;
}

/*
 * Attempts to resume a PCM.
 * Note that this path does not get executed for default playback/capture
 * stream. Default playback/capture stream are removed from the device
 * upon suspend, and re-attached to the device after resume.
 * The only stream that lives across suspend resume is hotword stream.
 */
int cras_alsa_attempt_resume(snd_pcm_t *handle)
{
	int rc;

	syslog(LOG_INFO, "System suspended.");
	while ((rc = snd_pcm_resume(handle)) == -EAGAIN)
		usleep(ALSA_SUSPENDED_SLEEP_TIME_US);
	if (rc < 0) {
		/*
		 * Some devices do not support snd_pcm_resume, that is
		 * acceptable.
		 */
		syslog(LOG_INFO, "System suspended, failed to resume %s.",
		       snd_strerror(rc));
		rc = snd_pcm_prepare(handle);
		if (rc < 0) {
			syslog(LOG_ERR, "Suspended, failed to prepare: %s.",
			       snd_strerror(rc));
		}
		/*
		 * CRAS does not use auto-start (start_threshold = 0), so start
		 * PCM after it is prepared. This is only for hotword stream.
		 */
		rc = snd_pcm_start(handle);
		if (rc < 0) {
			syslog(LOG_ERR, "Suspended, failed to start: %s.",
			       snd_strerror(rc));
		}
	}
	return rc;
}

int cras_alsa_mmap_get_whole_buffer(snd_pcm_t *handle, uint8_t **dst)
{
	snd_pcm_uframes_t offset;
	/* The purpose of calling cras_alsa_mmap_begin is to get the base
	 * address of the buffer. The requested and retrieved frames are not
	 * meaningful here.
	 * However, we need to set a non-zero requested frames to get a
	 * non-zero retrieved frames. This is to avoid the error checking in
	 * snd_pcm_mmap_begin, where it judges retrieved frames being 0 as a
	 * failure.
	 */
	snd_pcm_uframes_t frames = 1;

	return cras_alsa_mmap_begin(handle, 0, dst, &offset, &frames);
}

int cras_alsa_mmap_begin(snd_pcm_t *handle, unsigned int format_bytes,
			 uint8_t **dst, snd_pcm_uframes_t *offset,
			 snd_pcm_uframes_t *frames)
{
	int rc;
	unsigned int attempts = 0;
	const snd_pcm_channel_area_t *my_areas;

	while (attempts++ < MAX_MMAP_BEGIN_ATTEMPTS) {
		rc = snd_pcm_mmap_begin(handle, &my_areas, offset, frames);
		if (rc == -ESTRPIPE) {
			/* First handle suspend/resume. */
			rc = cras_alsa_attempt_resume(handle);
			if (rc < 0)
				return rc;
			continue; /* Recovered from suspend, try again. */
		} else if (rc < 0) {
			/* If we can recover, continue and try again. */
			if (snd_pcm_recover(handle, rc, 0) == 0)
				continue;
			syslog(LOG_INFO, "recover failed begin: %s\n",
			       snd_strerror(rc));
			return rc;
		}
		/* Available frames could be zero right after input pcm handle
		 * resumed. As for output pcm handle, some error has occurred
		 * when mmap_begin return zero frames, return -EIO for that
		 * case.
		 */
		if (snd_pcm_stream(handle) == SND_PCM_STREAM_PLAYBACK &&
		    *frames == 0) {
			syslog(LOG_INFO, "mmap_begin set frames to 0.");
			return -EIO;
		}
		*dst = (uint8_t *)my_areas[0].addr + (*offset) * format_bytes;
		return 0;
	}
	return -EIO;
}

int cras_alsa_mmap_commit(snd_pcm_t *handle, snd_pcm_uframes_t offset,
			  snd_pcm_uframes_t frames)
{
	int rc;
	snd_pcm_sframes_t res;

	res = snd_pcm_mmap_commit(handle, offset, frames);
	if (res != (snd_pcm_sframes_t)frames) {
		res = res >= 0 ? (int)-EPIPE : res;
		if (res == -ESTRPIPE) {
			/* First handle suspend/resume. */
			rc = cras_alsa_attempt_resume(handle);
			if (rc < 0)
				return rc;
		} else {
			/* If we can recover, continue and try again. */
			rc = snd_pcm_recover(handle, res, 0);
			if (rc < 0) {
				syslog(LOG_ERR,
				       "mmap_commit: pcm_recover failed: %s\n",
				       snd_strerror(rc));
				return rc;
			}
		}
	}
	return 0;
}
