Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /* IIO - useful set of util functionality
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (c) 2008 Jonathan Cameron
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <stdint.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <dirent.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include "iio_utils.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) const char *iio_dir = "/sys/bus/iio/devices/";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) static char * const iio_direction[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	"in",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	"out",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * iioutils_break_up_name() - extract generic name from full channel name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * @full_name: the full channel name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * @generic_name: the output generic channel name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * Returns 0 on success, or a negative error code if string extraction failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) int iioutils_break_up_name(const char *full_name, char **generic_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	char *current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	char *w, *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	char *working, *prefix = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	for (i = 0; i < ARRAY_SIZE(iio_direction); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 		if (!strncmp(full_name, iio_direction[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 			     strlen(iio_direction[i]))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 			prefix = iio_direction[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	current = strdup(full_name + strlen(prefix) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	if (!current)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	working = strtok(current, "_\0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	if (!working) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		free(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	w = working;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	r = working;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	while (*r != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		if (!isdigit(*r)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 			*w = *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 			w++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		r++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	*w = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	ret = asprintf(generic_name, "%s_%s", prefix, working);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	free(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	return (ret == -1) ? -ENOMEM : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  * iioutils_get_type() - find and process _type attribute data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  * @is_signed: output whether channel is signed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  * @bytes: output how many bytes the channel storage occupies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  * @bits_used: output number of valid bits of data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  * @shift: output amount of bits to shift right data before applying bit mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  * @mask: output a bit mask for the raw data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  * @be: output if data in big endian
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  * @device_dir: the IIO device directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  * @name: the channel name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  * @generic_name: the channel type name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  * Returns a value >= 0 on success, otherwise a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) int iioutils_get_type(unsigned *is_signed, unsigned *bytes, unsigned *bits_used,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		      unsigned *shift, uint64_t *mask, unsigned *be,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		      const char *device_dir, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		      const char *generic_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	FILE *sysfsfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	DIR *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	char *scan_el_dir, *builtname, *builtname_generic, *filename = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	char signchar, endianchar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	unsigned padint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	const struct dirent *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	ret = asprintf(&builtname, FORMAT_TYPE_FILE, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		goto error_free_scan_el_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	ret = asprintf(&builtname_generic, FORMAT_TYPE_FILE, generic_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		goto error_free_builtname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	dp = opendir(scan_el_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	if (!dp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		goto error_free_builtname_generic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	while (ent = readdir(dp), ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		if ((strcmp(builtname, ent->d_name) == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		    (strcmp(builtname_generic, ent->d_name) == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 			ret = asprintf(&filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 				       "%s/%s", scan_el_dir, ent->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 			if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 				ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 				goto error_closedir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 			sysfsfp = fopen(filename, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 			if (!sysfsfp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 				ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 				fprintf(stderr, "failed to open %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 					filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 				goto error_free_filename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 			ret = fscanf(sysfsfp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 				     "%ce:%c%u/%u>>%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 				     &endianchar,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 				     &signchar,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 				     bits_used,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 				     &padint, shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 			if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 				ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 				fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 					"failed to pass scan type description\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 				goto error_close_sysfsfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			} else if (ret != 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 				ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 				fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 					"scan type description didn't match\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 				goto error_close_sysfsfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 			*be = (endianchar == 'b');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			*bytes = padint / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 			if (*bits_used == 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 				*mask = ~(0ULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 				*mask = (1ULL << *bits_used) - 1ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 			*is_signed = (signchar == 's');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 			if (fclose(sysfsfp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 				ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 				fprintf(stderr, "Failed to close %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 					filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 				goto error_free_filename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 			sysfsfp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 			free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 			filename = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 			 * Avoid having a more generic entry overwriting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 			 * the settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			if (strcmp(builtname, ent->d_name) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) error_close_sysfsfp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	if (sysfsfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		if (fclose(sysfsfp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 			perror("iioutils_get_type(): Failed to close file");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) error_free_filename:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	if (filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) error_closedir:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	if (closedir(dp) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		perror("iioutils_get_type(): Failed to close directory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) error_free_builtname_generic:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	free(builtname_generic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) error_free_builtname:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	free(builtname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) error_free_scan_el_dir:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	free(scan_el_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)  * iioutils_get_param_float() - read a float value from a channel parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)  * @output: output the float value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)  * @param_name: the parameter name to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)  * @device_dir: the IIO device directory in sysfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)  * @name: the channel name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)  * @generic_name: the channel type name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)  * Returns a value >= 0 on success, otherwise a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) int iioutils_get_param_float(float *output, const char *param_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 			     const char *device_dir, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 			     const char *generic_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	FILE *sysfsfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	DIR *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	char *builtname, *builtname_generic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	char *filename = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	const struct dirent *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	ret = asprintf(&builtname, "%s_%s", name, param_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	ret = asprintf(&builtname_generic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		       "%s_%s", generic_name, param_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		goto error_free_builtname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	dp = opendir(device_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	if (!dp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		goto error_free_builtname_generic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	while (ent = readdir(dp), ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		if ((strcmp(builtname, ent->d_name) == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		    (strcmp(builtname_generic, ent->d_name) == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 			ret = asprintf(&filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 				       "%s/%s", device_dir, ent->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 			if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 				ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 				goto error_closedir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 			sysfsfp = fopen(filename, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 			if (!sysfsfp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 				ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 				goto error_free_filename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 			errno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 			if (fscanf(sysfsfp, "%f", output) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 				ret = errno ? -errno : -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) error_free_filename:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	if (filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) error_closedir:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	if (closedir(dp) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		perror("iioutils_get_param_float(): Failed to close directory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) error_free_builtname_generic:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	free(builtname_generic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) error_free_builtname:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	free(builtname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)  * bsort_channel_array_by_index() - sort the array in index order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)  * @ci_array: the iio_channel_info array to be sorted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)  * @cnt: the amount of array elements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) void bsort_channel_array_by_index(struct iio_channel_info *ci_array, int cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	struct iio_channel_info temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	int x, y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	for (x = 0; x < cnt; x++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		for (y = 0; y < (cnt - 1); y++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 			if (ci_array[y].index > ci_array[y + 1].index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 				temp = ci_array[y + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 				ci_array[y + 1] = ci_array[y];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 				ci_array[y] = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)  * build_channel_array() - function to figure out what channels are present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)  * @device_dir: the IIO device directory in sysfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)  * @ci_array: output the resulting array of iio_channel_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)  * @counter: output the amount of array elements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)  * Returns 0 on success, otherwise a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) int build_channel_array(const char *device_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 			struct iio_channel_info **ci_array, int *counter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	DIR *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	FILE *sysfsfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	int count = 0, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	struct iio_channel_info *current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	const struct dirent *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	char *scan_el_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	char *filename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	*counter = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	dp = opendir(scan_el_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	if (!dp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		goto error_free_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	while (ent = readdir(dp), ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 			   "_en") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 			ret = asprintf(&filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 				       "%s/%s", scan_el_dir, ent->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 			if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 				ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 				goto error_close_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 			sysfsfp = fopen(filename, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 			if (!sysfsfp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 				ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 				free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 				goto error_close_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 			errno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 			if (fscanf(sysfsfp, "%i", &ret) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 				ret = errno ? -errno : -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 				if (fclose(sysfsfp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 					perror("build_channel_array(): Failed to close file");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 				free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 				goto error_close_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 			if (ret == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 				(*counter)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 			if (fclose(sysfsfp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 				ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 				free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 				goto error_close_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 			free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	*ci_array = malloc(sizeof(**ci_array) * (*counter));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	if (!*ci_array) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		goto error_close_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	seekdir(dp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	while (ent = readdir(dp), ent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 		if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 			   "_en") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 			int current_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 			current = &(*ci_array)[count++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 			ret = asprintf(&filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 				       "%s/%s", scan_el_dir, ent->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 			if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 				ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 				/* decrement count to avoid freeing name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 				count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 				goto error_cleanup_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 			sysfsfp = fopen(filename, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 			if (!sysfsfp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 				ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 				free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 				count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 				goto error_cleanup_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 			errno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			if (fscanf(sysfsfp, "%i", &current_enabled) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 				ret = errno ? -errno : -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 				free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 				count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 				goto error_cleanup_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 			if (fclose(sysfsfp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 				ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 				free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 				count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 				goto error_cleanup_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 			if (!current_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 				free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 				count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 			current->scale = 1.0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 			current->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 			current->name = strndup(ent->d_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 						strlen(ent->d_name) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 						strlen("_en"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 			if (!current->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 				free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 				ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 				count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 				goto error_cleanup_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 			/* Get the generic and specific name elements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			ret = iioutils_break_up_name(current->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 						     &current->generic_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 			if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 				free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 				free(current->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 				count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 				goto error_cleanup_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 			ret = asprintf(&filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 				       "%s/%s_index",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 				       scan_el_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 				       current->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 			if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 				free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 				ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 				goto error_cleanup_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 			sysfsfp = fopen(filename, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 			if (!sysfsfp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 				ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 				fprintf(stderr, "failed to open %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 					filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 				free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 				goto error_cleanup_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 			errno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 			if (fscanf(sysfsfp, "%u", &current->index) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 				ret = errno ? -errno : -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 				if (fclose(sysfsfp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 					perror("build_channel_array(): Failed to close file");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 				free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 				goto error_cleanup_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 			if (fclose(sysfsfp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 				ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 				free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 				goto error_cleanup_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 			free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 			/* Find the scale */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 			ret = iioutils_get_param_float(&current->scale,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 						       "scale",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 						       device_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 						       current->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 						       current->generic_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 			if ((ret < 0) && (ret != -ENOENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 				goto error_cleanup_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 			ret = iioutils_get_param_float(&current->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 						       "offset",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 						       device_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 						       current->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 						       current->generic_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 			if ((ret < 0) && (ret != -ENOENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 				goto error_cleanup_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 			ret = iioutils_get_type(&current->is_signed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 						&current->bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 						&current->bits_used,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 						&current->shift,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 						&current->mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 						&current->be,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 						device_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 						current->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 						current->generic_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 				goto error_cleanup_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	if (closedir(dp) == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 		ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		goto error_cleanup_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	free(scan_el_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	/* reorder so that the array is in index order */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	bsort_channel_array_by_index(*ci_array, *counter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) error_cleanup_array:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	for (i = count - 1;  i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		free((*ci_array)[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		free((*ci_array)[i].generic_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	free(*ci_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	*ci_array = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	*counter = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) error_close_dir:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	if (dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		if (closedir(dp) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 			perror("build_channel_array(): Failed to close dir");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) error_free_name:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	free(scan_el_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static int calc_digits(int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	while (num != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		num /= 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)  * find_type_by_name() - function to match top level types by name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)  * @name: top level type instance name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)  * @type: the type of top level instance being searched
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)  * Returns the device number of a matched IIO device on success, otherwise a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)  * negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)  * Typical types this is used for are device and trigger.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) int find_type_by_name(const char *name, const char *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	const struct dirent *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	int number, numstrlen, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	FILE *namefp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	DIR *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	char thisname[IIO_MAX_NAME_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	char *filename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	dp = opendir(iio_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	if (!dp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 		fprintf(stderr, "No industrialio devices available\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	while (ent = readdir(dp), ent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 		if (strcmp(ent->d_name, ".") != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 		    strcmp(ent->d_name, "..") != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 		    strlen(ent->d_name) > strlen(type) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 		    strncmp(ent->d_name, type, strlen(type)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 			errno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 			ret = sscanf(ent->d_name + strlen(type), "%d", &number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 			if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 				ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 				fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 					"failed to read element number\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 				goto error_close_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 			} else if (ret != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 				ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 				fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 					"failed to match element number\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 				goto error_close_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 			numstrlen = calc_digits(number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 			/* verify the next character is not a colon */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 			if (strncmp(ent->d_name + strlen(type) + numstrlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 			    ":", 1) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 				filename = malloc(strlen(iio_dir) + strlen(type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 						  + numstrlen + 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 				if (!filename) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 					ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 					goto error_close_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 				ret = sprintf(filename, "%s%s%d/name", iio_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 					      type, number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 				if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 					free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 					goto error_close_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 				namefp = fopen(filename, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 				if (!namefp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 					free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 				free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 				errno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 				if (fscanf(namefp, "%s", thisname) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 					ret = errno ? -errno : -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 					goto error_close_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 				if (fclose(namefp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 					ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 					goto error_close_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 				if (strcmp(name, thisname) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 					if (closedir(dp) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 						return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 					return number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	if (closedir(dp) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 		return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) error_close_dir:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	if (closedir(dp) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 		perror("find_type_by_name(): Failed to close directory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) static int _write_sysfs_int(const char *filename, const char *basedir, int val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 			    int verify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	FILE *sysfsfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	int test;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	if (!temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	ret = sprintf(temp, "%s/%s", basedir, filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 		goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	sysfsfp = fopen(temp, "w");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	if (!sysfsfp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 		ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 		fprintf(stderr, "failed to open %s\n", temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 		goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	ret = fprintf(sysfsfp, "%d", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 		if (fclose(sysfsfp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 			perror("_write_sysfs_int(): Failed to close dir");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 		goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	if (fclose(sysfsfp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 		ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 		goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	if (verify) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 		sysfsfp = fopen(temp, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 		if (!sysfsfp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 			ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 			fprintf(stderr, "failed to open %s\n", temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 			goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 		if (fscanf(sysfsfp, "%d", &test) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 			ret = errno ? -errno : -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 			if (fclose(sysfsfp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 				perror("_write_sysfs_int(): Failed to close dir");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 			goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 		if (fclose(sysfsfp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 			ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 			goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 		if (test != val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 			fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 				"Possible failure in int write %d to %s/%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 				val, basedir, filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 			ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) error_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	free(temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)  * write_sysfs_int() - write an integer value to a sysfs file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)  * @filename: name of the file to write to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)  * @basedir: the sysfs directory in which the file is to be found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)  * @val: integer value to write to file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)  * Returns a value >= 0 on success, otherwise a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) int write_sysfs_int(const char *filename, const char *basedir, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	return _write_sysfs_int(filename, basedir, val, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)  * write_sysfs_int_and_verify() - write an integer value to a sysfs file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)  *				  and verify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)  * @filename: name of the file to write to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)  * @basedir: the sysfs directory in which the file is to be found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)  * @val: integer value to write to file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)  * Returns a value >= 0 on success, otherwise a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) int write_sysfs_int_and_verify(const char *filename, const char *basedir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 			       int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	return _write_sysfs_int(filename, basedir, val, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) static int _write_sysfs_string(const char *filename, const char *basedir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 			       const char *val, int verify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 	FILE  *sysfsfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 	if (!temp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 		fprintf(stderr, "Memory allocation failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 	ret = sprintf(temp, "%s/%s", basedir, filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 		goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	sysfsfp = fopen(temp, "w");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 	if (!sysfsfp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 		ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 		fprintf(stderr, "Could not open %s\n", temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 		goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 	ret = fprintf(sysfsfp, "%s", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 		if (fclose(sysfsfp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 			perror("_write_sysfs_string(): Failed to close dir");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 		goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 	if (fclose(sysfsfp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 		ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 		goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 	if (verify) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 		sysfsfp = fopen(temp, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 		if (!sysfsfp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 			ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 			fprintf(stderr, "Could not open file to verify\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 			goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 		if (fscanf(sysfsfp, "%s", temp) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 			ret = errno ? -errno : -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 			if (fclose(sysfsfp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 				perror("_write_sysfs_string(): Failed to close dir");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 			goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 		if (fclose(sysfsfp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 			ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 			goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 		if (strcmp(temp, val) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 			fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 				"Possible failure in string write of %s "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 				"Should be %s written to %s/%s\n", temp, val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 				basedir, filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 			ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) error_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 	free(temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)  * write_sysfs_string_and_verify() - string write, readback and verify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)  * @filename: name of file to write to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)  * @basedir: the sysfs directory in which the file is to be found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)  * @val: the string to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)  * Returns a value >= 0 on success, otherwise a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) int write_sysfs_string_and_verify(const char *filename, const char *basedir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 				  const char *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 	return _write_sysfs_string(filename, basedir, val, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)  * write_sysfs_string() - write string to a sysfs file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)  * @filename: name of file to write to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)  * @basedir: the sysfs directory in which the file is to be found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)  * @val: the string to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)  * Returns a value >= 0 on success, otherwise a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) int write_sysfs_string(const char *filename, const char *basedir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 		       const char *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 	return _write_sysfs_string(filename, basedir, val, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)  * read_sysfs_posint() - read an integer value from file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)  * @filename: name of file to read from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)  * @basedir: the sysfs directory in which the file is to be found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)  * Returns the read integer value >= 0 on success, otherwise a negative error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)  * code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) int read_sysfs_posint(const char *filename, const char *basedir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 	FILE  *sysfsfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 	char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 	if (!temp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 		fprintf(stderr, "Memory allocation failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 	ret = sprintf(temp, "%s/%s", basedir, filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 		goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 	sysfsfp = fopen(temp, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) 	if (!sysfsfp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) 		ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 		goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 	errno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 	if (fscanf(sysfsfp, "%d\n", &ret) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) 		ret = errno ? -errno : -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) 		if (fclose(sysfsfp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) 			perror("read_sysfs_posint(): Failed to close dir");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) 		goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) 	if (fclose(sysfsfp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) 		ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) error_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) 	free(temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)  * read_sysfs_float() - read a float value from file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)  * @filename: name of file to read from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)  * @basedir: the sysfs directory in which the file is to be found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)  * @val: output the read float value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)  * Returns a value >= 0 on success, otherwise a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) int read_sysfs_float(const char *filename, const char *basedir, float *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) 	FILE  *sysfsfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) 	char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) 	if (!temp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) 		fprintf(stderr, "Memory allocation failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 	ret = sprintf(temp, "%s/%s", basedir, filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) 		goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) 	sysfsfp = fopen(temp, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) 	if (!sysfsfp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) 		ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) 		goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) 	errno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) 	if (fscanf(sysfsfp, "%f\n", val) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) 		ret = errno ? -errno : -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) 		if (fclose(sysfsfp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) 			perror("read_sysfs_float(): Failed to close dir");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) 		goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) 	if (fclose(sysfsfp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) 		ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) error_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) 	free(temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)  * read_sysfs_string() - read a string from file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)  * @filename: name of file to read from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)  * @basedir: the sysfs directory in which the file is to be found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)  * @str: output the read string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)  * Returns a value >= 0 on success, otherwise a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) int read_sysfs_string(const char *filename, const char *basedir, char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) 	FILE  *sysfsfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) 	char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) 	if (!temp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) 		fprintf(stderr, "Memory allocation failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) 	ret = sprintf(temp, "%s/%s", basedir, filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) 		goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) 	sysfsfp = fopen(temp, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) 	if (!sysfsfp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) 		ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) 		goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) 	errno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) 	if (fscanf(sysfsfp, "%s\n", str) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) 		ret = errno ? -errno : -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) 		if (fclose(sysfsfp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) 			perror("read_sysfs_string(): Failed to close dir");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) 		goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) 	if (fclose(sysfsfp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) 		ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) error_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) 	free(temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }