/**
 * \file pcm/pcm_hw.c
 * \ingroup PCM_Plugins
 * \brief PCM HW Plugin Interface
 * \author Abramo Bagnara <abramo@alsa-project.org>
 * \author Jaroslav Kysela <perex@perex.cz>
 * \date 2000-2001
 */
/*
 *  PCM - Hardware
 *  Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
 *
 *
 *   This library is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as
 *   published by the Free Software Foundation; either version 2.1 of
 *   the License, or (at your option) any later version.
 *
 *   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 Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with this library; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 */
  
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include "pcm_local.h"
#include "../control/control_local.h"
#include "../timer/timer_local.h"

//#define DEBUG_RW		/* use to debug readi/writei/readn/writen */
//#define DEBUG_MMAP		/* debug mmap_commit */

#ifndef PIC
/* entry for static linking */
const char *_snd_module_pcm_hw = "";
#endif

#ifndef DOC_HIDDEN

#ifndef F_SETSIG
#define F_SETSIG 10
#endif

/*
 *  Compatibility
 */

struct sndrv_pcm_hw_params_old {
	unsigned int flags;
	unsigned int masks[SNDRV_PCM_HW_PARAM_SUBFORMAT -
			   SNDRV_PCM_HW_PARAM_ACCESS + 1];
	struct snd_interval intervals[SNDRV_PCM_HW_PARAM_TICK_TIME -
					SNDRV_PCM_HW_PARAM_SAMPLE_BITS + 1];
	unsigned int rmask;
	unsigned int cmask;
	unsigned int info;
	unsigned int msbits;
	unsigned int rate_num;
	unsigned int rate_den;
	sndrv_pcm_uframes_t fifo_size;
	unsigned char reserved[64];
};

#define SND_PCM_IOCTL_HW_REFINE_OLD _IOWR('A', 0x10, struct sndrv_pcm_hw_params_old)
#define SND_PCM_IOCTL_HW_PARAMS_OLD _IOWR('A', 0x11, struct sndrv_pcm_hw_params_old)

static int use_old_hw_params_ioctl(int fd, unsigned int cmd, snd_pcm_hw_params_t *params);
static snd_pcm_sframes_t snd_pcm_hw_avail_update(snd_pcm_t *pcm);
static const snd_pcm_fast_ops_t snd_pcm_hw_fast_ops;
static const snd_pcm_fast_ops_t snd_pcm_hw_fast_ops_timer;

/*
 *
 */

typedef struct {
	int version;
	int fd;
	int card, device, subdevice;
	int sync_ptr_ioctl;
	volatile struct snd_pcm_mmap_status * mmap_status;
	struct snd_pcm_mmap_control *mmap_control;
	struct snd_pcm_sync_ptr *sync_ptr;
	int period_event;
	snd_timer_t *period_timer;
	struct pollfd period_timer_pfd;
	int period_timer_need_poll;
	/* restricted parameters */
	snd_pcm_format_t format;
	int rate;
	int channels;
	/* for chmap */
	unsigned int chmap_caps;
	snd_pcm_chmap_query_t **chmap_override;
} snd_pcm_hw_t;

#define SNDRV_FILE_PCM_STREAM_PLAYBACK		ALSA_DEVICE_DIRECTORY "pcmC%iD%ip"
#define SNDRV_FILE_PCM_STREAM_CAPTURE		ALSA_DEVICE_DIRECTORY "pcmC%iD%ic"
#define SNDRV_PCM_VERSION_MAX			SNDRV_PROTOCOL_VERSION(2, 0, 9)

/* update appl_ptr with driver */
#define FAST_PCM_STATE(hw) \
	((snd_pcm_state_t) (hw)->mmap_status->state)
#define FAST_PCM_TSTAMP(hw) \
	((hw)->mmap_status->tstamp)

struct timespec snd_pcm_hw_fast_tstamp(snd_pcm_t *pcm)
{
	struct timespec res;
	snd_pcm_hw_t *hw = pcm->private_data;
	res = FAST_PCM_TSTAMP(hw);
	if (SNDRV_PROTOCOL_VERSION(2, 0, 5) > hw->version)
		res.tv_nsec *= 1000L;
	return res;
}
#endif /* DOC_HIDDEN */

static int sync_ptr1(snd_pcm_hw_t *hw, unsigned int flags)
{
	int err;
	hw->sync_ptr->flags = flags;
	err = ioctl((hw)->fd, SNDRV_PCM_IOCTL_SYNC_PTR, (hw)->sync_ptr);
	if (err < 0) {
		err = -errno;
		SYSMSG("SNDRV_PCM_IOCTL_SYNC_PTR failed (%i)", err);
		return err;
	}
	return 0;
}

static inline int sync_ptr(snd_pcm_hw_t *hw, unsigned int flags)
{
	return hw->sync_ptr ? sync_ptr1(hw, flags) : 0;
}

static int snd_pcm_hw_clear_timer_queue(snd_pcm_hw_t *hw)
{
	if (hw->period_timer_need_poll) {
		while (poll(&hw->period_timer_pfd, 1, 0) > 0) {
			snd_timer_tread_t rbuf[4];
			snd_timer_read(hw->period_timer, rbuf, sizeof(rbuf));
		}
	} else {
		snd_timer_tread_t rbuf[4];
		snd_timer_read(hw->period_timer, rbuf, sizeof(rbuf));
	}
	return 0;
}

static int snd_pcm_hw_poll_descriptors_count(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
{
	return 2;
}

static int snd_pcm_hw_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space)
{
	snd_pcm_hw_t *hw = pcm->private_data;

	if (space < 2)
		return -ENOMEM;
	pfds[0].fd = hw->fd;
	pfds[0].events = pcm->poll_events | POLLERR | POLLNVAL;
	pfds[1].fd = hw->period_timer_pfd.fd;
	pfds[1].events = POLLIN | POLLERR | POLLNVAL;
	return 2;
}

static int snd_pcm_hw_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned nfds, unsigned short *revents)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	unsigned int events;

	if (nfds != 2 || pfds[0].fd != hw->fd || pfds[1].fd != hw->period_timer_pfd.fd)
		return -EINVAL;
	events = pfds[0].revents;
	if (pfds[1].revents & POLLIN) {
		snd_pcm_hw_clear_timer_queue(hw);
		events |= pcm->poll_events & ~(POLLERR|POLLNVAL);
	}
	*revents = events;
	return 0;
}

static int snd_pcm_hw_nonblock(snd_pcm_t *pcm, int nonblock)
{
	long flags;
	snd_pcm_hw_t *hw = pcm->private_data;
	int fd = hw->fd, err;

	if ((flags = fcntl(fd, F_GETFL)) < 0) {
		err = -errno;
		SYSMSG("F_GETFL failed (%i)", err);
		return err;
	}
	if (nonblock)
		flags |= O_NONBLOCK;
	else
		flags &= ~O_NONBLOCK;
	if (fcntl(fd, F_SETFL, flags) < 0) {
		err = -errno;
		SYSMSG("F_SETFL for O_NONBLOCK failed (%i)", err);
		return err;
	}
	return 0;
}

static int snd_pcm_hw_async(snd_pcm_t *pcm, int sig, pid_t pid)
{
	long flags;
	snd_pcm_hw_t *hw = pcm->private_data;
	int fd = hw->fd, err;

	if ((flags = fcntl(fd, F_GETFL)) < 0) {
		err = -errno;
		SYSMSG("F_GETFL failed (%i)", err);
		return err;
	}
	if (sig >= 0)
		flags |= O_ASYNC;
	else
		flags &= ~O_ASYNC;
	if (fcntl(fd, F_SETFL, flags) < 0) {
		err = -errno;
		SYSMSG("F_SETFL for O_ASYNC failed (%i)", err);
		return err;
	}
	if (sig < 0)
		return 0;
	if (fcntl(fd, F_SETSIG, (long)sig) < 0) {
		err = -errno;
		SYSMSG("F_SETSIG failed (%i)", err);
		return err;
	}
	if (fcntl(fd, F_SETOWN, (long)pid) < 0) {
		err = -errno;
		SYSMSG("F_SETOWN failed (%i)", err);
		return err;
	}
	return 0;
}

static int snd_pcm_hw_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	int fd = hw->fd, err;
	if (ioctl(fd, SNDRV_PCM_IOCTL_INFO, info) < 0) {
		err = -errno;
		SYSMSG("SNDRV_PCM_IOCTL_INFO failed (%i)", err);
		return err;
	}
	return 0;
}

static inline int hw_refine_call(snd_pcm_hw_t *pcm_hw, snd_pcm_hw_params_t *params)
{
	/* check for new hw_params structure; it's available from 2.0.2 version of PCM API */
	if (SNDRV_PROTOCOL_VERSION(2, 0, 2) <= pcm_hw->version)
		return ioctl(pcm_hw->fd, SNDRV_PCM_IOCTL_HW_REFINE, params);
	return use_old_hw_params_ioctl(pcm_hw->fd, SND_PCM_IOCTL_HW_REFINE_OLD, params);
}

static int snd_pcm_hw_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	int err;

	if (hw->format != SND_PCM_FORMAT_UNKNOWN) {
		err = _snd_pcm_hw_params_set_format(params, hw->format);
		if (err < 0)
			return err;
	}
	if (hw->channels > 0) {
		err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_CHANNELS,
					    hw->channels, 0);
		if (err < 0)
			return err;
	}
	if (hw->rate > 0) {
		err = _snd_pcm_hw_param_set_minmax(params, SND_PCM_HW_PARAM_RATE,
						   hw->rate, 0, hw->rate + 1, -1);
		if (err < 0)
			return err;
	}

	if (hw_refine_call(hw, params) < 0) {
		err = -errno;
		// SYSMSG("SNDRV_PCM_IOCTL_HW_REFINE failed");
		return err;
	}

	if (params->info != ~0U) {
		params->info &= ~0xf0000000;
		if (pcm->tstamp_type != SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY)
			params->info |= SND_PCM_INFO_MONOTONIC;
	}
	
	return 0;
}

static inline int hw_params_call(snd_pcm_hw_t *pcm_hw, snd_pcm_hw_params_t *params)
{
	/* check for new hw_params structure; it's available from 2.0.2 version of PCM API */
	if (SNDRV_PROTOCOL_VERSION(2, 0, 2) <= pcm_hw->version)
		return ioctl(pcm_hw->fd, SNDRV_PCM_IOCTL_HW_PARAMS, params);
	return use_old_hw_params_ioctl(pcm_hw->fd, SND_PCM_IOCTL_HW_PARAMS_OLD, params);
}

static int snd_pcm_hw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	int err;
	if (hw_params_call(hw, params) < 0) {
		err = -errno;
		SYSMSG("SNDRV_PCM_IOCTL_HW_PARAMS failed (%i)", err);
		return err;
	}
	params->info &= ~0xf0000000;
	if (pcm->tstamp_type != SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY)
		params->info |= SND_PCM_INFO_MONOTONIC;
	err = sync_ptr(hw, 0);
	if (err < 0)
		return err;
	if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
		snd_pcm_set_appl_ptr(pcm, &hw->mmap_control->appl_ptr, hw->fd,
				     SNDRV_PCM_MMAP_OFFSET_CONTROL);
	}
	return 0;
}

static void snd_pcm_hw_close_timer(snd_pcm_hw_t *hw)
{
	if (hw->period_timer) {
		snd_timer_close(hw->period_timer);
		hw->period_timer = NULL;
	}
}

static int snd_pcm_hw_change_timer(snd_pcm_t *pcm, int enable)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	snd_timer_params_t params = {0};
	unsigned int suspend, resume;
	int err;
	
	if (enable) {
		err = snd_timer_hw_open(&hw->period_timer,
				"hw-pcm-period-event",
				SND_TIMER_CLASS_PCM, SND_TIMER_SCLASS_NONE,
				hw->card, hw->device,
				(hw->subdevice << 1) | (pcm->stream & 1),
				SND_TIMER_OPEN_NONBLOCK | SND_TIMER_OPEN_TREAD);
		if (err < 0) {
			err = snd_timer_hw_open(&hw->period_timer,
				"hw-pcm-period-event",
				SND_TIMER_CLASS_PCM, SND_TIMER_SCLASS_NONE,
				hw->card, hw->device,
				(hw->subdevice << 1) | (pcm->stream & 1),
				SND_TIMER_OPEN_NONBLOCK);
			return err;
		}
		if (snd_timer_poll_descriptors_count(hw->period_timer) != 1) {
			snd_pcm_hw_close_timer(hw);
			return -EINVAL;
		}
		hw->period_timer_pfd.events = POLLIN;
 		hw->period_timer_pfd.revents = 0;
		snd_timer_poll_descriptors(hw->period_timer,
					   &hw->period_timer_pfd, 1);
		hw->period_timer_need_poll = 0;
		suspend = 1<<SND_TIMER_EVENT_MSUSPEND;
		resume = 1<<SND_TIMER_EVENT_MRESUME;
		/*
		 * hacks for older kernel drivers
		 */
		{
			int ver = 0;
			ioctl(hw->period_timer_pfd.fd,
			      SNDRV_TIMER_IOCTL_PVERSION, &ver);
			/*
			 * In older versions, check via poll before read() is
			 * needed because of the confliction between
			 * TIMER_START and FIONBIO ioctls.
                         */
			if (ver < SNDRV_PROTOCOL_VERSION(2, 0, 4))
				hw->period_timer_need_poll = 1;
			/*
			 * In older versions, timer uses pause events instead
			 * suspend/resume events.
			 */
			if (ver < SNDRV_PROTOCOL_VERSION(2, 0, 5)) {
				suspend = 1<<SND_TIMER_EVENT_MPAUSE;
				resume = 1<<SND_TIMER_EVENT_MCONTINUE;
			}
		}
		snd_timer_params_set_auto_start(&params, 1);
		snd_timer_params_set_ticks(&params, 1);
		snd_timer_params_set_filter(&params, (1<<SND_TIMER_EVENT_TICK) |
					    suspend | resume);
		err = snd_timer_params(hw->period_timer, &params);
		if (err < 0) {
			snd_pcm_hw_close_timer(hw);
			return err;
		}
		err = snd_timer_start(hw->period_timer);
		if (err < 0) {
			snd_pcm_hw_close_timer(hw);
			return err;
		}
		pcm->fast_ops = &snd_pcm_hw_fast_ops_timer;
	} else {
		snd_pcm_hw_close_timer(hw);
		pcm->fast_ops = &snd_pcm_hw_fast_ops;
		hw->period_event = 0;
	}
	return 0;
}

static int snd_pcm_hw_hw_free(snd_pcm_t *pcm)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	int fd = hw->fd, err;
	snd_pcm_hw_change_timer(pcm, 0);
	if (ioctl(fd, SNDRV_PCM_IOCTL_HW_FREE) < 0) {
		err = -errno;
		SYSMSG("SNDRV_PCM_IOCTL_HW_FREE failed (%i)", err);
		return err;
	}
	return 0;
}

static int snd_pcm_hw_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	int fd = hw->fd, err;
	int old_period_event = sw_get_period_event(params);
	sw_set_period_event(params, 0);
	if ((snd_pcm_tstamp_t) params->tstamp_mode == pcm->tstamp_mode &&
	    (snd_pcm_tstamp_type_t) params->tstamp_type == pcm->tstamp_type &&
	    params->period_step == pcm->period_step &&
	    params->start_threshold == pcm->start_threshold &&
	    params->stop_threshold == pcm->stop_threshold &&
	    params->silence_threshold == pcm->silence_threshold &&
	    params->silence_size == pcm->silence_size &&
	    old_period_event == hw->period_event) {
		hw->mmap_control->avail_min = params->avail_min;
		return sync_ptr(hw, 0);
	}
	if (params->tstamp_type == SND_PCM_TSTAMP_TYPE_MONOTONIC_RAW &&
	    hw->version < SNDRV_PROTOCOL_VERSION(2, 0, 12)) {
		SYSMSG("Kernel doesn't support SND_PCM_TSTAMP_TYPE_MONOTONIC_RAW");
		return -EINVAL;
	}
	if (params->tstamp_type == SND_PCM_TSTAMP_TYPE_MONOTONIC &&
	    hw->version < SNDRV_PROTOCOL_VERSION(2, 0, 5)) {
		SYSMSG("Kernel doesn't support SND_PCM_TSTAMP_TYPE_MONOTONIC");
		return -EINVAL;
	}
	if (ioctl(fd, SNDRV_PCM_IOCTL_SW_PARAMS, params) < 0) {
		err = -errno;
		SYSMSG("SNDRV_PCM_IOCTL_SW_PARAMS failed (%i)", err);
		return err;
	}
	if ((snd_pcm_tstamp_type_t) params->tstamp_type != pcm->tstamp_type) {
		if (hw->version < SNDRV_PROTOCOL_VERSION(2, 0, 12)) {
			int on = (snd_pcm_tstamp_type_t) params->tstamp_type ==
				SND_PCM_TSTAMP_TYPE_MONOTONIC;
			if (ioctl(fd, SNDRV_PCM_IOCTL_TSTAMP, &on) < 0) {
				err = -errno;
				SNDMSG("TSTAMP failed\n");
				return err;
			}
		}
		pcm->tstamp_type = params->tstamp_type;
	}
	sw_set_period_event(params, old_period_event);
	hw->mmap_control->avail_min = params->avail_min;
	if (hw->period_event != old_period_event) {
		err = snd_pcm_hw_change_timer(pcm, old_period_event);
		if (err < 0)
			return err;
		hw->period_event = old_period_event;
	}
	return 0;
}

static int snd_pcm_hw_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	struct snd_pcm_channel_info i;
	int fd = hw->fd, err;
	i.channel = info->channel;
	if (ioctl(fd, SNDRV_PCM_IOCTL_CHANNEL_INFO, &i) < 0) {
		err = -errno;
		SYSMSG("SNDRV_PCM_IOCTL_CHANNEL_INFO failed (%i)", err);
		return err;
	}
	info->channel = i.channel;
	info->addr = 0;
	info->first = i.first;
	info->step = i.step;
	info->type = SND_PCM_AREA_MMAP;
	info->u.mmap.fd = fd;
	info->u.mmap.offset = i.offset;
	return 0;
}

static int snd_pcm_hw_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	int fd = hw->fd, err;
	if (SNDRV_PROTOCOL_VERSION(2, 0, 13) > hw->version) {
		if (ioctl(fd, SNDRV_PCM_IOCTL_STATUS, status) < 0) {
			err = -errno;
			SYSMSG("SNDRV_PCM_IOCTL_STATUS failed (%i)", err);
			return err;
		}
	} else {
		if (ioctl(fd, SNDRV_PCM_IOCTL_STATUS_EXT, status) < 0) {
			err = -errno;
			SYSMSG("SNDRV_PCM_IOCTL_STATUS_EXT failed (%i)", err);
			return err;
		}
	}
	if (SNDRV_PROTOCOL_VERSION(2, 0, 5) > hw->version) {
		status->tstamp.tv_nsec *= 1000L;
		status->trigger_tstamp.tv_nsec *= 1000L;
	}
	return 0;
}

static snd_pcm_state_t snd_pcm_hw_state(snd_pcm_t *pcm)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	int err = sync_ptr(hw, 0);
	if (err < 0)
		return err;
	return (snd_pcm_state_t) hw->mmap_status->state;
}

static int snd_pcm_hw_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	int fd = hw->fd, err;
	if (ioctl(fd, SNDRV_PCM_IOCTL_DELAY, delayp) < 0) {
		err = -errno;
		SYSMSG("SNDRV_PCM_IOCTL_DELAY failed (%i)", err);
		return err;
	}
	return 0;
}

static int snd_pcm_hw_hwsync(snd_pcm_t *pcm)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	int fd = hw->fd, err;
	if (SNDRV_PROTOCOL_VERSION(2, 0, 3) <= hw->version) {
		if (hw->sync_ptr) {
			err = sync_ptr1(hw, SNDRV_PCM_SYNC_PTR_HWSYNC);
			if (err < 0)
				return err;
		} else {
			if (ioctl(fd, SNDRV_PCM_IOCTL_HWSYNC) < 0) {
				err = -errno;
				SYSMSG("SNDRV_PCM_IOCTL_HWSYNC failed (%i)", err);
				return err;
			}
		}
	} else {
		snd_pcm_sframes_t delay;
		int err = snd_pcm_hw_delay(pcm, &delay);
		if (err < 0) {
			switch (FAST_PCM_STATE(hw)) {
			case SND_PCM_STATE_PREPARED:
			case SND_PCM_STATE_SUSPENDED:
				return 0;
			default:
				return err;
			}
		}
	}
	return 0;
}

static int snd_pcm_hw_prepare(snd_pcm_t *pcm)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	int fd = hw->fd, err;
	if (ioctl(fd, SNDRV_PCM_IOCTL_PREPARE) < 0) {
		err = -errno;
		SYSMSG("SNDRV_PCM_IOCTL_PREPARE failed (%i)", err);
		return err;
	}
	return sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL);
}

static int snd_pcm_hw_reset(snd_pcm_t *pcm)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	int fd = hw->fd, err;
	if (ioctl(fd, SNDRV_PCM_IOCTL_RESET) < 0) {
		err = -errno;
		SYSMSG("SNDRV_PCM_IOCTL_RESET failed (%i)", err);
		return err;
	}
	return sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL);
}

static int snd_pcm_hw_start(snd_pcm_t *pcm)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	int err;
#if 0
	assert(pcm->stream != SND_PCM_STREAM_PLAYBACK ||
	       snd_pcm_mmap_playback_hw_avail(pcm) > 0);
#endif
	sync_ptr(hw, 0);
	if (ioctl(hw->fd, SNDRV_PCM_IOCTL_START) < 0) {
		err = -errno;
		SYSMSG("SNDRV_PCM_IOCTL_START failed (%i)", err);
#if 0
		if (err == -EBADFD)
			SNDERR("PCM state = %s", snd_pcm_state_name(snd_pcm_hw_state(pcm)));
#endif
		return err;
	}
	return 0;
}

static int snd_pcm_hw_drop(snd_pcm_t *pcm)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	int err;
	if (ioctl(hw->fd, SNDRV_PCM_IOCTL_DROP) < 0) {
		err = -errno;
		SYSMSG("SNDRV_PCM_IOCTL_DROP failed (%i)", err);
		return err;
	} else {
	}
	return 0;
}

static int snd_pcm_hw_drain(snd_pcm_t *pcm)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	int err;
	if (ioctl(hw->fd, SNDRV_PCM_IOCTL_DRAIN) < 0) {
		err = -errno;
		SYSMSG("SNDRV_PCM_IOCTL_DRAIN failed (%i)", err);
		return err;
	}
	return 0;
}

static int snd_pcm_hw_pause(snd_pcm_t *pcm, int enable)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	int err;
	if (ioctl(hw->fd, SNDRV_PCM_IOCTL_PAUSE, enable) < 0) {
		err = -errno;
		SYSMSG("SNDRV_PCM_IOCTL_PAUSE failed (%i)", err);
		return err;
	}
	return 0;
}

static snd_pcm_sframes_t snd_pcm_hw_rewindable(snd_pcm_t *pcm)
{
	return snd_pcm_mmap_hw_rewindable(pcm);
}

static snd_pcm_sframes_t snd_pcm_hw_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	int err;
	if (ioctl(hw->fd, SNDRV_PCM_IOCTL_REWIND, &frames) < 0) {
		err = -errno;
		SYSMSG("SNDRV_PCM_IOCTL_REWIND failed (%i)", err);
		return err;
	}
	err = sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL);
	if (err < 0)
		return err;
	return frames;
}

static snd_pcm_sframes_t snd_pcm_hw_forwardable(snd_pcm_t *pcm)
{
	return snd_pcm_mmap_avail(pcm);
}

static snd_pcm_sframes_t snd_pcm_hw_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	int err;
	if (SNDRV_PROTOCOL_VERSION(2, 0, 4) <= hw->version) {
		if (ioctl(hw->fd, SNDRV_PCM_IOCTL_FORWARD, &frames) < 0) {
			err = -errno;
			SYSMSG("SNDRV_PCM_IOCTL_FORWARD failed (%i)", err);
			return err;
		}
		err = sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL);
		if (err < 0)
			return err;
		return frames;
	} else {
		snd_pcm_sframes_t avail;

		err = sync_ptr(hw, SNDRV_PCM_SYNC_PTR_HWSYNC);
		if (err < 0)
			return err;
		switch (FAST_PCM_STATE(hw)) {
		case SNDRV_PCM_STATE_RUNNING:
		case SNDRV_PCM_STATE_DRAINING:
		case SNDRV_PCM_STATE_PAUSED:
		case SNDRV_PCM_STATE_PREPARED:
			break;
		case SNDRV_PCM_STATE_XRUN:
			return -EPIPE;
		default:
			return -EBADFD;
		}
		avail = snd_pcm_mmap_avail(pcm);
		if (avail < 0)
			return 0;
		if (frames > (snd_pcm_uframes_t)avail)
			frames = avail;
		snd_pcm_mmap_appl_forward(pcm, frames);
		err = sync_ptr(hw, 0);
		if (err < 0)
			return err;
		return frames;
	}
}

static int snd_pcm_hw_resume(snd_pcm_t *pcm)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	int fd = hw->fd, err;
	if (ioctl(fd, SNDRV_PCM_IOCTL_RESUME) < 0) {
		err = -errno;
		SYSMSG("SNDRV_PCM_IOCTL_RESUME failed (%i)", err);
		return err;
	}
	return 0;
}

static int hw_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2)
{
	snd_pcm_hw_t *hw1 = pcm1->private_data;
	snd_pcm_hw_t *hw2 = pcm2->private_data;
	if (ioctl(hw1->fd, SNDRV_PCM_IOCTL_LINK, hw2->fd) < 0) {
		SYSMSG("SNDRV_PCM_IOCTL_LINK failed (%i)", -errno);
		return -errno;
	}
	return 0;
}

static int snd_pcm_hw_link_slaves(snd_pcm_t *pcm, snd_pcm_t *master)
{
	if (master->type != SND_PCM_TYPE_HW) {
		SYSMSG("Invalid type for SNDRV_PCM_IOCTL_LINK (%i)", master->type);
		return -EINVAL;
	}
	return hw_link(master, pcm);
}

static int snd_pcm_hw_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2)
{
	if (pcm2->type != SND_PCM_TYPE_HW) {
		if (pcm2->fast_ops->link_slaves)
			return pcm2->fast_ops->link_slaves(pcm2, pcm1);
		return -ENOSYS;
	}
	return hw_link(pcm1, pcm2);
 }

static int snd_pcm_hw_unlink(snd_pcm_t *pcm)
{
	snd_pcm_hw_t *hw = pcm->private_data;

	if (ioctl(hw->fd, SNDRV_PCM_IOCTL_UNLINK) < 0) {
		SYSMSG("SNDRV_PCM_IOCTL_UNLINK failed (%i)", -errno);
		return -errno;
	}
	return 0;
}

static snd_pcm_sframes_t snd_pcm_hw_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
{
	int err;
	snd_pcm_hw_t *hw = pcm->private_data;
	int fd = hw->fd;
	struct snd_xferi xferi;
	xferi.buf = (char*) buffer;
	xferi.frames = size;
	xferi.result = 0; /* make valgrind happy */
	err = ioctl(fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &xferi);
	err = err >= 0 ? sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL) : -errno;
#ifdef DEBUG_RW
	fprintf(stderr, "hw_writei: frames = %li, xferi.result = %li, err = %i\n", size, xferi.result, err);
#endif
	if (err < 0)
		return snd_pcm_check_error(pcm, err);
	return xferi.result;
}

static snd_pcm_sframes_t snd_pcm_hw_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
{
	int err;
	snd_pcm_hw_t *hw = pcm->private_data;
	int fd = hw->fd;
	struct snd_xfern xfern;
	memset(&xfern, 0, sizeof(xfern)); /* make valgrind happy */
	xfern.bufs = bufs;
	xfern.frames = size;
	err = ioctl(fd, SNDRV_PCM_IOCTL_WRITEN_FRAMES, &xfern);
	err = err >= 0 ? sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL) : -errno;
#ifdef DEBUG_RW
	fprintf(stderr, "hw_writen: frames = %li, result = %li, err = %i\n", size, xfern.result, err);
#endif
	if (err < 0)
		return snd_pcm_check_error(pcm, err);
	return xfern.result;
}

static snd_pcm_sframes_t snd_pcm_hw_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
{
	int err;
	snd_pcm_hw_t *hw = pcm->private_data;
	int fd = hw->fd;
	struct snd_xferi xferi;
	xferi.buf = buffer;
	xferi.frames = size;
	xferi.result = 0; /* make valgrind happy */
	err = ioctl(fd, SNDRV_PCM_IOCTL_READI_FRAMES, &xferi);
	err = err >= 0 ? sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL) : -errno;
#ifdef DEBUG_RW
	fprintf(stderr, "hw_readi: frames = %li, result = %li, err = %i\n", size, xferi.result, err);
#endif
	if (err < 0)
		return snd_pcm_check_error(pcm, err);
	return xferi.result;
}

static snd_pcm_sframes_t snd_pcm_hw_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
{
	int err;
	snd_pcm_hw_t *hw = pcm->private_data;
	int fd = hw->fd;
	struct snd_xfern xfern;
	memset(&xfern, 0, sizeof(xfern)); /* make valgrind happy */
	xfern.bufs = bufs;
	xfern.frames = size;
	err = ioctl(fd, SNDRV_PCM_IOCTL_READN_FRAMES, &xfern);
	err = err >= 0 ? sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL) : -errno;
#ifdef DEBUG_RW
	fprintf(stderr, "hw_readn: frames = %li, result = %li, err = %i\n", size, xfern.result, err);
#endif
	if (err < 0)
		return snd_pcm_check_error(pcm, err);
	return xfern.result;
}

static int snd_pcm_hw_mmap_status(snd_pcm_t *pcm)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	struct snd_pcm_sync_ptr sync_ptr;
	void *ptr;
	int err;
	ptr = MAP_FAILED;
	if (hw->sync_ptr_ioctl == 0)
		ptr = mmap(NULL, page_align(sizeof(struct snd_pcm_mmap_status)),
			   PROT_READ, MAP_FILE|MAP_SHARED, 
			   hw->fd, SNDRV_PCM_MMAP_OFFSET_STATUS);
	if (ptr == MAP_FAILED || ptr == NULL) {
		memset(&sync_ptr, 0, sizeof(sync_ptr));
		sync_ptr.c.control.appl_ptr = 0;
		sync_ptr.c.control.avail_min = 1;
		err = ioctl(hw->fd, SNDRV_PCM_IOCTL_SYNC_PTR, &sync_ptr);
		if (err < 0) {
			err = -errno;
			SYSMSG("SNDRV_PCM_IOCTL_SYNC_PTR failed (%i)", err);
			return err;
		}
		hw->sync_ptr = calloc(1, sizeof(struct snd_pcm_sync_ptr));
		if (hw->sync_ptr == NULL)
			return -ENOMEM;
		hw->mmap_status = &hw->sync_ptr->s.status;
		hw->mmap_control = &hw->sync_ptr->c.control;
		hw->sync_ptr_ioctl = 1;
	} else {
		hw->mmap_status = ptr;
	}
	snd_pcm_set_hw_ptr(pcm, &hw->mmap_status->hw_ptr, hw->fd, SNDRV_PCM_MMAP_OFFSET_STATUS + offsetof(struct snd_pcm_mmap_status, hw_ptr));
	return 0;
}

static int snd_pcm_hw_mmap_control(snd_pcm_t *pcm)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	void *ptr;
	int err;
	if (hw->sync_ptr == NULL) {
		ptr = mmap(NULL, page_align(sizeof(struct snd_pcm_mmap_control)),
			   PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, 
			   hw->fd, SNDRV_PCM_MMAP_OFFSET_CONTROL);
		if (ptr == MAP_FAILED || ptr == NULL) {
			err = -errno;
			SYSMSG("control mmap failed (%i)", err);
			return err;
		}
		hw->mmap_control = ptr;
	} else {
		hw->mmap_control->avail_min = 1;
	}
	snd_pcm_set_appl_ptr(pcm, &hw->mmap_control->appl_ptr, hw->fd, SNDRV_PCM_MMAP_OFFSET_CONTROL);
	return 0;
}

static int snd_pcm_hw_munmap_status(snd_pcm_t *pcm)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	int err;
	if (hw->sync_ptr_ioctl) {
		free(hw->sync_ptr);
		hw->sync_ptr = NULL;
	} else {
		if (munmap((void*)hw->mmap_status, page_align(sizeof(*hw->mmap_status))) < 0) {
			err = -errno;
			SYSMSG("status munmap failed (%i)", err);
			return err;
		}
	}
	return 0;
}

static int snd_pcm_hw_munmap_control(snd_pcm_t *pcm)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	int err;
	if (hw->sync_ptr_ioctl) {
		free(hw->sync_ptr);
		hw->sync_ptr = NULL;
	} else {
		if (munmap(hw->mmap_control, page_align(sizeof(*hw->mmap_control))) < 0) {
			err = -errno;
			SYSMSG("control munmap failed (%i)", err);
			return err;
		}
	}
	return 0;
}

static int snd_pcm_hw_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
{
	return 0;
}

static int snd_pcm_hw_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
{
	return 0;
}

static int snd_pcm_hw_close(snd_pcm_t *pcm)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	int err = 0;
	if (close(hw->fd)) {
		err = -errno;
		SYSMSG("close failed (%i)\n", err);
	}
	snd_pcm_hw_munmap_status(pcm);
	snd_pcm_hw_munmap_control(pcm);
	free(hw);
	return err;
}

static snd_pcm_sframes_t snd_pcm_hw_mmap_commit(snd_pcm_t *pcm,
						snd_pcm_uframes_t offset ATTRIBUTE_UNUSED,
						snd_pcm_uframes_t size)
{
	snd_pcm_hw_t *hw = pcm->private_data;

	snd_pcm_mmap_appl_forward(pcm, size);
	sync_ptr(hw, 0);
#ifdef DEBUG_MMAP
	fprintf(stderr, "appl_forward: hw_ptr = %li, appl_ptr = %li, size = %li\n", *pcm->hw.ptr, *pcm->appl.ptr, size);
#endif
	return size;
}

static snd_pcm_sframes_t snd_pcm_hw_avail_update(snd_pcm_t *pcm)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	snd_pcm_uframes_t avail;

	sync_ptr(hw, 0);
	avail = snd_pcm_mmap_avail(pcm);
	switch (FAST_PCM_STATE(hw)) {
	case SNDRV_PCM_STATE_RUNNING:
		if (avail >= pcm->stop_threshold) {
			/* SNDRV_PCM_IOCTL_XRUN ioctl has been implemented since PCM kernel API 2.0.1 */
			if (SNDRV_PROTOCOL_VERSION(2, 0, 1) <= hw->version) {
				if (ioctl(hw->fd, SNDRV_PCM_IOCTL_XRUN) < 0)
					return -errno;
			}
			/* everything is ok, state == SND_PCM_STATE_XRUN at the moment */
			return -EPIPE;
		}
		break;
	case SNDRV_PCM_STATE_XRUN:
		return -EPIPE;
	default:
		break;
	}
	return avail;
}

static int snd_pcm_hw_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail,
				 snd_htimestamp_t *tstamp)
{
	snd_pcm_sframes_t avail1;
	int ok = 0;

	/* unfortunately, loop is necessary to ensure valid timestamp */
	while (1) {
		avail1 = snd_pcm_hw_avail_update(pcm);
		if (avail1 < 0)
			return avail1;
		if (ok && (snd_pcm_uframes_t)avail1 == *avail)
			break;
		*avail = avail1;
		*tstamp = snd_pcm_hw_fast_tstamp(pcm);
		ok = 1;
	}
	return 0;
}

static void __fill_chmap_ctl_id(snd_ctl_elem_id_t *id, int dev, int subdev,
				int stream)
{
	snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_PCM);
	if (stream == SND_PCM_STREAM_PLAYBACK)
		snd_ctl_elem_id_set_name(id, "Playback Channel Map");
	else
		snd_ctl_elem_id_set_name(id, "Capture Channel Map");
	snd_ctl_elem_id_set_device(id, dev);
	snd_ctl_elem_id_set_index(id, subdev);
}

static void fill_chmap_ctl_id(snd_pcm_t *pcm, snd_ctl_elem_id_t *id)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	return __fill_chmap_ctl_id(id, hw->device, hw->subdevice, pcm->stream);
}

static int is_chmap_type(int type)
{
	return (type >= SND_CTL_TLVT_CHMAP_FIXED &&
		type <= SND_CTL_TLVT_CHMAP_PAIRED);
}

/**
 * \!brief Query the available channel maps
 * \param card the card number
 * \param dev the PCM device number
 * \param subdev the PCM substream index
 * \param stream the direction of PCM stream
 * \return the NULL-terminated array of integer pointers, or NULL at error.
 *
 * This function works like snd_pcm_query_chmaps() but it takes the card,
 * device, substream and stream numbers instead of the already opened
 * snd_pcm_t instance, so that you can query available channel maps of
 * a PCM before actually opening it.
 *
 * As the parameters stand, the query is performed only to the hw PCM
 * devices, not the abstracted PCM object in alsa-lib.
 */
snd_pcm_chmap_query_t **
snd_pcm_query_chmaps_from_hw(int card, int dev, int subdev,
			     snd_pcm_stream_t stream)
{
	snd_ctl_t *ctl;
	snd_ctl_elem_id_t id = {0};
	unsigned int tlv[2048], *start;
	snd_pcm_chmap_query_t **map;
	int i, ret, nums;

	ret = snd_ctl_hw_open(&ctl, NULL, card, 0);
	if (ret < 0) {
		SYSMSG("Cannot open the associated CTL\n");
		return NULL;
	}

	__fill_chmap_ctl_id(&id, dev, subdev, stream);
	ret = snd_ctl_elem_tlv_read(ctl, &id, tlv, sizeof(tlv));
	snd_ctl_close(ctl);
	if (ret < 0) {
		SYSMSG("Cannot read Channel Map TLV\n");
		return NULL;
	}

#if 0
	for (i = 0; i < 32; i++)
		fprintf(stderr, "%02x: %08x\n", i, tlv[i]);
#endif
	/* FIXME: the parser below assumes that the TLV only contains
	 * chmap-related blocks
	 */
	if (tlv[0] != SND_CTL_TLVT_CONTAINER) {
		if (!is_chmap_type(tlv[0])) {
			SYSMSG("Invalid TLV type %d\n", tlv[0]);
			return NULL;
		}
		start = tlv;
		nums = 1;
	} else {
		unsigned int *p;
		int size;
		start = tlv + 2;
		size = tlv[1];
		nums = 0;
		for (p = start; size > 0; ) {
			if (!is_chmap_type(p[0])) {
				SYSMSG("Invalid TLV type %d\n", p[0]);
				return NULL;
			}
			nums++;
			size -= p[1] + 8;
			p += p[1] / 4 + 2;
		}
	}
	map = calloc(nums + 1, sizeof(int *));
	if (!map)
		return NULL;
	for (i = 0; i < nums; i++) {
		map[i] = malloc(start[1] + 8);
		if (!map[i]) {
			snd_pcm_free_chmaps(map);
			return NULL;
		}
		map[i]->type = start[0] - 0x100;
		map[i]->map.channels = start[1] / 4;
		memcpy(map[i]->map.pos, start + 2, start[1]);
		start += start[1] / 4 + 2;
	}
	return map;
}

enum { CHMAP_CTL_QUERY, CHMAP_CTL_GET, CHMAP_CTL_SET };

static int chmap_caps(snd_pcm_hw_t *hw, int type)
{
	if (hw->chmap_caps & (1 << type))
		return 1;
	if (hw->chmap_caps & (1 << (type + 8)))
		return 0;
	return 1;
}

static void chmap_caps_set_ok(snd_pcm_hw_t *hw, int type)
{
	hw->chmap_caps |= (1 << type);
}

static void chmap_caps_set_error(snd_pcm_hw_t *hw, int type)
{
	hw->chmap_caps |= (1 << (type + 8));
}

static snd_pcm_chmap_query_t **snd_pcm_hw_query_chmaps(snd_pcm_t *pcm)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	snd_pcm_chmap_query_t **map;

	if (hw->chmap_override)
		return _snd_pcm_copy_chmap_query(hw->chmap_override);

	if (!chmap_caps(hw, CHMAP_CTL_QUERY))
		return NULL;

	map = snd_pcm_query_chmaps_from_hw(hw->card, hw->device,
					   hw->subdevice, pcm->stream);
	if (map)
		chmap_caps_set_ok(hw, CHMAP_CTL_QUERY);
	else
		chmap_caps_set_error(hw, CHMAP_CTL_QUERY);
	return map;
}

static snd_pcm_chmap_t *snd_pcm_hw_get_chmap(snd_pcm_t *pcm)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	snd_pcm_chmap_t *map;
	snd_ctl_t *ctl;
	snd_ctl_elem_id_t id = {0};
	snd_ctl_elem_value_t val = {0};
	unsigned int i;
	int ret;

	if (hw->chmap_override)
		return _snd_pcm_choose_fixed_chmap(pcm, hw->chmap_override);

	if (!chmap_caps(hw, CHMAP_CTL_GET))
		return NULL;

	switch (FAST_PCM_STATE(hw)) {
	case SNDRV_PCM_STATE_PREPARED:
	case SNDRV_PCM_STATE_RUNNING:
	case SNDRV_PCM_STATE_XRUN:
	case SNDRV_PCM_STATE_DRAINING:
	case SNDRV_PCM_STATE_PAUSED:
	case SNDRV_PCM_STATE_SUSPENDED:
		break;
	default:
		SYSMSG("Invalid PCM state for chmap_get: %s\n",
		       snd_pcm_state_name(FAST_PCM_STATE(hw)));
		return NULL;
	}
	map = malloc(pcm->channels * sizeof(map->pos[0]) + sizeof(*map));
	if (!map)
		return NULL;
	map->channels = pcm->channels;
	ret = snd_ctl_hw_open(&ctl, NULL, hw->card, 0);
	if (ret < 0) {
		free(map);
		SYSMSG("Cannot open the associated CTL\n");
		chmap_caps_set_error(hw, CHMAP_CTL_GET);
		return NULL;
	}
	fill_chmap_ctl_id(pcm, &id);
	snd_ctl_elem_value_set_id(&val, &id);
	ret = snd_ctl_elem_read(ctl, &val);
	snd_ctl_close(ctl);
	if (ret < 0) {
		free(map);
		SYSMSG("Cannot read Channel Map ctl\n");
		chmap_caps_set_error(hw, CHMAP_CTL_GET);
		return NULL;
	}
	for (i = 0; i < pcm->channels; i++)
		map->pos[i] = snd_ctl_elem_value_get_integer(&val, i);
	chmap_caps_set_ok(hw, CHMAP_CTL_GET);
	return map;
}

static int snd_pcm_hw_set_chmap(snd_pcm_t *pcm, const snd_pcm_chmap_t *map)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	snd_ctl_t *ctl;
	snd_ctl_elem_id_t id = {0};
	snd_ctl_elem_value_t val = {0};
	unsigned int i;
	int ret;

	if (hw->chmap_override)
		return -ENXIO;

	if (!chmap_caps(hw, CHMAP_CTL_SET))
		return -ENXIO;

	if (map->channels > 128) {
		SYSMSG("Invalid number of channels %d\n", map->channels);
		return -EINVAL;
	}
	if (FAST_PCM_STATE(hw) != SNDRV_PCM_STATE_PREPARED) {
		SYSMSG("Invalid PCM state for chmap_set: %s\n",
		       snd_pcm_state_name(FAST_PCM_STATE(hw)));
		return -EBADFD;
	}
	ret = snd_ctl_hw_open(&ctl, NULL, hw->card, 0);
	if (ret < 0) {
		SYSMSG("Cannot open the associated CTL\n");
		chmap_caps_set_error(hw, CHMAP_CTL_SET);
		return ret;
	}

	fill_chmap_ctl_id(pcm, &id);
	snd_ctl_elem_value_set_id(&val, &id);
	for (i = 0; i < map->channels; i++)
		snd_ctl_elem_value_set_integer(&val, i, map->pos[i]);
	ret = snd_ctl_elem_write(ctl, &val);
	snd_ctl_close(ctl);
	if (ret >= 0)
		chmap_caps_set_ok(hw, CHMAP_CTL_SET);
	else if (ret == -ENOENT || ret == -EPERM || ret == -ENXIO) {
		chmap_caps_set_error(hw, CHMAP_CTL_SET);
		ret = -ENXIO;
	}
	if (ret < 0)
		SYSMSG("Cannot write Channel Map ctl\n");
	return ret;
}

static void snd_pcm_hw_dump(snd_pcm_t *pcm, snd_output_t *out)
{
	snd_pcm_hw_t *hw = pcm->private_data;
	char *name;
	int err = snd_card_get_name(hw->card, &name);
	if (err < 0) {
		SNDERR("cannot get card name");
		return;
	}
	snd_output_printf(out, "Hardware PCM card %d '%s' device %d subdevice %d\n",
			  hw->card, name, hw->device, hw->subdevice);
	free(name);
	if (pcm->setup) {
		snd_output_printf(out, "Its setup is:\n");
		snd_pcm_dump_setup(pcm, out);
		snd_output_printf(out, "  appl_ptr     : %li\n", hw->mmap_control->appl_ptr);
		snd_output_printf(out, "  hw_ptr       : %li\n", hw->mmap_status->hw_ptr);
	}
}

static const snd_pcm_ops_t snd_pcm_hw_ops = {
	.close = snd_pcm_hw_close,
	.info = snd_pcm_hw_info,
	.hw_refine = snd_pcm_hw_hw_refine,
	.hw_params = snd_pcm_hw_hw_params,
	.hw_free = snd_pcm_hw_hw_free,
	.sw_params = snd_pcm_hw_sw_params,
	.channel_info = snd_pcm_hw_channel_info,
	.dump = snd_pcm_hw_dump,
	.nonblock = snd_pcm_hw_nonblock,
	.async = snd_pcm_hw_async,
	.mmap = snd_pcm_hw_mmap,
	.munmap = snd_pcm_hw_munmap,
	.query_chmaps = snd_pcm_hw_query_chmaps,
	.get_chmap = snd_pcm_hw_get_chmap,
	.set_chmap = snd_pcm_hw_set_chmap,
};

static const snd_pcm_fast_ops_t snd_pcm_hw_fast_ops = {
	.status = snd_pcm_hw_status,
	.state = snd_pcm_hw_state,
	.hwsync = snd_pcm_hw_hwsync,
	.delay = snd_pcm_hw_delay,
	.prepare = snd_pcm_hw_prepare,
	.reset = snd_pcm_hw_reset,
	.start = snd_pcm_hw_start,
	.drop = snd_pcm_hw_drop,
	.drain = snd_pcm_hw_drain,
	.pause = snd_pcm_hw_pause,
	.rewindable = snd_pcm_hw_rewindable,
	.rewind = snd_pcm_hw_rewind,
	.forwardable = snd_pcm_hw_forwardable,
	.forward = snd_pcm_hw_forward,
	.resume = snd_pcm_hw_resume,
	.link = snd_pcm_hw_link,
	.link_slaves = snd_pcm_hw_link_slaves,
	.unlink = snd_pcm_hw_unlink,
	.writei = snd_pcm_hw_writei,
	.writen = snd_pcm_hw_writen,
	.readi = snd_pcm_hw_readi,
	.readn = snd_pcm_hw_readn,
	.avail_update = snd_pcm_hw_avail_update,
	.mmap_commit = snd_pcm_hw_mmap_commit,
	.htimestamp = snd_pcm_hw_htimestamp,
	.poll_descriptors = NULL,
	.poll_descriptors_count = NULL,
	.poll_revents = NULL,
};

static const snd_pcm_fast_ops_t snd_pcm_hw_fast_ops_timer = {
	.status = snd_pcm_hw_status,
	.state = snd_pcm_hw_state,
	.hwsync = snd_pcm_hw_hwsync,
	.delay = snd_pcm_hw_delay,
	.prepare = snd_pcm_hw_prepare,
	.reset = snd_pcm_hw_reset,
	.start = snd_pcm_hw_start,
	.drop = snd_pcm_hw_drop,
	.drain = snd_pcm_hw_drain,
	.pause = snd_pcm_hw_pause,
	.rewindable = snd_pcm_hw_rewindable,
	.rewind = snd_pcm_hw_rewind,
	.forwardable = snd_pcm_hw_forwardable,
	.forward = snd_pcm_hw_forward,
	.resume = snd_pcm_hw_resume,
	.link = snd_pcm_hw_link,
	.link_slaves = snd_pcm_hw_link_slaves,
	.unlink = snd_pcm_hw_unlink,
	.writei = snd_pcm_hw_writei,
	.writen = snd_pcm_hw_writen,
	.readi = snd_pcm_hw_readi,
	.readn = snd_pcm_hw_readn,
	.avail_update = snd_pcm_hw_avail_update,
	.mmap_commit = snd_pcm_hw_mmap_commit,
	.htimestamp = snd_pcm_hw_htimestamp,
	.poll_descriptors = snd_pcm_hw_poll_descriptors,
	.poll_descriptors_count = snd_pcm_hw_poll_descriptors_count,
	.poll_revents = snd_pcm_hw_poll_revents,
};

/**
 * \brief Creates a new hw PCM
 * \param pcmp Returns created PCM handle
 * \param name Name of PCM
 * \param fd File descriptor
 * \param mmap_emulation Obsoleted parameter
 * \param sync_ptr_ioctl Boolean flag for sync_ptr ioctl
 * \retval zero on success otherwise a negative error code
 * \warning Using of this function might be dangerous in the sense
 *          of compatibility reasons. The prototype might be freely
 *          changed in future.
 */
int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name,
		       int fd, int mmap_emulation ATTRIBUTE_UNUSED,
		       int sync_ptr_ioctl)
{
	int ver, mode;
	snd_pcm_tstamp_type_t tstamp_type = SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY;
	long fmode;
	snd_pcm_t *pcm = NULL;
	snd_pcm_hw_t *hw = NULL;
	snd_pcm_info_t info;
	int ret;

	assert(pcmp);

	memset(&info, 0, sizeof(info));
	if (ioctl(fd, SNDRV_PCM_IOCTL_INFO, &info) < 0) {
		ret = -errno;
		SYSMSG("SNDRV_PCM_IOCTL_INFO failed (%i)", ret);
		close(fd);
		return ret;

	}

	if ((fmode = fcntl(fd, F_GETFL)) < 0) {
		ret = -errno;
		close(fd);
		return ret;
	}
	mode = 0;
	if (fmode & O_NONBLOCK)
		mode |= SND_PCM_NONBLOCK;
	if (fmode & O_ASYNC)
		mode |= SND_PCM_ASYNC;

	if (ioctl(fd, SNDRV_PCM_IOCTL_PVERSION, &ver) < 0) {
		ret = -errno;
		SYSMSG("SNDRV_PCM_IOCTL_PVERSION failed (%i)", ret);
		close(fd);
		return ret;
	}
	if (SNDRV_PROTOCOL_INCOMPATIBLE(ver, SNDRV_PCM_VERSION_MAX))
		return -SND_ERROR_INCOMPATIBLE_VERSION;

#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
	if (SNDRV_PROTOCOL_VERSION(2, 0, 9) <= ver) {
		struct timespec timespec;
		if (clock_gettime(CLOCK_MONOTONIC, &timespec) == 0) {
			int on = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC;
			if (ioctl(fd, SNDRV_PCM_IOCTL_TTSTAMP, &on) < 0) {
				ret = -errno;
				SNDMSG("TTSTAMP failed\n");
				return ret;
			}
			tstamp_type = SND_PCM_TSTAMP_TYPE_MONOTONIC;
		}
	} else
#endif
	  if (SNDRV_PROTOCOL_VERSION(2, 0, 5) <= ver) {
		int on = 1;
		if (ioctl(fd, SNDRV_PCM_IOCTL_TSTAMP, &on) < 0) {
			ret = -errno;
			SNDMSG("TSTAMP failed\n");
			return ret;
		}
	}
	
	hw = calloc(1, sizeof(snd_pcm_hw_t));
	if (!hw) {
		close(fd);
		return -ENOMEM;
	}

	hw->version = ver;
	hw->card = info.card;
	hw->device = info.device;
	hw->subdevice = info.subdevice;
	hw->fd = fd;
	hw->sync_ptr_ioctl = sync_ptr_ioctl;
	/* no restriction */
	hw->format = SND_PCM_FORMAT_UNKNOWN;
	hw->rate = 0;
	hw->channels = 0;

	ret = snd_pcm_new(&pcm, SND_PCM_TYPE_HW, name, info.stream, mode);
	if (ret < 0) {
		free(hw);
		close(fd);
		return ret;
	}

	pcm->ops = &snd_pcm_hw_ops;
	pcm->fast_ops = &snd_pcm_hw_fast_ops;
	pcm->private_data = hw;
	pcm->poll_fd = fd;
	pcm->poll_events = info.stream == SND_PCM_STREAM_PLAYBACK ? POLLOUT : POLLIN;
	pcm->tstamp_type = tstamp_type;
#ifdef THREAD_SAFE_API
	pcm->thread_safe = 1;
#endif

	ret = snd_pcm_hw_mmap_status(pcm);
	if (ret < 0) {
		snd_pcm_close(pcm);
		return ret;
	}
	ret = snd_pcm_hw_mmap_control(pcm);
	if (ret < 0) {
		snd_pcm_close(pcm);
		return ret;
	}

	*pcmp = pcm;
	return 0;
}

/**
 * \brief Creates a new hw PCM
 * \param pcmp Returns created PCM handle
 * \param name Name of PCM
 * \param card Number of card
 * \param device Number of device
 * \param subdevice Number of subdevice
 * \param stream PCM Stream
 * \param mode PCM Mode
 * \param mmap_emulation Obsoleted parameter
 * \param sync_ptr_ioctl Use SYNC_PTR ioctl rather than mmap for control structures
 * \retval zero on success otherwise a negative error code
 * \warning Using of this function might be dangerous in the sense
 *          of compatibility reasons. The prototype might be freely
 *          changed in future.
 */
int snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name,
		    int card, int device, int subdevice,
		    snd_pcm_stream_t stream, int mode,
		    int mmap_emulation ATTRIBUTE_UNUSED,
		    int sync_ptr_ioctl)
{
	char filename[sizeof(SNDRV_FILE_PCM_STREAM_PLAYBACK) + 20];
	const char *filefmt;
	int ret = 0, fd = -1;
	int attempt = 0;
	snd_pcm_info_t info;
	int fmode;
	snd_ctl_t *ctl;

	assert(pcmp);

	if ((ret = snd_ctl_hw_open(&ctl, NULL, card, 0)) < 0)
		return ret;

	switch (stream) {
	case SND_PCM_STREAM_PLAYBACK:
		filefmt = SNDRV_FILE_PCM_STREAM_PLAYBACK;
		break;
	case SND_PCM_STREAM_CAPTURE:
		filefmt = SNDRV_FILE_PCM_STREAM_CAPTURE;
		break;
	default:
		SNDERR("invalid stream %d", stream);
		return -EINVAL;
	}
	sprintf(filename, filefmt, card, device);

      __again:
      	if (attempt++ > 3) {
		ret = -EBUSY;
		goto _err;
	}
	ret = snd_ctl_pcm_prefer_subdevice(ctl, subdevice);
	if (ret < 0)
		goto _err;
	fmode = O_RDWR;
	if (mode & SND_PCM_NONBLOCK)
		fmode |= O_NONBLOCK;
	if (mode & SND_PCM_ASYNC)
		fmode |= O_ASYNC;
	if (mode & SND_PCM_APPEND)
		fmode |= O_APPEND;
	fd = snd_open_device(filename, fmode);
	if (fd < 0) {
		ret = -errno;
		SYSMSG("open '%s' failed (%i)", filename, ret);
		goto _err;
	}
	if (subdevice >= 0) {
		memset(&info, 0, sizeof(info));
		if (ioctl(fd, SNDRV_PCM_IOCTL_INFO, &info) < 0) {
			ret = -errno;
			SYSMSG("SNDRV_PCM_IOCTL_INFO failed (%i)", ret);
			goto _err;
		}
		if (info.subdevice != (unsigned int) subdevice) {
			close(fd);
			goto __again;
		}
	}
	snd_ctl_close(ctl);
	return snd_pcm_hw_open_fd(pcmp, name, fd, 0, sync_ptr_ioctl);
       _err:
	snd_ctl_close(ctl);
	return ret;
}

/*! \page pcm_plugins

\section pcm_plugins_hw Plugin: hw

This plugin communicates directly with the ALSA kernel driver. It is a raw
communication without any conversions. The emulation of mmap access can be
optionally enabled, but expect worse latency in the case.

The nonblock option specifies whether the device is opened in a non-blocking
manner.  Note that the blocking behavior for read/write access won't be
changed by this option.  This influences only on the blocking behavior at
opening the device.  If you would like to keep the compatibility with the
older ALSA stuff, turn this option off.

\code
pcm.name {
	type hw			# Kernel PCM
	card INT/STR		# Card name (string) or number (integer)
	[device INT]		# Device number (default 0)
	[subdevice INT]		# Subdevice number (default -1: first available)
	[sync_ptr_ioctl BOOL]	# Use SYNC_PTR ioctl rather than the direct mmap access for control structures
	[nonblock BOOL]		# Force non-blocking open mode
	[format STR]		# Restrict only to the given format
	[channels INT]		# Restrict only to the given channels
	[rate INT]		# Restrict only to the given rate
	[chmap MAP]		# Override channel maps; MAP is a string array
}
\endcode

\subsection pcm_plugins_hw_funcref Function reference

<UL>
  <LI>snd_pcm_hw_open()
  <LI>_snd_pcm_hw_open()
</UL>

*/

/**
 * \brief Creates a new hw PCM
 * \param pcmp Returns created PCM handle
 * \param name Name of PCM
 * \param root Root configuration node
 * \param conf Configuration node with hw PCM description
 * \param stream PCM Stream
 * \param mode PCM Mode
 * \warning Using of this function might be dangerous in the sense
 *          of compatibility reasons. The prototype might be freely
 *          changed in future.
 */
int _snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name,
		     snd_config_t *root ATTRIBUTE_UNUSED, snd_config_t *conf,
		     snd_pcm_stream_t stream, int mode)
{
	snd_config_iterator_t i, next;
	long card = -1, device = 0, subdevice = -1;
	const char *str;
	int err, sync_ptr_ioctl = 0;
	int rate = 0, channels = 0;
	snd_pcm_format_t format = SND_PCM_FORMAT_UNKNOWN;
	snd_config_t *n;
	int nonblock = 1; /* non-block per default */
	snd_pcm_chmap_query_t **chmap = NULL;
	snd_pcm_hw_t *hw;

	/* look for defaults.pcm.nonblock definition */
	if (snd_config_search(root, "defaults.pcm.nonblock", &n) >= 0) {
		err = snd_config_get_bool(n);
		if (err >= 0)
			nonblock = err;
	}
	snd_config_for_each(i, next, conf) {
		const char *id;
		n = snd_config_iterator_entry(i);
		if (snd_config_get_id(n, &id) < 0)
			continue;
		if (snd_pcm_conf_generic_id(id))
			continue;
		if (strcmp(id, "card") == 0) {
			err = snd_config_get_integer(n, &card);
			if (err < 0) {
				err = snd_config_get_string(n, &str);
				if (err < 0) {
					SNDERR("Invalid type for %s", id);
					err = -EINVAL;
					goto fail;
				}
				card = snd_card_get_index(str);
				if (card < 0) {
					SNDERR("Invalid value for %s", id);
					err = card;
					goto fail;
				}
			}
			continue;
		}
		if (strcmp(id, "device") == 0) {
			err = snd_config_get_integer(n, &device);
			if (err < 0) {
				SNDERR("Invalid type for %s", id);
				goto fail;
			}
			continue;
		}
		if (strcmp(id, "subdevice") == 0) {
			err = snd_config_get_integer(n, &subdevice);
			if (err < 0) {
				SNDERR("Invalid type for %s", id);
				goto fail;
			}
			continue;
		}
		if (strcmp(id, "sync_ptr_ioctl") == 0) {
			err = snd_config_get_bool(n);
			if (err < 0)
				continue;
			sync_ptr_ioctl = err;
			continue;
		}
		if (strcmp(id, "nonblock") == 0) {
			err = snd_config_get_bool(n);
			if (err < 0)
				continue;
			nonblock = err;
			continue;
		}
		if (strcmp(id, "rate") == 0) {
			long val;
			err = snd_config_get_integer(n, &val);
			if (err < 0) {
				SNDERR("Invalid type for %s", id);
				goto fail;
			}
			rate = val;
			continue;
		}
		if (strcmp(id, "format") == 0) {
			err = snd_config_get_string(n, &str);
			if (err < 0) {
				SNDERR("invalid type for %s", id);
				goto fail;
			}
			format = snd_pcm_format_value(str);
			continue;
		}
		if (strcmp(id, "channels") == 0) {
			long val;
			err = snd_config_get_integer(n, &val);
			if (err < 0) {
				SNDERR("Invalid type for %s", id);
				goto fail;
			}
			channels = val;
			continue;
		}
		if (strcmp(id, "chmap") == 0) {
			snd_pcm_free_chmaps(chmap);
			chmap = _snd_pcm_parse_config_chmaps(n);
			if (!chmap) {
				SNDERR("Invalid channel map for %s", id);
				err = -EINVAL;
				goto fail;
			}
			continue;
		}
		SNDERR("Unknown field %s", id);
		err = -EINVAL;
		goto fail;
	}
	if (card < 0) {
		SNDERR("card is not defined");
		err = -EINVAL;
		goto fail;
	}
	err = snd_pcm_hw_open(pcmp, name, card, device, subdevice, stream,
			      mode | (nonblock ? SND_PCM_NONBLOCK : 0),
			      0, sync_ptr_ioctl);
	if (err < 0)
		goto fail;
	if (nonblock && ! (mode & SND_PCM_NONBLOCK)) {
		/* revert to blocking mode for read/write access */
		snd_pcm_hw_nonblock(*pcmp, 0);
		(*pcmp)->mode = mode;
	} else
		/* make sure the SND_PCM_NO_xxx flags don't get lost on the
		 * way */
		(*pcmp)->mode |= mode & (SND_PCM_NO_AUTO_RESAMPLE|
					 SND_PCM_NO_AUTO_CHANNELS|
					 SND_PCM_NO_AUTO_FORMAT|
					 SND_PCM_NO_SOFTVOL);

	hw = (*pcmp)->private_data;
	if (format != SND_PCM_FORMAT_UNKNOWN)
		hw->format = format;
	if (channels > 0)
		hw->channels = channels;
	if (rate > 0)
		hw->rate = rate;
	if (chmap)
		hw->chmap_override = chmap;

	return 0;

fail:
        snd_pcm_free_chmaps(chmap);
        return err;
}

#ifndef DOC_HIDDEN
SND_DLSYM_BUILD_VERSION(_snd_pcm_hw_open, SND_PCM_DLSYM_VERSION);
#endif

/*
 *  To be removed helpers, but keep binary compatibility at the time
 */

#ifndef DOC_HIDDEN
#define __OLD_TO_NEW_MASK(x) ((x&7)|((x&0x07fffff8)<<5))
#define __NEW_TO_OLD_MASK(x) ((x&7)|((x&0xffffff00)>>5))
#endif

static void snd_pcm_hw_convert_from_old_params(snd_pcm_hw_params_t *params,
					       struct sndrv_pcm_hw_params_old *oparams)
{
	unsigned int i;

	memset(params, 0, sizeof(*params));
	params->flags = oparams->flags;
	for (i = 0; i < sizeof(oparams->masks) / sizeof(unsigned int); i++)
		params->masks[i].bits[0] = oparams->masks[i];
	memcpy(params->intervals, oparams->intervals, sizeof(oparams->intervals));
	params->rmask = __OLD_TO_NEW_MASK(oparams->rmask);
	params->cmask = __OLD_TO_NEW_MASK(oparams->cmask);
	params->info = oparams->info;
	params->msbits = oparams->msbits;
	params->rate_num = oparams->rate_num;
	params->rate_den = oparams->rate_den;
	params->fifo_size = oparams->fifo_size;
}

static void snd_pcm_hw_convert_to_old_params(struct sndrv_pcm_hw_params_old *oparams,
					     snd_pcm_hw_params_t *params,
					     unsigned int *cmask)
{
	unsigned int i, j;

	memset(oparams, 0, sizeof(*oparams));
	oparams->flags = params->flags;
	for (i = 0; i < sizeof(oparams->masks) / sizeof(unsigned int); i++) {
		oparams->masks[i] = params->masks[i].bits[0];
		for (j = 1; j < sizeof(params->masks[i].bits) / sizeof(unsigned int); j++)
			if (params->masks[i].bits[j]) {
				*cmask |= 1 << i;
				break;
			}
	}
	memcpy(oparams->intervals, params->intervals, sizeof(oparams->intervals));
	oparams->rmask = __NEW_TO_OLD_MASK(params->rmask);
	oparams->cmask = __NEW_TO_OLD_MASK(params->cmask);
	oparams->info = params->info;
	oparams->msbits = params->msbits;
	oparams->rate_num = params->rate_num;
	oparams->rate_den = params->rate_den;
	oparams->fifo_size = params->fifo_size;
}

static int use_old_hw_params_ioctl(int fd, unsigned int cmd, snd_pcm_hw_params_t *params)
{
	struct sndrv_pcm_hw_params_old oparams;
	unsigned int cmask = 0;
	int res;
	
	snd_pcm_hw_convert_to_old_params(&oparams, params, &cmask);
	res = ioctl(fd, cmd, &oparams);
	snd_pcm_hw_convert_from_old_params(params, &oparams);
	params->cmask |= cmask;
	return res;
}
