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