Home | History | Annotate | Download | only in hwdep
      1 /**
      2  * \file hwdep/hwdep.c
      3  * \brief HwDep Interface (hardware dependent)
      4  * \author Jaroslav Kysela <perex (at) perex.cz>
      5  * \date 2000-2001
      6  *
      7  * HwDep (hardware dependent) Interface is designed for individual hardware
      8  * access. This interface does not cover any API specification.
      9  */
     10 /*
     11  *  Hardware dependent Interface - main file
     12  *  Copyright (c) 2000 by Jaroslav Kysela <perex (at) perex.cz>
     13  *
     14  *
     15  *   This library is free software; you can redistribute it and/or modify
     16  *   it under the terms of the GNU Lesser General Public License as
     17  *   published by the Free Software Foundation; either version 2.1 of
     18  *   the License, or (at your option) any later version.
     19  *
     20  *   This program is distributed in the hope that it will be useful,
     21  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     22  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     23  *   GNU Lesser General Public License for more details.
     24  *
     25  *   You should have received a copy of the GNU Lesser General Public
     26  *   License along with this library; if not, write to the Free Software
     27  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
     28  *
     29  */
     30 
     31 #include <stdio.h>
     32 #include <stdlib.h>
     33 #include <unistd.h>
     34 #include <string.h>
     35 #include <fcntl.h>
     36 #include <sys/ioctl.h>
     37 #include "hwdep_local.h"
     38 
     39 static int snd_hwdep_open_conf(snd_hwdep_t **hwdep,
     40 			       const char *name, snd_config_t *hwdep_root,
     41 			       snd_config_t *hwdep_conf, int mode)
     42 {
     43 	const char *str;
     44 	char buf[256];
     45 	int err;
     46 	snd_config_t *conf, *type_conf = NULL;
     47 	snd_config_iterator_t i, next;
     48 	const char *id;
     49 	const char *lib = NULL, *open_name = NULL;
     50 	int (*open_func)(snd_hwdep_t **, const char *, snd_config_t *, snd_config_t *, int) = NULL;
     51 #ifndef PIC
     52 	extern void *snd_hwdep_open_symbols(void);
     53 #endif
     54 	void *h = NULL;
     55 	if (snd_config_get_type(hwdep_conf) != SND_CONFIG_TYPE_COMPOUND) {
     56 		if (name)
     57 			SNDERR("Invalid type for HWDEP %s definition", name);
     58 		else
     59 			SNDERR("Invalid type for HWDEP definition");
     60 		return -EINVAL;
     61 	}
     62 	err = snd_config_search(hwdep_conf, "type", &conf);
     63 	if (err < 0) {
     64 		SNDERR("type is not defined");
     65 		return err;
     66 	}
     67 	err = snd_config_get_id(conf, &id);
     68 	if (err < 0) {
     69 		SNDERR("unable to get id");
     70 		return err;
     71 	}
     72 	err = snd_config_get_string(conf, &str);
     73 	if (err < 0) {
     74 		SNDERR("Invalid type for %s", id);
     75 		return err;
     76 	}
     77 	err = snd_config_search_definition(hwdep_root, "hwdep_type", str, &type_conf);
     78 	if (err >= 0) {
     79 		if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) {
     80 			SNDERR("Invalid type for HWDEP type %s definition", str);
     81 			goto _err;
     82 		}
     83 		snd_config_for_each(i, next, type_conf) {
     84 			snd_config_t *n = snd_config_iterator_entry(i);
     85 			const char *id;
     86 			if (snd_config_get_id(n, &id) < 0)
     87 				continue;
     88 			if (strcmp(id, "comment") == 0)
     89 				continue;
     90 			if (strcmp(id, "lib") == 0) {
     91 				err = snd_config_get_string(n, &lib);
     92 				if (err < 0) {
     93 					SNDERR("Invalid type for %s", id);
     94 					goto _err;
     95 				}
     96 				continue;
     97 			}
     98 			if (strcmp(id, "open") == 0) {
     99 				err = snd_config_get_string(n, &open_name);
    100 				if (err < 0) {
    101 					SNDERR("Invalid type for %s", id);
    102 					goto _err;
    103 				}
    104 				continue;
    105 			}
    106 			SNDERR("Unknown field %s", id);
    107 			err = -EINVAL;
    108 			goto _err;
    109 		}
    110 	}
    111 	if (!open_name) {
    112 		open_name = buf;
    113 		snprintf(buf, sizeof(buf), "_snd_hwdep_%s_open", str);
    114 	}
    115 #ifndef PIC
    116 	snd_hwdep_open_symbols();
    117 #endif
    118 	h = snd_dlopen(lib, RTLD_NOW);
    119 	if (h)
    120 		open_func = snd_dlsym(h, open_name, SND_DLSYM_VERSION(SND_HWDEP_DLSYM_VERSION));
    121 	err = 0;
    122 	if (!h) {
    123 		SNDERR("Cannot open shared library %s", lib);
    124 		err = -ENOENT;
    125 	} else if (!open_func) {
    126 		SNDERR("symbol %s is not defined inside %s", open_name, lib);
    127 		snd_dlclose(h);
    128 		err = -ENXIO;
    129 	}
    130        _err:
    131 	if (type_conf)
    132 		snd_config_delete(type_conf);
    133 	if (err >= 0) {
    134 		err = open_func(hwdep, name, hwdep_root, hwdep_conf, mode);
    135 		if (err >= 0) {
    136 			(*hwdep)->dl_handle = h;
    137 		} else {
    138 			snd_dlclose(h);
    139 		}
    140 	}
    141 	return err;
    142 }
    143 
    144 static int snd_hwdep_open_noupdate(snd_hwdep_t **hwdep, snd_config_t *root, const char *name, int mode)
    145 {
    146 	int err;
    147 	snd_config_t *hwdep_conf;
    148 	err = snd_config_search_definition(root, "hwdep", name, &hwdep_conf);
    149 	if (err < 0) {
    150 		SNDERR("Unknown HwDep %s", name);
    151 		return err;
    152 	}
    153 	err = snd_hwdep_open_conf(hwdep, name, root, hwdep_conf, mode);
    154 	snd_config_delete(hwdep_conf);
    155 	return err;
    156 }
    157 
    158 /**
    159  * \brief Opens a new connection to the HwDep interface.
    160  * \param hwdep Returned handle (NULL if not wanted)
    161  * \param name ASCII identifier of the HwDep handle
    162  * \param mode Open mode
    163  * \return 0 on success otherwise a negative error code
    164  *
    165  * Opens a new connection to the HwDep interface specified with
    166  * an ASCII identifier and mode.
    167  */
    168 int snd_hwdep_open(snd_hwdep_t **hwdep, const char *name, int mode)
    169 {
    170 	int err;
    171 	assert(hwdep && name);
    172 	err = snd_config_update();
    173 	if (err < 0)
    174 		return err;
    175 	return snd_hwdep_open_noupdate(hwdep, snd_config, name, mode);
    176 }
    177 
    178 /**
    179  * \brief Opens a new connection to the HwDep interface using local configuration
    180  * \param hwdep Returned handle (NULL if not wanted)
    181  * \param name ASCII identifier of the HwDep handle
    182  * \param mode Open mode
    183  * \param lconf The local configuration tree
    184  * \return 0 on success otherwise a negative error code
    185  *
    186  * Opens a new connection to the HwDep interface specified with
    187  * an ASCII identifier and mode.
    188  */
    189 int snd_hwdep_open_lconf(snd_hwdep_t **hwdep, const char *name,
    190 			 int mode, snd_config_t *lconf)
    191 {
    192 	assert(hwdep && name && lconf);
    193 	return snd_hwdep_open_noupdate(hwdep, lconf, name, mode);
    194 }
    195 
    196 /**
    197  * \brief close HwDep handle
    198  * \param hwdep HwDep handle
    199  * \return 0 on success otherwise a negative error code
    200  *
    201  * Closes the specified HwDep handle and frees all associated
    202  * resources.
    203  */
    204 int snd_hwdep_close(snd_hwdep_t *hwdep)
    205 {
    206 	int err;
    207   	assert(hwdep);
    208 	err = hwdep->ops->close(hwdep);
    209 	if (hwdep->dl_handle)
    210 		snd_dlclose(hwdep->dl_handle);
    211 	free(hwdep->name);
    212 	free(hwdep);
    213 	return err;
    214 }
    215 
    216 /**
    217  * \brief get identifier of HwDep handle
    218  * \param hwdep a Hwdep handle
    219  * \return ascii identifier of HwDep handle
    220  *
    221  * Returns the ASCII identifier of given HwDep handle. It's the same
    222  * identifier specified in snd_hwdep_open().
    223  */
    224 const char *snd_hwdep_name(snd_hwdep_t *hwdep)
    225 {
    226 	assert(hwdep);
    227 	return hwdep->name;
    228 }
    229 
    230 /**
    231  * \brief get type of HwDep handle
    232  * \param hwdep a HwDep handle
    233  * \return type of HwDep handle
    234  *
    235  * Returns the type #snd_hwdep_type_t of given HwDep handle.
    236  */
    237 snd_hwdep_type_t snd_hwdep_type(snd_hwdep_t *hwdep)
    238 {
    239 	assert(hwdep);
    240 	return hwdep->type;
    241 }
    242 
    243 /**
    244  * \brief get count of poll descriptors for HwDep handle
    245  * \param hwdep HwDep handle
    246  * \return count of poll descriptors
    247  */
    248 int snd_hwdep_poll_descriptors_count(snd_hwdep_t *hwdep)
    249 {
    250 	assert(hwdep);
    251 	return 1;
    252 }
    253 
    254 /**
    255  * \brief get poll descriptors
    256  * \param hwdep HwDep handle
    257  * \param pfds array of poll descriptors
    258  * \param space space in the poll descriptor array
    259  * \return count of filled descriptors
    260  */
    261 int snd_hwdep_poll_descriptors(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned int space)
    262 {
    263 	assert(hwdep);
    264 	if (space >= 1) {
    265 		pfds->fd = hwdep->poll_fd;
    266 		switch (hwdep->mode & O_ACCMODE) {
    267 		case O_WRONLY:
    268 			pfds->events = POLLOUT|POLLERR|POLLNVAL;
    269 			break;
    270 		case O_RDONLY:
    271 			pfds->events = POLLIN|POLLERR|POLLNVAL;
    272 			break;
    273 		case O_RDWR:
    274 			pfds->events = POLLOUT|POLLIN|POLLERR|POLLNVAL;
    275 			break;
    276 		default:
    277 			return -EIO;
    278 		}
    279 		return 1;
    280 	}
    281 	return 0;
    282 }
    283 
    284 /**
    285  * \brief get returned events from poll descriptors
    286  * \param hwdep HwDep  handle
    287  * \param pfds array of poll descriptors
    288  * \param nfds count of poll descriptors
    289  * \param revents returned events
    290  * \return zero if success, otherwise a negative error code
    291  */
    292 int snd_hwdep_poll_descriptors_revents(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
    293 {
    294         assert(hwdep && pfds && revents);
    295         if (nfds == 1) {
    296                 *revents = pfds->revents;
    297                 return 0;
    298         }
    299         return -EINVAL;
    300 }
    301 
    302 /**
    303  * \brief set nonblock mode
    304  * \param hwdep HwDep handle
    305  * \param nonblock 0 = block, 1 = nonblock mode
    306  * \return 0 on success otherwise a negative error code
    307  */
    308 int snd_hwdep_nonblock(snd_hwdep_t *hwdep, int nonblock)
    309 {
    310 	int err;
    311 	assert(hwdep);
    312 	if ((err = hwdep->ops->nonblock(hwdep, nonblock)) < 0)
    313 		return err;
    314 	if (nonblock)
    315 		hwdep->mode |= SND_HWDEP_OPEN_NONBLOCK;
    316 	else
    317 		hwdep->mode &= ~SND_HWDEP_OPEN_NONBLOCK;
    318 	return 0;
    319 }
    320 
    321 /**
    322  * \brief get size of the snd_hwdep_info_t structure in bytes
    323  * \return size of the snd_hwdep_info_t structure in bytes
    324  */
    325 size_t snd_hwdep_info_sizeof()
    326 {
    327 	return sizeof(snd_hwdep_info_t);
    328 }
    329 
    330 /**
    331  * \brief allocate a new snd_hwdep_info_t structure
    332  * \param info returned pointer
    333  * \return 0 on success otherwise a negative error code if fails
    334  *
    335  * Allocates a new snd_hwdep_info_t structure using the standard
    336  * malloc C library function.
    337  */
    338 int snd_hwdep_info_malloc(snd_hwdep_info_t **info)
    339 {
    340 	assert(info);
    341 	*info = calloc(1, sizeof(snd_hwdep_info_t));
    342 	if (!*info)
    343 		return -ENOMEM;
    344 	return 0;
    345 }
    346 
    347 /**
    348  * \brief frees the snd_hwdep_info_t structure
    349  * \param info pointer to the snd_hwdep_info_t structure to free
    350  *
    351  * Frees the given snd_hwdep_info_t structure using the standard
    352  * free C library function.
    353  */
    354 void snd_hwdep_info_free(snd_hwdep_info_t *info)
    355 {
    356 	assert(info);
    357 	free(info);
    358 }
    359 
    360 /**
    361  * \brief copy one snd_hwdep_info_t structure to another
    362  * \param dst destination snd_hwdep_info_t structure
    363  * \param src source snd_hwdep_info_t structure
    364  */
    365 void snd_hwdep_info_copy(snd_hwdep_info_t *dst, const snd_hwdep_info_t *src)
    366 {
    367 	assert(dst && src);
    368 	*dst = *src;
    369 }
    370 
    371 /**
    372  * \brief get hwdep card number
    373  * \param obj pointer to a snd_hwdep_info_t structure
    374  * \return hwdep card number
    375  */
    376 int snd_hwdep_info_get_card(const snd_hwdep_info_t *obj)
    377 {
    378 	assert(obj);
    379 	return obj->card;
    380 }
    381 
    382 /**
    383  * \brief get hwdep device number
    384  * \param info pointer to a snd_hwdep_info_t structure
    385  * \return hwdep device number
    386  */
    387 unsigned int snd_hwdep_info_get_device(const snd_hwdep_info_t *info)
    388 {
    389 	assert(info);
    390 	return info->device;
    391 }
    392 
    393 /**
    394  * \brief get hwdep driver identifier
    395  * \param obj pointer to a snd_hwdep_info_t structure
    396  * \return hwdep driver identifier
    397  */
    398 const char *snd_hwdep_info_get_id(const snd_hwdep_info_t *obj)
    399 {
    400 	assert(obj);
    401 	return (const char *)obj->id;
    402 }
    403 
    404 /**
    405  * \brief get hwdep driver name
    406  * \param obj pointer to a snd_hwdep_info_t structure
    407  * \return hwdep driver name
    408  */
    409 const char *snd_hwdep_info_get_name(const snd_hwdep_info_t *obj)
    410 {
    411 	assert(obj);
    412 	return (const char *)obj->name;
    413 }
    414 
    415 /**
    416  * \brief get hwdep protocol interface
    417  * \param obj pointer to a snd_hwdep_info_t structure
    418  * \return hwdep protocol interface
    419  */
    420 snd_hwdep_iface_t snd_hwdep_info_get_iface(const snd_hwdep_info_t *obj)
    421 {
    422 	assert(obj);
    423 	return obj->iface;
    424 }
    425 
    426 /**
    427  * \brief set hwdep device number
    428  * \param obj pointer to a snd_hwdep_info_t structure
    429  * \param val hwdep device
    430  */
    431 void snd_hwdep_info_set_device(snd_hwdep_info_t *obj, unsigned int val)
    432 {
    433 	assert(obj);
    434 	obj->device = val;
    435 }
    436 
    437 /**
    438  * \brief get information about HwDep handle
    439  * \param hwdep HwDep handle
    440  * \param info pointer to a snd_hwdep_info_t structure to be filled
    441  * \return 0 on success otherwise a negative error code
    442  */
    443 int snd_hwdep_info(snd_hwdep_t *hwdep, snd_hwdep_info_t * info)
    444 {
    445 	assert(hwdep);
    446 	assert(info);
    447 	return hwdep->ops->info(hwdep, info);
    448 }
    449 
    450 /**
    451  * \brief do hardware dependent ioctl
    452  * \param hwdep HwDep handle
    453  * \param request ioctl command
    454  * \param arg ioctl argument
    455  * \return 0 on success otherwise a negative error code
    456  */
    457 int snd_hwdep_ioctl(snd_hwdep_t *hwdep, unsigned int request, void * arg)
    458 {
    459 	assert(hwdep);
    460 	return hwdep->ops->ioctl(hwdep, request, arg);
    461 }
    462 
    463 /**
    464  * \brief write bytes using HwDep handle
    465  * \param hwdep HwDep handle
    466  * \param buffer buffer containing bytes to write
    467  * \param size output buffer size in bytes
    468  */
    469 ssize_t snd_hwdep_write(snd_hwdep_t *hwdep, const void *buffer, size_t size)
    470 {
    471 	assert(hwdep);
    472 	assert(((hwdep->mode & O_ACCMODE) == O_WRONLY) || ((hwdep->mode & O_ACCMODE) == O_RDWR));
    473 	assert(buffer || size == 0);
    474 	return hwdep->ops->write(hwdep, buffer, size);
    475 }
    476 
    477 /**
    478  * \brief read bytes using HwDep handle
    479  * \param hwdep HwDep handle
    480  * \param buffer buffer to store the input bytes
    481  * \param size input buffer size in bytes
    482  */
    483 ssize_t snd_hwdep_read(snd_hwdep_t *hwdep, void *buffer, size_t size)
    484 {
    485 	assert(hwdep);
    486 	assert(((hwdep->mode & O_ACCMODE) == O_RDONLY) || ((hwdep->mode & O_ACCMODE) == O_RDWR));
    487 	assert(buffer || size == 0);
    488 	return (hwdep->ops->read)(hwdep, buffer, size);
    489 }
    490 
    491 /**
    492  * \brief get the DSP status information
    493  * \param hwdep HwDep handle
    494  * \param info pointer to a snd_hwdep_dsp_status_t structure to be filled
    495  * \return 0 on success otherwise a negative error code
    496  */
    497 int snd_hwdep_dsp_status(snd_hwdep_t *hwdep, snd_hwdep_dsp_status_t *info)
    498 {
    499 	assert(hwdep);
    500 	assert(info);
    501 	return hwdep->ops->ioctl(hwdep, SNDRV_HWDEP_IOCTL_DSP_STATUS, (void*)info);
    502 }
    503 
    504 /**
    505  * \brief load the DSP block
    506  * \param hwdep HwDep handle
    507  * \param block pointer to a snd_hwdep_dsp_image_t structure to transfer
    508  * \return 0 on success otherwise a negative error code
    509  */
    510 int snd_hwdep_dsp_load(snd_hwdep_t *hwdep, snd_hwdep_dsp_image_t *block)
    511 {
    512 	assert(hwdep);
    513 	assert(block);
    514 	return hwdep->ops->ioctl(hwdep, SNDRV_HWDEP_IOCTL_DSP_LOAD, (void*)block);
    515 }
    516 
    517 /**
    518  * \brief get size of the snd_hwdep_dsp_status_t structure in bytes
    519  * \return size of the snd_hwdep_dsp_status_t structure in bytes
    520  */
    521 size_t snd_hwdep_dsp_status_sizeof()
    522 {
    523 	return sizeof(snd_hwdep_dsp_status_t);
    524 }
    525 
    526 /**
    527  * \brief allocate a new snd_hwdep_dsp_status_t structure
    528  * \param info returned pointer
    529  * \return 0 on success otherwise a negative error code if fails
    530  *
    531  * Allocates a new snd_hwdep_dsp_status_t structure using the standard
    532  * malloc C library function.
    533  */
    534 int snd_hwdep_dsp_status_malloc(snd_hwdep_dsp_status_t **info)
    535 {
    536 	assert(info);
    537 	*info = calloc(1, sizeof(snd_hwdep_dsp_status_t));
    538 	if (!*info)
    539 		return -ENOMEM;
    540 	return 0;
    541 }
    542 
    543 /**
    544  * \brief frees the snd_hwdep_dsp_status_t structure
    545  * \param info pointer to the snd_hwdep_dsp_status_t structure to free
    546  *
    547  * Frees the given snd_hwdep_dsp_status_t structure using the standard
    548  * free C library function.
    549  */
    550 void snd_hwdep_dsp_status_free(snd_hwdep_dsp_status_t *info)
    551 {
    552 	assert(info);
    553 	free(info);
    554 }
    555 
    556 /**
    557  * \brief copy one snd_hwdep_dsp_status_t structure to another
    558  * \param dst destination snd_hwdep_dsp_status_t structure
    559  * \param src source snd_hwdep_dsp_status_t structure
    560  */
    561 void snd_hwdep_dsp_status_copy(snd_hwdep_dsp_status_t *dst, const snd_hwdep_dsp_status_t *src)
    562 {
    563 	assert(dst && src);
    564 	*dst = *src;
    565 }
    566 
    567 /**
    568  * \brief get the driver version of dsp loader
    569  * \param obj pointer to a snd_hwdep_dsp_status_t structure
    570  * \return the driver version
    571  */
    572 unsigned int snd_hwdep_dsp_status_get_version(const snd_hwdep_dsp_status_t *obj)
    573 {
    574 	assert(obj);
    575 	return obj->version;
    576 }
    577 
    578 /**
    579  * \brief get the driver id of dsp loader
    580  * \param obj pointer to a snd_hwdep_dsp_status_t structure
    581  * \return the driver id string
    582  */
    583 const char *snd_hwdep_dsp_status_get_id(const snd_hwdep_dsp_status_t *obj)
    584 {
    585 	assert(obj);
    586 	return (const char *)obj->id;
    587 }
    588 
    589 /**
    590  * \brief get number of dsp blocks
    591  * \param obj pointer to a snd_hwdep_dsp_status_t structure
    592  * \return number of dsp blocks
    593  */
    594 unsigned int snd_hwdep_dsp_status_get_num_dsps(const snd_hwdep_dsp_status_t *obj)
    595 {
    596 	assert(obj);
    597 	return obj->num_dsps;
    598 }
    599 
    600 /**
    601  * \brief get the bit flags of the loaded dsp blocks
    602  * \param info pointer to a snd_hwdep_dsp_status_t structure
    603  * \return the big flags of the loaded dsp blocks
    604  */
    605 unsigned int snd_hwdep_dsp_status_get_dsp_loaded(const snd_hwdep_dsp_status_t *info)
    606 {
    607 	assert(info);
    608 	return info->dsp_loaded;
    609 }
    610 
    611 /**
    612  * \brief get the chip status of dsp loader
    613  * \param obj pointer to a snd_hwdep_dsp_status_t structure
    614  * \return non-zero if all DSP blocks are loaded and the chip is ready
    615  */
    616 unsigned int snd_hwdep_dsp_status_get_chip_ready(const snd_hwdep_dsp_status_t *obj)
    617 {
    618 	assert(obj);
    619 	return obj->chip_ready;
    620 }
    621 
    622 /**
    623  * \brief get size of the snd_hwdep_dsp_image_t structure in bytes
    624  * \return size of the snd_hwdep_dsp_image_t structure in bytes
    625  */
    626 size_t snd_hwdep_dsp_image_sizeof()
    627 {
    628 	return sizeof(snd_hwdep_dsp_image_t);
    629 }
    630 
    631 /**
    632  * \brief allocate a new snd_hwdep_dsp_image_t structure
    633  * \param info returned pointer
    634  * \return 0 on success otherwise a negative error code if fails
    635  *
    636  * Allocates a new snd_hwdep_dsp_image_t structure using the standard
    637  * malloc C library function.
    638  */
    639 int snd_hwdep_dsp_image_malloc(snd_hwdep_dsp_image_t **info)
    640 {
    641 	assert(info);
    642 	*info = calloc(1, sizeof(snd_hwdep_dsp_image_t));
    643 	if (!*info)
    644 		return -ENOMEM;
    645 	return 0;
    646 }
    647 
    648 /**
    649  * \brief frees the snd_hwdep_dsp_image_t structure
    650  * \param info pointer to the snd_hwdep_dsp_image_t structure to free
    651  *
    652  * Frees the given snd_hwdep_dsp_image_t structure using the standard
    653  * free C library function.
    654  */
    655 void snd_hwdep_dsp_image_free(snd_hwdep_dsp_image_t *info)
    656 {
    657 	assert(info);
    658 	free(info);
    659 }
    660 
    661 /**
    662  * \brief copy one snd_hwdep_dsp_image_t structure to another
    663  * \param dst destination snd_hwdep_dsp_image_t structure
    664  * \param src source snd_hwdep_dsp_image_t structure
    665  */
    666 void snd_hwdep_dsp_image_copy(snd_hwdep_dsp_image_t *dst, const snd_hwdep_dsp_image_t *src)
    667 {
    668 	assert(dst && src);
    669 	*dst = *src;
    670 }
    671 
    672 /**
    673  * \brief get the DSP block index
    674  * \param obj pointer to a snd_hwdep_dsp_image_t structure
    675  * \return the index of the DSP block
    676  */
    677 unsigned int snd_hwdep_dsp_image_get_index(const snd_hwdep_dsp_image_t *obj)
    678 {
    679 	assert(obj);
    680 	return obj->index;
    681 }
    682 
    683 /**
    684  * \brief get the name of the DSP block
    685  * \param obj pointer to a snd_hwdep_dsp_image_t structure
    686  * \return the name string of the DSP block
    687  */
    688 const char *snd_hwdep_dsp_image_get_name(const snd_hwdep_dsp_image_t *obj)
    689 {
    690 	assert(obj);
    691 	return (const char *)obj->name;
    692 }
    693 
    694 /**
    695  * \brief get the length of the DSP block
    696  * \param obj pointer to a snd_hwdep_dsp_image_t structure
    697  * \return the length of the DSP block in bytes
    698  */
    699 size_t snd_hwdep_dsp_image_get_length(const snd_hwdep_dsp_image_t *obj)
    700 {
    701 	assert(obj);
    702 	return obj->length;
    703 }
    704 
    705 /**
    706  * \brief get the image pointer of the DSP block
    707  * \param obj pointer to a snd_hwdep_dsp_image_t structure
    708  * \return the image pointer of the DSP block
    709  */
    710 const void *snd_hwdep_dsp_image_get_image(const snd_hwdep_dsp_image_t *obj)
    711 {
    712 	assert(obj);
    713 	return obj->image;
    714 }
    715 
    716 /**
    717  * \brief set the DSP block index
    718  * \param obj pointer to a snd_hwdep_dsp_image_t structure
    719  * \param index the index value to set
    720  */
    721 void snd_hwdep_dsp_image_set_index(snd_hwdep_dsp_image_t *obj, unsigned int index)
    722 {
    723 	assert(obj);
    724 	obj->index = index;
    725 }
    726 
    727 /**
    728  * \brief set the name of the DSP block
    729  * \param obj pointer to a snd_hwdep_dsp_image_t structure
    730  * \param name the name string
    731  */
    732 void snd_hwdep_dsp_image_set_name(snd_hwdep_dsp_image_t *obj, const char *name)
    733 {
    734 	assert(obj && name);
    735 	strncpy((char *)obj->name, name, sizeof(obj->name));
    736 	obj->name[sizeof(obj->name)-1] = 0;
    737 }
    738 
    739 /**
    740  * \brief set the DSP block length
    741  * \param obj pointer to a snd_hwdep_dsp_image_t structure
    742  * \param length the length of the DSP block
    743  */
    744 void snd_hwdep_dsp_image_set_length(snd_hwdep_dsp_image_t *obj, size_t length)
    745 {
    746 	assert(obj);
    747 	obj->length = length;
    748 }
    749 
    750 /**
    751  * \brief set the DSP block image pointer
    752  * \param obj pointer to a snd_hwdep_dsp_image_t structure
    753  * \param image the DSP image pointer
    754  */
    755 void snd_hwdep_dsp_image_set_image(snd_hwdep_dsp_image_t *obj, void *image)
    756 {
    757 	assert(obj);
    758 	obj->image = image;
    759 }
    760 
    761