/**
 * \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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "control_local.h"
#include "control_external.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;

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

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_rawmidi_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 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\n");
		return -ENXIO;
	}

	err = snd_ctl_new(&ctl, SND_CTL_TYPE_EXT, name);
	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);
}
