/*
 *  Hardware dependent Interface - main file for hardware access
 *  Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
 *
 *
 *   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 <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "hwdep_local.h"

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

#define SNDRV_FILE_HWDEP	ALSA_DEVICE_DIRECTORY "hwC%iD%i"
#define SNDRV_HWDEP_VERSION_MAX	SNDRV_PROTOCOL_VERSION(1, 0, 1)

static int snd_hwdep_hw_close(snd_hwdep_t *hwdep)
{
	int res;
	assert(hwdep);
	res = close(hwdep->poll_fd) < 0 ? -errno : 0;
	return res;
}

static int snd_hwdep_hw_nonblock(snd_hwdep_t *hwdep, int nonblock)
{
	long flags;
	assert(hwdep);
	if ((flags = fcntl(hwdep->poll_fd, F_GETFL)) < 0)
		return -errno;
	if (nonblock)
		flags |= O_NONBLOCK;
	else
		flags &= ~O_NONBLOCK;
	if (fcntl(hwdep->poll_fd, F_SETFL, flags) < 0)
		return -errno;
	return 0;
}

static int snd_hwdep_hw_info(snd_hwdep_t *hwdep, snd_hwdep_info_t *info)
{
	assert(hwdep && info);
	if (ioctl(hwdep->poll_fd, SNDRV_HWDEP_IOCTL_INFO, info) < 0)
		return -errno;
	return 0;
}

static int snd_hwdep_hw_ioctl(snd_hwdep_t *hwdep, unsigned int request, void * arg)
{
	assert(hwdep);
	if (ioctl(hwdep->poll_fd, request, arg) < 0)
		return -errno;
	return 0;
}

static ssize_t snd_hwdep_hw_write(snd_hwdep_t *hwdep, const void *buffer, size_t size)
{
	ssize_t result;
	assert(hwdep && (buffer || size == 0));
	result = write(hwdep->poll_fd, buffer, size);
	if (result < 0)
		return -errno;
	return result;
}

static ssize_t snd_hwdep_hw_read(snd_hwdep_t *hwdep, void *buffer, size_t size)
{
	ssize_t result;
	assert(hwdep && (buffer || size == 0));
	result = read(hwdep->poll_fd, buffer, size);
	if (result < 0)
		return -errno;
	return result;
}

static const snd_hwdep_ops_t snd_hwdep_hw_ops = {
	.close = snd_hwdep_hw_close,
	.nonblock = snd_hwdep_hw_nonblock,
	.info = snd_hwdep_hw_info,
	.ioctl = snd_hwdep_hw_ioctl,
	.write = snd_hwdep_hw_write,
	.read = snd_hwdep_hw_read,
};

int snd_hwdep_hw_open(snd_hwdep_t **handle, const char *name, int card, int device, int mode)
{
	int fd, ver, ret;
	char filename[sizeof(SNDRV_FILE_HWDEP) + 20];
	snd_hwdep_t *hwdep;
	assert(handle);

	*handle = NULL;
	
	if (card < 0 || card >= SND_MAX_CARDS)
		return -EINVAL;
	sprintf(filename, SNDRV_FILE_HWDEP, card, device);
	fd = snd_open_device(filename, mode);
	if (fd < 0) {
		snd_card_load(card);
		fd = snd_open_device(filename, mode);
		if (fd < 0)
			return -errno;
	}
	if (ioctl(fd, SNDRV_HWDEP_IOCTL_PVERSION, &ver) < 0) {
		ret = -errno;
		close(fd);
		return ret;
	}
	if (SNDRV_PROTOCOL_INCOMPATIBLE(ver, SNDRV_HWDEP_VERSION_MAX)) {
		close(fd);
		return -SND_ERROR_INCOMPATIBLE_VERSION;
	}
	hwdep = (snd_hwdep_t *) calloc(1, sizeof(snd_hwdep_t));
	if (hwdep == NULL) {
		close(fd);
		return -ENOMEM;
	}
	hwdep->name = strdup(name);
	hwdep->poll_fd = fd;
	hwdep->mode = mode;
	hwdep->type = SND_HWDEP_TYPE_HW;
	hwdep->ops = &snd_hwdep_hw_ops;
	*handle = hwdep;
	return 0;
}

int _snd_hwdep_hw_open(snd_hwdep_t **hwdep, char *name,
		       snd_config_t *root ATTRIBUTE_UNUSED,
		       snd_config_t *conf, int mode)
{
	snd_config_iterator_t i, next;
	long card = -1, device = 0;
	const char *str;
	int err;
	snd_config_for_each(i, next, conf) {
		snd_config_t *n = snd_config_iterator_entry(i);
		const char *id;
		if (snd_config_get_id(n, &id) < 0)
			continue;
		if (_snd_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)
					return -EINVAL;
				card = snd_card_get_index(str);
				if (card < 0)
					return card;
			}
			continue;
		}
		if (strcmp(id, "device") == 0) {
			err = snd_config_get_integer(n, &device);
			if (err < 0)
				return err;
			continue;
		}
		SNDERR("Unexpected field %s", id);
		return -EINVAL;
	}
	if (card < 0)
		return -EINVAL;
	return snd_hwdep_hw_open(hwdep, name, card, device, mode);
}
SND_DLSYM_BUILD_VERSION(_snd_hwdep_hw_open, SND_HWDEP_DLSYM_VERSION);
