/**
 * \file control/control_ext.c
 * \ingroup CtlPlugin_SDK
 * \brief External Control Plugin SDK
 * \author Takashi Iwai <tiwai@suse.de>
 * \date 2005
 */
/*
 *  Control Interface - External Control Plugin SDK
 *
 *  Copyright (c) 2005 Takashi Iwai <tiwai@suse.de>
 *
 *
 *   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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include "control_local.h"
#include "control_external.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

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

static int snd_ctl_ext_close(snd_ctl_t *handle)
{
	snd_ctl_ext_t *ext = handle->private_data;
	
	if (ext->callback->close)
		ext->callback->close(ext);
	return 0;
}

static int snd_ctl_ext_nonblock(snd_ctl_t *handle, int nonblock)
{
	snd_ctl_ext_t *ext = handle->private_data;

	ext->nonblock = nonblock;
	return 0;
}

static int snd_ctl_ext_async(snd_ctl_t *ctl ATTRIBUTE_UNUSED,
			     int sig ATTRIBUTE_UNUSED,
			     pid_t pid ATTRIBUTE_UNUSED)
{
	return -ENOSYS;
}

static int snd_ctl_ext_subscribe_events(snd_ctl_t *handle, int subscribe)
{
	snd_ctl_ext_t *ext = handle->private_data;

	if (subscribe < 0)
		return ext->subscribed;
	ext->subscribed = !!subscribe;
	if (ext->callback->subscribe_events)
		ext->callback->subscribe_events(ext, subscribe);
	return 0;
}

static int snd_ctl_ext_card_info(snd_ctl_t *handle, snd_ctl_card_info_t *info)
{
	snd_ctl_ext_t *ext = handle->private_data;

	memset(info, 0, sizeof(*info));
	info->card = ext->card_idx;
	memcpy(info->id, ext->id, sizeof(info->id));
	memcpy(info->driver, ext->driver, sizeof(info->driver));
	memcpy(info->name, ext->name, sizeof(info->name));
	memcpy(info->longname, ext->longname, sizeof(info->longname));
	memcpy(info->mixername, ext->mixername, sizeof(info->mixername));
	return 0;
}

static int snd_ctl_ext_elem_list(snd_ctl_t *handle, snd_ctl_elem_list_t *list)
{
	snd_ctl_ext_t *ext = handle->private_data;
	int ret;
	unsigned int i, offset;
	snd_ctl_elem_id_t *ids;

	list->count = ext->callback->elem_count(ext);
	list->used = 0;
	ids = list->pids;
	offset = list->offset;
	for (i = 0; i < list->space; i++) {
		if (offset >= list->count)
			break;
		snd_ctl_elem_id_clear(ids);
		ret = ext->callback->elem_list(ext, offset, ids);
		if (ret < 0)
			return ret;
		ids->numid = offset + 1; /* fake number */
		list->used++;
		offset++;
		ids++;
	}
	return 0;
}

static snd_ctl_ext_key_t get_elem(snd_ctl_ext_t *ext, snd_ctl_elem_id_t *id)
{
	int numid = id->numid;
	if (numid > 0) {
		ext->callback->elem_list(ext, numid - 1, id);
		id->numid = numid;
	} else
		id->numid = 0;
	return ext->callback->find_elem(ext, id);
}

static int snd_ctl_ext_elem_info(snd_ctl_t *handle, snd_ctl_elem_info_t *info)
{
	snd_ctl_ext_t *ext = handle->private_data;
	snd_ctl_ext_key_t key;
	int type, ret;

	key = get_elem(ext, &info->id);
	if (key == SND_CTL_EXT_KEY_NOT_FOUND)
		return -ENOENT;
	ret = ext->callback->get_attribute(ext, key, &type, &info->access, &info->count);
	if (ret < 0)
		goto err;
	info->type = type;
	ret = -EINVAL;
	switch (info->type) {
	case SND_CTL_ELEM_TYPE_BOOLEAN:
		info->value.integer.min = 0;
		info->value.integer.max = 1;
		ret = 0;
		break;
	case SND_CTL_ELEM_TYPE_INTEGER:
		if (! ext->callback->get_integer_info)
			goto err;
		ret = ext->callback->get_integer_info(ext, key, &info->value.integer.min,
						      &info->value.integer.max,
						      &info->value.integer.step);
		break;
	case SND_CTL_ELEM_TYPE_INTEGER64:
		if (! ext->callback->get_integer64_info)
			goto err;
		{
			int64_t xmin, xmax, xstep;
			ret = ext->callback->get_integer64_info(ext, key,
								&xmin,
								&xmax,
								&xstep);
			info->value.integer64.min = xmin;
			info->value.integer64.max = xmax;
			info->value.integer64.step = xstep;
		}
		break;
	case SND_CTL_ELEM_TYPE_ENUMERATED:
		if (! ext->callback->get_enumerated_info)
			goto err;
		ret = ext->callback->get_enumerated_info(ext, key, &info->value.enumerated.items);
		ext->callback->get_enumerated_name(ext, key, info->value.enumerated.item,
						   info->value.enumerated.name,
						   sizeof(info->value.enumerated.name));
		break;
	default:
		ret = 0;
		break;
	}

 err:
	if (ext->callback->free_key)
		ext->callback->free_key(ext, key);

	return ret;
}

static int snd_ctl_ext_elem_add(snd_ctl_t *handle ATTRIBUTE_UNUSED,
				snd_ctl_elem_info_t *info ATTRIBUTE_UNUSED)
{
	return -ENXIO;
}

static int snd_ctl_ext_elem_replace(snd_ctl_t *handle ATTRIBUTE_UNUSED,
				    snd_ctl_elem_info_t *info ATTRIBUTE_UNUSED)
{
	return -ENXIO;
}

static int snd_ctl_ext_elem_remove(snd_ctl_t *handle ATTRIBUTE_UNUSED,
				   snd_ctl_elem_id_t *id ATTRIBUTE_UNUSED)
{
	return -ENXIO;
}

static int snd_ctl_ext_elem_read(snd_ctl_t *handle, snd_ctl_elem_value_t *control)
{
	snd_ctl_ext_t *ext = handle->private_data;
	snd_ctl_ext_key_t key;
	int type, ret;
	unsigned int access, count;

	key = get_elem(ext, &control->id);
	if (key == SND_CTL_EXT_KEY_NOT_FOUND)
		return -ENOENT;
	ret = ext->callback->get_attribute(ext, key, &type, &access, &count);
	if (ret < 0)
		goto err;
	ret = -EINVAL;
	switch (type) {
	case SND_CTL_ELEM_TYPE_BOOLEAN:
	case SND_CTL_ELEM_TYPE_INTEGER:
		if (! ext->callback->read_integer)
			goto err;
		ret = ext->callback->read_integer(ext, key, control->value.integer.value);
		break;
	case SND_CTL_ELEM_TYPE_INTEGER64:
		if (! ext->callback->read_integer64)
			goto err;
		ret = ext->callback->read_integer64(ext, key,
						    (int64_t*)control->value.integer64.value);
		break;
	case SND_CTL_ELEM_TYPE_ENUMERATED:
		if (! ext->callback->read_enumerated)
			goto err;
		ret = ext->callback->read_enumerated(ext, key, control->value.enumerated.item);
		break;
	case SND_CTL_ELEM_TYPE_BYTES:
		if (! ext->callback->read_bytes)
			goto err;
		ret = ext->callback->read_bytes(ext, key, control->value.bytes.data,
						sizeof(control->value.bytes.data));
		break;
	case SND_CTL_ELEM_TYPE_IEC958:
		if (! ext->callback->read_iec958)
			goto err;
		ret = ext->callback->read_iec958(ext, key, (snd_aes_iec958_t *)&control->value.iec958);
		break;
	default:
		break;
	}

 err:
	if (ext->callback->free_key)
		ext->callback->free_key(ext, key);

	return ret;
}

static int snd_ctl_ext_elem_write(snd_ctl_t *handle, snd_ctl_elem_value_t *control)
{
	snd_ctl_ext_t *ext = handle->private_data;
	snd_ctl_ext_key_t key;
	int type, ret;
	unsigned int access, count;

	key = get_elem(ext, &control->id);
	if (key == SND_CTL_EXT_KEY_NOT_FOUND)
		return -ENOENT;
	ret = ext->callback->get_attribute(ext, key, &type, &access, &count);
	if (ret < 0)
		goto err;
	ret = -EINVAL;
	switch (type) {
	case SND_CTL_ELEM_TYPE_BOOLEAN:
	case SND_CTL_ELEM_TYPE_INTEGER:
		if (! ext->callback->write_integer)
			goto err;
		ret = ext->callback->write_integer(ext, key, control->value.integer.value);
		break;
	case SND_CTL_ELEM_TYPE_INTEGER64:
		if (! ext->callback->write_integer64)
			goto err;
		ret = ext->callback->write_integer64(ext, key, (int64_t *)control->value.integer64.value);
		break;
	case SND_CTL_ELEM_TYPE_ENUMERATED:
		if (! ext->callback->write_enumerated)
			goto err;
		ret = ext->callback->write_enumerated(ext, key, control->value.enumerated.item);
		break;
	case SND_CTL_ELEM_TYPE_BYTES:
		if (! ext->callback->write_bytes)
			goto err;
		ret = ext->callback->write_bytes(ext, key, control->value.bytes.data,
						sizeof(control->value.bytes.data));
		break;
	case SND_CTL_ELEM_TYPE_IEC958:
		if (! ext->callback->write_iec958)
			goto err;
		ret = ext->callback->write_iec958(ext, key, (snd_aes_iec958_t *)&control->value.iec958);
		break;
	default:
		break;
	}

 err:
	if (ext->callback->free_key)
		ext->callback->free_key(ext, key);

	return ret;
}

static int snd_ctl_ext_elem_lock(snd_ctl_t *handle ATTRIBUTE_UNUSED,
				 snd_ctl_elem_id_t *id ATTRIBUTE_UNUSED)
{
	return -ENXIO;
}

static int snd_ctl_ext_elem_unlock(snd_ctl_t *handle ATTRIBUTE_UNUSED,
				   snd_ctl_elem_id_t *id ATTRIBUTE_UNUSED)
{
	return -ENXIO;
}

static int snd_ctl_ext_elem_tlv(snd_ctl_t *handle, int op_flag,
				unsigned int numid,
				unsigned int *tlv, unsigned int tlv_size)
{
	snd_ctl_ext_t *ext = handle->private_data;
	snd_ctl_ext_key_t key;
	int type, ret;
	unsigned int access, count, len;
	snd_ctl_elem_id_t id;

	/* we don't support TLV on protocol ver 1.0.0 or earlier */
	if (ext->version <= SNDRV_PROTOCOL_VERSION(1, 0, 0))
		return -ENXIO;

	snd_ctl_elem_id_clear(&id);
	if (numid > 0) {
		ext->callback->elem_list(ext, numid - 1, &id);
		id.numid = numid;
	} else
		id.numid = 0;
	key = ext->callback->find_elem(ext, &id);

	if (key == SND_CTL_EXT_KEY_NOT_FOUND)
		return -ENOENT;
	ret = ext->callback->get_attribute(ext, key, &type, &access, &count);
	if (ret < 0)
		return ret;

	if ((op_flag == 0 && (access & SND_CTL_EXT_ACCESS_TLV_READ) == 0) ||
	    (op_flag > 0 && (access & SND_CTL_EXT_ACCESS_TLV_WRITE) == 0) ||
	    (op_flag < 0 && (access & SND_CTL_EXT_ACCESS_TLV_COMMAND) == 0))
		return -ENXIO;
	if (access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
		return ext->tlv.c(ext, key, op_flag, numid, tlv, tlv_size);
	} else {
		if (op_flag)
			return -ENXIO;
		len = ext->tlv.p[1] + 2 * sizeof(unsigned int);
		if (tlv_size < len)
			return -ENOMEM;
		memcpy(tlv, ext->tlv.p, len);
		return 0;
	}
}

static int snd_ctl_ext_next_device(snd_ctl_t *handle ATTRIBUTE_UNUSED,
				   int *device ATTRIBUTE_UNUSED)
{
	return -ENXIO;
}

static int snd_ctl_ext_prefer_subdevice(snd_ctl_t *handle ATTRIBUTE_UNUSED,
					int subdev ATTRIBUTE_UNUSED)
{
	return -ENXIO;
}

static int snd_ctl_ext_hwdep_info(snd_ctl_t *handle ATTRIBUTE_UNUSED,
				  snd_hwdep_info_t *info ATTRIBUTE_UNUSED)
{
	return -ENXIO;
}

static int snd_ctl_ext_pcm_info(snd_ctl_t *handle ATTRIBUTE_UNUSED,
				snd_pcm_info_t *info ATTRIBUTE_UNUSED)
{
	return -ENXIO;
}

static int snd_ctl_ext_rawmidi_info(snd_ctl_t *handle ATTRIBUTE_UNUSED,
				    snd_rawmidi_info_t *info ATTRIBUTE_UNUSED)
{
	return -ENXIO;
}

static int snd_ctl_ext_set_power_state(snd_ctl_t *handle ATTRIBUTE_UNUSED,
				       unsigned int state ATTRIBUTE_UNUSED)
{
	return 0;
}

static int snd_ctl_ext_get_power_state(snd_ctl_t *handle ATTRIBUTE_UNUSED,
				       unsigned int *state ATTRIBUTE_UNUSED)
{
	return 0;
}

static int snd_ctl_ext_read(snd_ctl_t *handle, snd_ctl_event_t *event)
{
	snd_ctl_ext_t *ext = handle->private_data;

	if (ext->callback->read_event) {
		memset(event, 0, sizeof(*event));
		return ext->callback->read_event(ext, &event->data.elem.id, &event->data.elem.mask);
	}

	return -EINVAL;
}

static int snd_ctl_ext_poll_descriptors_count(snd_ctl_t *handle)
{
	snd_ctl_ext_t *ext = handle->private_data;

	if (ext->callback->poll_descriptors_count)
		return ext->callback->poll_descriptors_count(ext);
	if (ext->poll_fd >= 0)
		return 1;
	return 0;
}

static int snd_ctl_ext_poll_descriptors(snd_ctl_t *handle, struct pollfd *pfds, unsigned int space)
{
	snd_ctl_ext_t *ext = handle->private_data;

	if (ext->callback->poll_descriptors)
		return ext->callback->poll_descriptors(ext, pfds, space);
	if (ext->poll_fd < 0)
		return 0;
	if (space > 0) {
		pfds->fd = ext->poll_fd;
		pfds->events = POLLIN|POLLERR|POLLNVAL;
		return 1;
	}
	return 0;
}

static int snd_ctl_ext_poll_revents(snd_ctl_t *handle, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
{
	snd_ctl_ext_t *ext = handle->private_data;

	if (ext->callback->poll_revents)
		return ext->callback->poll_revents(ext, pfds, nfds, revents);
	if (nfds == 1) {
		*revents = pfds->revents;
                return 0;
	}
	return -EINVAL;
}

static const snd_ctl_ops_t snd_ctl_ext_ops = {
	.close = snd_ctl_ext_close,
	.nonblock = snd_ctl_ext_nonblock,
	.async = snd_ctl_ext_async,
	.subscribe_events = snd_ctl_ext_subscribe_events,
	.card_info = snd_ctl_ext_card_info,
	.element_list = snd_ctl_ext_elem_list,
	.element_info = snd_ctl_ext_elem_info,
	.element_add = snd_ctl_ext_elem_add,
	.element_replace = snd_ctl_ext_elem_replace,
	.element_remove = snd_ctl_ext_elem_remove,
	.element_read = snd_ctl_ext_elem_read,
	.element_write = snd_ctl_ext_elem_write,
	.element_lock = snd_ctl_ext_elem_lock,
	.element_unlock = snd_ctl_ext_elem_unlock,
	.element_tlv = snd_ctl_ext_elem_tlv,
	.hwdep_next_device = snd_ctl_ext_next_device,
	.hwdep_info = snd_ctl_ext_hwdep_info,
	.pcm_next_device = snd_ctl_ext_next_device,
	.pcm_info = snd_ctl_ext_pcm_info,
	.pcm_prefer_subdevice = snd_ctl_ext_prefer_subdevice,
	.rawmidi_next_device = snd_ctl_ext_next_device,
	.rawmidi_info = snd_ctl_ext_rawmidi_info,
	.rawmidi_prefer_subdevice = snd_ctl_ext_prefer_subdevice,
	.set_power_state = snd_ctl_ext_set_power_state,
	.get_power_state = snd_ctl_ext_get_power_state,
	.read = snd_ctl_ext_read,
	.poll_descriptors_count = snd_ctl_ext_poll_descriptors_count,
	.poll_descriptors = snd_ctl_ext_poll_descriptors,
	.poll_revents = snd_ctl_ext_poll_revents,
};

/*
 * Exported functions
 */

/*! \page ctl_external_plugins External Control Plugin SDK

\section ctl_externals External Control Plugins

The external plugins are implemented in a shared object file located
at /usr/lib/alsa-lib (the exact location depends on the build option
and asoundrc configuration).  It has to be the file like
libasound_module_ctl_MYPLUGIN.so, where MYPLUGIN corresponds to your
own plugin name.

The entry point of the plugin is defined via
#SND_CTL_PLUGIN_DEFINE_FUNC() macro.  This macro defines the function
with a proper name to be referred from alsa-lib.  The function takes
the following 5 arguments:
\code
int (snd_ctl_t **phandle, const char *name, snd_config_t *root,
	snd_config_t *conf, int mode)
\endcode
The first argument, phandle, is the pointer to store the resultant control
handle.  The arguments name, root and mode are the parameters
to be passed to the plugin constructor.  The conf is the configuration
tree for the plugin.  The arguments above are defined in the macro
itself, so don't use variables with the same names to shadow
parameters.

After parsing the configuration parameters in the given conf tree,
usually you will call the external plugin API function
#snd_ctl_ext_create().
The control handle must be filled *phandle in return.
Then this function must return either a value 0 when succeeded, or a
negative value as the error code. 

Finally, add #SND_CTL_PLUGIN_SYMBOL() with the name of your
plugin as the argument at the end.  This defines the proper versioned
symbol as the reference.

The typical code would look like below:
\code
struct myctl_info {
	snd_ctl_ext_t ext;
	int my_own_data;
	...
};

SND_CTL_PLUGIN_DEFINE_FUNC(myctl)
{
	snd_config_iterator_t i, next;
	struct myctl_info *myctl;
	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 (strcmp(id, "comment") == 0 || strcmp(id, "type") == 0)
			continue;
		if (strcmp(id, "my_own_parameter") == 0) {
			....
			continue;
		}
		SNDERR("Unknown field %s", id);
		return -EINVAL;
	}

	myctl = calloc(1, sizeof(*myctl));
	if (myctl == NULL)
		return -ENOMEM;

	myctl->ext.version = SND_CTL_EXT_VERSION;
	myctl->ext.card_idx = 0;
	strcpy(myctl->ext.id, "Myctl");
	strcpy(myctl->ext.name, "My Control");
	strcpy(myctl->ext.longname, "My External Control for Foobar");
	strcpy(myctl->ext.mixername, "My Control");
	myctl->ext.callback = &my_own_callback;
	myctl->ext.private_data = myctl;
	....

	err = snd_pcm_extplug_create(&myctl->ext, name, mode);
	if (err < 0) {
		myctl_free(myctl);
		return err;
	}

	*phandle = myctl->ext.handle;
	return 0;
}

SND_CTL_PLUGIN_SYMBOL(myctl);
\endcode

Read the codes in alsa-plugins package for the real examples.


\section ctl_ext_impl Implementation of External Control Plugins

The following fields have to be filled in external control record before calling
#snd_ctl_ext_create() : version, card_idx, id, name, longname, mixername, poll_fd and callback.
Otherfields are optional and should be initialized with zero.

The constant #SND_CTL_EXT_VERSION must be passed to the version
field for the version check in alsa-lib.  The card_idx field specifies the card
index of this control.  [FIXME: solve confliction of card index in alsa-lib?]

The id, name, longname and mixername fields are the strings shown in the card_info
inqurirys.  They are the char arrays, so you have to <i>copy</i> strings to these
fields.

The callback field contains the  table of callback functions for this plugin (defined as
#snd_ctl_ext_callback_t).
The poll_fd can be used to specify the poll file descriptor for this control.
Set -1 if not available.  Alternatively, you can define poll_descriptors_count and
poll_descriptors callbacks in the callback table for handling the poll descriptor(s)
dynamically after the creation of plugin instance.

The driver can set an arbitrary value (pointer) to private_data
field to refer its own data in the callbacks.

The rest fields are filled by #snd_ctl_ext_create().  The handle field
is the resultant PCM handle.  The others are the current status of the
PCM.

\section ctl_ext_impl_cb Callback Functions of External Control Plugins

The callback functions in #snd_ctl_ext_callback_t define the real
behavior of the driver.  There are many callbacks but many of them are optional. 

The close callback is called when the PCM is closed.  If the plugin
allocates private resources, this is the place to release them
again.  This callback is optional.

The elem_count and elem_list callbacks are mandatory.  The elem_count returns the
total number of control elements.  The elem_list returns the control element ID
of the corresponding element offset (the offset is from 0 to elem_count - 1).
The id field is initialized to all zero in prior to elem_list callback.  The callback
has to fill the necessary field (typically iface, name and index) in return via the
standard control API functions like #snd_ctl_elem_id_set_interface,
#snd_ctl_elem_id_set_name and #snd_ctl_elem_id_set_index, etc.  The callbacks should
return 0 if successful, or a negative error code.

The find_elem callback is used to convert the given control element ID to the
certain key value for the faster access to get, read and write callbacks.
The key type is alias of unsigned long, so you can assign some static number
(e.g. index of the array) to this value of the corresponding element, or
assign the pointer (cast to #snd_ctl_ext_key_t).  When no key is defined or found,
return #SND_CTL_EXT_KEY_NOT_FOUND.  This callback is (very likely) required
if you use get, read and write callbacks as follows.
If you need to create a record dynamically (e.g. via malloc) at each find_elem call,
the allocated record can be released with the optional free_key callback.

The get_attribute is a mandatory callback, which returns the attribute of the 
control element given via a key value (converted with find_elem callback).
It must fill the control element type (#snd_ctl_elem_type_t), the access type
(#snd_ctl_ext_access_t), and the count (element array size).  The callback returns
0 if successful, or a negative error code, as usual.

The get_integer_info, get_integetr64_info and get_enumerated_info callbacks are called
to return the information of the given control element for each element type.
For integer and integer64 types, the callbacks need to fill the minimal (imin),
maximal (imax) and the step (istep) values of the control.  For the enumerated type,
the number of enum items must be filled.  Additionally, the enum control has to define
get_enumerated_name callback to store the name of the enumerated item of the given control
element.  All functions return 0 if successful, or a negative error code.

For reading the current values of a control element, read_integer, read_integer64,
read_enumerated, read_bytes and read_iec958 callbacks are called depending on the
element type.  These callbacks have to fill the current values of the element in return.
Note that a control element can be an array.  If it contains more than one values
(i.e. the count value in get_attribute callback is more than 1), <i>all</i> values
must be filled on the given value pointer as an array.  Also, note that the boolean type
is handled as integer here (although boolean type doesn't need to define the corresponding
info callback since it's obvious).  These callbacks return 0 if successful, or
a negative error code.

For writing the current values, write_integer, write_integer64, write_bytes, and
write_iec958 callbacks are called as well as for read.  The callbacks should check the
current values and compare with the given values.  If they are identical, the callbacks
should do nothing and return 0.  If they differ, update the current values and return 1,
instead.  For any errors, return a negative error code.

The subscribe_events callback is called when the application subscribes or cancels
the event notifications (e.g. through mixer API).  The current value of event
subscription is kept in the subscribed field.
The read_event callback is called for reading a pending notification event.
The callback needs to fill the event_mask value, a bit-field defined as SND_CTL_EVENT_MASK_XXX.
If no event is pending, return -EAGAIN.  These two callbacks are optional.

The poll_descriptors_count and poll_descriptors callbacks are used to return
the poll descriptor(s) via callbacks.  As already mentioned, if the callback cannot
set the static poll_fd, you can define these callbacks to return dynamically.
Also, when multiple poll descriptors are required, use these callbacks.
The poll_revents callback is used for handle poll revents.

*/

/**
 * \brief Create an external control plugin instance
 * \param ext the plugin handle
 * \param name name of control
 * \param mode control open mode
 * \return 0 if successful, or a negative error code
 *
 * Creates the external control instance.
 *
 */
int snd_ctl_ext_create(snd_ctl_ext_t *ext, const char *name, int mode)
{
	snd_ctl_t *ctl;
	int err;

	if (ext->version < SNDRV_PROTOCOL_VERSION(1, 0, 0) ||
	    ext->version > SND_CTL_EXT_VERSION) {
		SNDERR("ctl_ext: Plugin version mismatch");
		return -ENXIO;
	}

	err = snd_ctl_new(&ctl, SND_CTL_TYPE_EXT, name, mode);
	if (err < 0)
		return err;

	ext->handle = ctl;

	ctl->ops = &snd_ctl_ext_ops;
	ctl->private_data = ext;
	ctl->poll_fd = ext->poll_fd;
	if (mode & SND_CTL_NONBLOCK)
		ext->nonblock = 1;

	return 0;
}

/**
 * \brief Delete the external control plugin
 * \param ext the plugin handle
 * \return 0 if successful, or a negative error code
 */
int snd_ctl_ext_delete(snd_ctl_ext_t *ext)
{
	return snd_ctl_close(ext->handle);
}
