Pratyush Mallick
/
testing
this is testing
app/noos_mbed/libraries/iio/iio.c@0:3afcd581558d, 2021-01-14 (annotated)
- Committer:
- pmallick
- Date:
- Thu Jan 14 18:54:16 2021 +0530
- Revision:
- 0:3afcd581558d
this is testing
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
pmallick | 0:3afcd581558d | 1 | /***************************************************************************//** |
pmallick | 0:3afcd581558d | 2 | * @file iio.c |
pmallick | 0:3afcd581558d | 3 | * @brief Implementation of iio. |
pmallick | 0:3afcd581558d | 4 | * This module implements read/write ops, required by libtinyiiod and further |
pmallick | 0:3afcd581558d | 5 | * calls show/store functions, corresponding to device/channel/attribute. |
pmallick | 0:3afcd581558d | 6 | * @author Cristian Pop (cristian.pop@analog.com) |
pmallick | 0:3afcd581558d | 7 | ******************************************************************************** |
pmallick | 0:3afcd581558d | 8 | * Copyright 2019, 2020(c) Analog Devices, Inc. |
pmallick | 0:3afcd581558d | 9 | * |
pmallick | 0:3afcd581558d | 10 | * All rights reserved. |
pmallick | 0:3afcd581558d | 11 | * |
pmallick | 0:3afcd581558d | 12 | * Redistribution and use in source and binary forms, with or without |
pmallick | 0:3afcd581558d | 13 | * modification, are permitted provided that the following conditions are met: |
pmallick | 0:3afcd581558d | 14 | * - Redistributions of source code must retain the above copyright |
pmallick | 0:3afcd581558d | 15 | * notice, this list of conditions and the following disclaimer. |
pmallick | 0:3afcd581558d | 16 | * - Redistributions in binary form must reproduce the above copyright |
pmallick | 0:3afcd581558d | 17 | * notice, this list of conditions and the following disclaimer in |
pmallick | 0:3afcd581558d | 18 | * the documentation and/or other materials provided with the |
pmallick | 0:3afcd581558d | 19 | * distribution. |
pmallick | 0:3afcd581558d | 20 | * - Neither the name of Analog Devices, Inc. nor the names of its |
pmallick | 0:3afcd581558d | 21 | * contributors may be used to endorse or promote products derived |
pmallick | 0:3afcd581558d | 22 | * from this software without specific prior written permission. |
pmallick | 0:3afcd581558d | 23 | * - The use of this software may or may not infringe the patent rights |
pmallick | 0:3afcd581558d | 24 | * of one or more patent holders. This license does not release you |
pmallick | 0:3afcd581558d | 25 | * from the requirement that you obtain separate licenses from these |
pmallick | 0:3afcd581558d | 26 | * patent holders to use this software. |
pmallick | 0:3afcd581558d | 27 | * - Use of the software either in source or binary form, must be run |
pmallick | 0:3afcd581558d | 28 | * on or directly connected to an Analog Devices Inc. component. |
pmallick | 0:3afcd581558d | 29 | * |
pmallick | 0:3afcd581558d | 30 | * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR |
pmallick | 0:3afcd581558d | 31 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, |
pmallick | 0:3afcd581558d | 32 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
pmallick | 0:3afcd581558d | 33 | * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, |
pmallick | 0:3afcd581558d | 34 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
pmallick | 0:3afcd581558d | 35 | * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR |
pmallick | 0:3afcd581558d | 36 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
pmallick | 0:3afcd581558d | 37 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
pmallick | 0:3afcd581558d | 38 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
pmallick | 0:3afcd581558d | 39 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
pmallick | 0:3afcd581558d | 40 | *******************************************************************************/ |
pmallick | 0:3afcd581558d | 41 | |
pmallick | 0:3afcd581558d | 42 | /******************************************************************************/ |
pmallick | 0:3afcd581558d | 43 | /***************************** Include Files **********************************/ |
pmallick | 0:3afcd581558d | 44 | /******************************************************************************/ |
pmallick | 0:3afcd581558d | 45 | |
pmallick | 0:3afcd581558d | 46 | #include "iio.h" |
pmallick | 0:3afcd581558d | 47 | #include "ctype.h" |
pmallick | 0:3afcd581558d | 48 | #include "tinyiiod.h" |
pmallick | 0:3afcd581558d | 49 | #include "util.h" |
pmallick | 0:3afcd581558d | 50 | #include "error.h" |
pmallick | 0:3afcd581558d | 51 | #include "errno.h" |
pmallick | 0:3afcd581558d | 52 | #include "compat.h" |
pmallick | 0:3afcd581558d | 53 | |
pmallick | 0:3afcd581558d | 54 | /******************************************************************************/ |
pmallick | 0:3afcd581558d | 55 | /*************************** Types Declarations *******************************/ |
pmallick | 0:3afcd581558d | 56 | /******************************************************************************/ |
pmallick | 0:3afcd581558d | 57 | |
pmallick | 0:3afcd581558d | 58 | /** |
pmallick | 0:3afcd581558d | 59 | * @struct iio_interfaces |
pmallick | 0:3afcd581558d | 60 | * @brief Structure containing all interfaces. |
pmallick | 0:3afcd581558d | 61 | */ |
pmallick | 0:3afcd581558d | 62 | struct iio_interfaces { |
pmallick | 0:3afcd581558d | 63 | /** List containing all interfaces */ |
pmallick | 0:3afcd581558d | 64 | struct iio_interface **interfaces; |
pmallick | 0:3afcd581558d | 65 | /** Number of Interfaces */ |
pmallick | 0:3afcd581558d | 66 | uint8_t num_interfaces; |
pmallick | 0:3afcd581558d | 67 | }; |
pmallick | 0:3afcd581558d | 68 | |
pmallick | 0:3afcd581558d | 69 | /** |
pmallick | 0:3afcd581558d | 70 | * @struct element_info |
pmallick | 0:3afcd581558d | 71 | * @brief Structure informations about a specific parameter. |
pmallick | 0:3afcd581558d | 72 | */ |
pmallick | 0:3afcd581558d | 73 | struct element_info { |
pmallick | 0:3afcd581558d | 74 | /** Device name */ |
pmallick | 0:3afcd581558d | 75 | const char *device_name; |
pmallick | 0:3afcd581558d | 76 | /** Channel name */ |
pmallick | 0:3afcd581558d | 77 | const char *channel_name; |
pmallick | 0:3afcd581558d | 78 | /** Attribute name */ |
pmallick | 0:3afcd581558d | 79 | const char *attribute_name; |
pmallick | 0:3afcd581558d | 80 | /** If set, is an output channel */ |
pmallick | 0:3afcd581558d | 81 | bool ch_out; |
pmallick | 0:3afcd581558d | 82 | }; |
pmallick | 0:3afcd581558d | 83 | |
pmallick | 0:3afcd581558d | 84 | /** |
pmallick | 0:3afcd581558d | 85 | * iio_read_attr(), iio_write_attr() functions, they need to know about iio_interfaces |
pmallick | 0:3afcd581558d | 86 | */ |
pmallick | 0:3afcd581558d | 87 | static struct iio_interfaces *iio_interfaces = NULL; |
pmallick | 0:3afcd581558d | 88 | |
pmallick | 0:3afcd581558d | 89 | /******************************************************************************/ |
pmallick | 0:3afcd581558d | 90 | /************************ Functions Definitions *******************************/ |
pmallick | 0:3afcd581558d | 91 | /******************************************************************************/ |
pmallick | 0:3afcd581558d | 92 | |
pmallick | 0:3afcd581558d | 93 | /** |
pmallick | 0:3afcd581558d | 94 | * @brief Get channel number. |
pmallick | 0:3afcd581558d | 95 | * @param ch - String containing channel name + channel number. |
pmallick | 0:3afcd581558d | 96 | * @return - Channel number. Ex: for "altvoltage0" return 0, for "voltage2" |
pmallick | 0:3afcd581558d | 97 | * return 2. |
pmallick | 0:3afcd581558d | 98 | */ |
pmallick | 0:3afcd581558d | 99 | static int32_t iio_get_channel_number(const char *ch) |
pmallick | 0:3afcd581558d | 100 | { |
pmallick | 0:3afcd581558d | 101 | char *p = (char*)ch; |
pmallick | 0:3afcd581558d | 102 | int32_t ch_num = FAILURE; |
pmallick | 0:3afcd581558d | 103 | |
pmallick | 0:3afcd581558d | 104 | while (*p) { |
pmallick | 0:3afcd581558d | 105 | if (isdigit(*p)) |
pmallick | 0:3afcd581558d | 106 | ch_num = strtol(p, &p, 10); |
pmallick | 0:3afcd581558d | 107 | else |
pmallick | 0:3afcd581558d | 108 | p++; |
pmallick | 0:3afcd581558d | 109 | } |
pmallick | 0:3afcd581558d | 110 | |
pmallick | 0:3afcd581558d | 111 | return ch_num; |
pmallick | 0:3afcd581558d | 112 | } |
pmallick | 0:3afcd581558d | 113 | |
pmallick | 0:3afcd581558d | 114 | /** |
pmallick | 0:3afcd581558d | 115 | * @brief Get channel ID from a list of channels. |
pmallick | 0:3afcd581558d | 116 | * @param channel - Channel name. |
pmallick | 0:3afcd581558d | 117 | * @param channels - List of channels. |
pmallick | 0:3afcd581558d | 118 | * @param ch_out - If "true" is output channel, if "false" is input channel. |
pmallick | 0:3afcd581558d | 119 | * @return Channel ID, or negative value if attribute is not found. |
pmallick | 0:3afcd581558d | 120 | */ |
pmallick | 0:3afcd581558d | 121 | static int16_t iio_get_channel_id(const char *channel, |
pmallick | 0:3afcd581558d | 122 | struct iio_channel **channels, bool ch_out) |
pmallick | 0:3afcd581558d | 123 | { |
pmallick | 0:3afcd581558d | 124 | int16_t i = 0; |
pmallick | 0:3afcd581558d | 125 | |
pmallick | 0:3afcd581558d | 126 | if (!(*channels)) |
pmallick | 0:3afcd581558d | 127 | return -EINVAL; |
pmallick | 0:3afcd581558d | 128 | |
pmallick | 0:3afcd581558d | 129 | while (channels[i]) { |
pmallick | 0:3afcd581558d | 130 | if (!strcmp(channel, channels[i]->name) && (channels[i]->ch_out == ch_out)) |
pmallick | 0:3afcd581558d | 131 | return i; |
pmallick | 0:3afcd581558d | 132 | i++; |
pmallick | 0:3afcd581558d | 133 | } |
pmallick | 0:3afcd581558d | 134 | |
pmallick | 0:3afcd581558d | 135 | return -ENOENT; |
pmallick | 0:3afcd581558d | 136 | } |
pmallick | 0:3afcd581558d | 137 | |
pmallick | 0:3afcd581558d | 138 | /** |
pmallick | 0:3afcd581558d | 139 | * @brief Get attribute ID from a list of attributes. |
pmallick | 0:3afcd581558d | 140 | * @param attr - Attribute name. |
pmallick | 0:3afcd581558d | 141 | * @param attributes - List of attributes. |
pmallick | 0:3afcd581558d | 142 | * @return - Attribute ID, or negative value if attribute is not found. |
pmallick | 0:3afcd581558d | 143 | */ |
pmallick | 0:3afcd581558d | 144 | static int16_t iio_get_attribute_id(const char *attr, |
pmallick | 0:3afcd581558d | 145 | struct iio_attribute **attributes) |
pmallick | 0:3afcd581558d | 146 | { |
pmallick | 0:3afcd581558d | 147 | int16_t i = 0; |
pmallick | 0:3afcd581558d | 148 | |
pmallick | 0:3afcd581558d | 149 | if (!(*attributes)) |
pmallick | 0:3afcd581558d | 150 | return -EINVAL; |
pmallick | 0:3afcd581558d | 151 | |
pmallick | 0:3afcd581558d | 152 | while (attributes[i]) { |
pmallick | 0:3afcd581558d | 153 | if (!strcmp(attr, attributes[i]->name)) |
pmallick | 0:3afcd581558d | 154 | return i; |
pmallick | 0:3afcd581558d | 155 | i++; |
pmallick | 0:3afcd581558d | 156 | } |
pmallick | 0:3afcd581558d | 157 | |
pmallick | 0:3afcd581558d | 158 | return -ENOENT; |
pmallick | 0:3afcd581558d | 159 | } |
pmallick | 0:3afcd581558d | 160 | |
pmallick | 0:3afcd581558d | 161 | /** |
pmallick | 0:3afcd581558d | 162 | * @brief Find interface with "device_name". |
pmallick | 0:3afcd581558d | 163 | * @param device_name - Device name. |
pmallick | 0:3afcd581558d | 164 | * @param iio_interfaces - List of interfaces. |
pmallick | 0:3afcd581558d | 165 | * @return Interface pointer if interface is found, NULL otherwise. |
pmallick | 0:3afcd581558d | 166 | */ |
pmallick | 0:3afcd581558d | 167 | static struct iio_interface *iio_get_interface(const char *device_name, |
pmallick | 0:3afcd581558d | 168 | struct iio_interfaces *iio_interfaces) |
pmallick | 0:3afcd581558d | 169 | { |
pmallick | 0:3afcd581558d | 170 | int16_t i; |
pmallick | 0:3afcd581558d | 171 | |
pmallick | 0:3afcd581558d | 172 | if (!iio_interfaces) |
pmallick | 0:3afcd581558d | 173 | return NULL; |
pmallick | 0:3afcd581558d | 174 | |
pmallick | 0:3afcd581558d | 175 | for (i = 0; i < iio_interfaces->num_interfaces; i++) { |
pmallick | 0:3afcd581558d | 176 | if (!strcmp(device_name, iio_interfaces->interfaces[i]->name)) |
pmallick | 0:3afcd581558d | 177 | return iio_interfaces->interfaces[i]; |
pmallick | 0:3afcd581558d | 178 | } |
pmallick | 0:3afcd581558d | 179 | |
pmallick | 0:3afcd581558d | 180 | return NULL; |
pmallick | 0:3afcd581558d | 181 | } |
pmallick | 0:3afcd581558d | 182 | |
pmallick | 0:3afcd581558d | 183 | /** |
pmallick | 0:3afcd581558d | 184 | * @brief Read all attributes from an attribute list. |
pmallick | 0:3afcd581558d | 185 | * @param device - Physical instance of a device. |
pmallick | 0:3afcd581558d | 186 | * @param buf - Buffer where values are read. |
pmallick | 0:3afcd581558d | 187 | * @param len - Maximum length of value to be stored in buf. |
pmallick | 0:3afcd581558d | 188 | * @param channel - Channel properties. |
pmallick | 0:3afcd581558d | 189 | * @param attributes - List of attributes to be read. |
pmallick | 0:3afcd581558d | 190 | * @return Number of bytes read or negative value in case of error. |
pmallick | 0:3afcd581558d | 191 | */ |
pmallick | 0:3afcd581558d | 192 | static ssize_t iio_read_all_attr(void *device, char *buf, size_t len, |
pmallick | 0:3afcd581558d | 193 | const struct iio_ch_info *channel, struct iio_attribute **attributes) |
pmallick | 0:3afcd581558d | 194 | { |
pmallick | 0:3afcd581558d | 195 | int16_t i = 0, j = 0; |
pmallick | 0:3afcd581558d | 196 | char local_buf[256]; |
pmallick | 0:3afcd581558d | 197 | ssize_t attr_length; |
pmallick | 0:3afcd581558d | 198 | uint32_t *pattr_length; |
pmallick | 0:3afcd581558d | 199 | |
pmallick | 0:3afcd581558d | 200 | if (!attributes) |
pmallick | 0:3afcd581558d | 201 | return FAILURE; |
pmallick | 0:3afcd581558d | 202 | |
pmallick | 0:3afcd581558d | 203 | if (!buf) |
pmallick | 0:3afcd581558d | 204 | return FAILURE; |
pmallick | 0:3afcd581558d | 205 | |
pmallick | 0:3afcd581558d | 206 | while (attributes[i]) { |
pmallick | 0:3afcd581558d | 207 | attr_length = attributes[i]->show(device, local_buf, len, channel); |
pmallick | 0:3afcd581558d | 208 | pattr_length = (uint32_t *)(buf + j); |
pmallick | 0:3afcd581558d | 209 | *pattr_length = bswap_constant_32(attr_length); |
pmallick | 0:3afcd581558d | 210 | j += 4; |
pmallick | 0:3afcd581558d | 211 | if (attr_length >= 0) { |
pmallick | 0:3afcd581558d | 212 | sprintf(buf + j, "%s", local_buf); |
pmallick | 0:3afcd581558d | 213 | if (attr_length & 0x3) /* multiple of 4 */ |
pmallick | 0:3afcd581558d | 214 | attr_length = ((attr_length >> 2) + 1) << 2; |
pmallick | 0:3afcd581558d | 215 | j += attr_length; |
pmallick | 0:3afcd581558d | 216 | } |
pmallick | 0:3afcd581558d | 217 | i++; |
pmallick | 0:3afcd581558d | 218 | } |
pmallick | 0:3afcd581558d | 219 | |
pmallick | 0:3afcd581558d | 220 | return j; |
pmallick | 0:3afcd581558d | 221 | } |
pmallick | 0:3afcd581558d | 222 | |
pmallick | 0:3afcd581558d | 223 | /** |
pmallick | 0:3afcd581558d | 224 | * @brief Write all attributes from an attribute list. |
pmallick | 0:3afcd581558d | 225 | * @param device - Physical instance of a device. |
pmallick | 0:3afcd581558d | 226 | * @param buf - Values to be written. |
pmallick | 0:3afcd581558d | 227 | * @param len - Length of buf. |
pmallick | 0:3afcd581558d | 228 | * @param channel - Channel properties. |
pmallick | 0:3afcd581558d | 229 | * @param attributes - List of attributes to be written. |
pmallick | 0:3afcd581558d | 230 | * @return Number of written bytes or negative value in case of error. |
pmallick | 0:3afcd581558d | 231 | */ |
pmallick | 0:3afcd581558d | 232 | static ssize_t iio_write_all_attr(void *device, char *buf, size_t len, |
pmallick | 0:3afcd581558d | 233 | const struct iio_ch_info *channel, struct iio_attribute **attributes) |
pmallick | 0:3afcd581558d | 234 | { |
pmallick | 0:3afcd581558d | 235 | int16_t i = 0, j = 0; |
pmallick | 0:3afcd581558d | 236 | int16_t attr_length; |
pmallick | 0:3afcd581558d | 237 | |
pmallick | 0:3afcd581558d | 238 | if (!attributes) |
pmallick | 0:3afcd581558d | 239 | return FAILURE; |
pmallick | 0:3afcd581558d | 240 | |
pmallick | 0:3afcd581558d | 241 | if (!buf) |
pmallick | 0:3afcd581558d | 242 | return FAILURE; |
pmallick | 0:3afcd581558d | 243 | |
pmallick | 0:3afcd581558d | 244 | while (attributes[i]) { |
pmallick | 0:3afcd581558d | 245 | attr_length = bswap_constant_32((uint32_t)(buf + j)); |
pmallick | 0:3afcd581558d | 246 | j += 4; |
pmallick | 0:3afcd581558d | 247 | attributes[i]->store(device, (buf + j), attr_length, channel); |
pmallick | 0:3afcd581558d | 248 | j += attr_length; |
pmallick | 0:3afcd581558d | 249 | if (j & 0x3) |
pmallick | 0:3afcd581558d | 250 | j = ((j >> 2) + 1) << 2; |
pmallick | 0:3afcd581558d | 251 | i++; |
pmallick | 0:3afcd581558d | 252 | } |
pmallick | 0:3afcd581558d | 253 | |
pmallick | 0:3afcd581558d | 254 | return len; |
pmallick | 0:3afcd581558d | 255 | } |
pmallick | 0:3afcd581558d | 256 | |
pmallick | 0:3afcd581558d | 257 | /** |
pmallick | 0:3afcd581558d | 258 | * @brief Read/write channel attribute. |
pmallick | 0:3afcd581558d | 259 | * @param el_info - Structure describing element to be written. |
pmallick | 0:3afcd581558d | 260 | * @param buf - Read/write value. |
pmallick | 0:3afcd581558d | 261 | * @param len - Length of data in "buf" parameter. |
pmallick | 0:3afcd581558d | 262 | * @param channel - Structure describing channel attributes. |
pmallick | 0:3afcd581558d | 263 | * @param is_write -If it has value "1", writes attribute, otherwise reads |
pmallick | 0:3afcd581558d | 264 | * attribute. |
pmallick | 0:3afcd581558d | 265 | * @return Length of chars written/read or negative value in case of error. |
pmallick | 0:3afcd581558d | 266 | */ |
pmallick | 0:3afcd581558d | 267 | static ssize_t iio_rd_wr_channel_attribute(struct element_info *el_info, |
pmallick | 0:3afcd581558d | 268 | char *buf, size_t len, |
pmallick | 0:3afcd581558d | 269 | struct iio_channel *channel, bool is_write) |
pmallick | 0:3afcd581558d | 270 | { |
pmallick | 0:3afcd581558d | 271 | int16_t attribute_id; |
pmallick | 0:3afcd581558d | 272 | struct iio_interface *iface = iio_get_interface(el_info->device_name, |
pmallick | 0:3afcd581558d | 273 | iio_interfaces); |
pmallick | 0:3afcd581558d | 274 | const struct iio_ch_info channel_info = { |
pmallick | 0:3afcd581558d | 275 | iio_get_channel_number(el_info->channel_name), |
pmallick | 0:3afcd581558d | 276 | el_info->ch_out |
pmallick | 0:3afcd581558d | 277 | }; |
pmallick | 0:3afcd581558d | 278 | |
pmallick | 0:3afcd581558d | 279 | if (!strcmp(el_info->attribute_name, "")) { |
pmallick | 0:3afcd581558d | 280 | /* read / write all channel attributes */ |
pmallick | 0:3afcd581558d | 281 | if (is_write) |
pmallick | 0:3afcd581558d | 282 | return iio_write_all_attr(iface->dev_instance, buf, len, &channel_info, |
pmallick | 0:3afcd581558d | 283 | channel->attributes); |
pmallick | 0:3afcd581558d | 284 | else |
pmallick | 0:3afcd581558d | 285 | return iio_read_all_attr(iface->dev_instance, buf, len, &channel_info, |
pmallick | 0:3afcd581558d | 286 | channel->attributes); |
pmallick | 0:3afcd581558d | 287 | } else { |
pmallick | 0:3afcd581558d | 288 | /* read / write single channel attribute, if attribute found */ |
pmallick | 0:3afcd581558d | 289 | attribute_id = iio_get_attribute_id(el_info->attribute_name, |
pmallick | 0:3afcd581558d | 290 | channel->attributes); |
pmallick | 0:3afcd581558d | 291 | if (attribute_id >= 0) { |
pmallick | 0:3afcd581558d | 292 | if (is_write) |
pmallick | 0:3afcd581558d | 293 | return channel->attributes[attribute_id]->store(iface->dev_instance, |
pmallick | 0:3afcd581558d | 294 | (char*)buf, len, &channel_info); |
pmallick | 0:3afcd581558d | 295 | else |
pmallick | 0:3afcd581558d | 296 | return channel->attributes[attribute_id]->show(iface->dev_instance, (char*)buf, |
pmallick | 0:3afcd581558d | 297 | len, &channel_info); |
pmallick | 0:3afcd581558d | 298 | } |
pmallick | 0:3afcd581558d | 299 | } |
pmallick | 0:3afcd581558d | 300 | |
pmallick | 0:3afcd581558d | 301 | return -ENOENT; |
pmallick | 0:3afcd581558d | 302 | } |
pmallick | 0:3afcd581558d | 303 | |
pmallick | 0:3afcd581558d | 304 | /** |
pmallick | 0:3afcd581558d | 305 | * @brief Read/write attribute. |
pmallick | 0:3afcd581558d | 306 | * @param el_info - Structure describing element to be written. |
pmallick | 0:3afcd581558d | 307 | * @param buf - Read/write value. |
pmallick | 0:3afcd581558d | 308 | * @param len - Length of data in "buf" parameter. |
pmallick | 0:3afcd581558d | 309 | * @param iio_device - Physical instance of a device. |
pmallick | 0:3afcd581558d | 310 | * @param is_write -If it has value "1", writes attribute, otherwise reads |
pmallick | 0:3afcd581558d | 311 | * attribute. |
pmallick | 0:3afcd581558d | 312 | * @return Length of chars written/read or negative value in case of error. |
pmallick | 0:3afcd581558d | 313 | */ |
pmallick | 0:3afcd581558d | 314 | static ssize_t iio_rd_wr_attribute(struct element_info *el_info, char *buf, |
pmallick | 0:3afcd581558d | 315 | size_t len, |
pmallick | 0:3afcd581558d | 316 | struct iio_device *iio_device, bool is_write) |
pmallick | 0:3afcd581558d | 317 | { |
pmallick | 0:3afcd581558d | 318 | int16_t channel_id; |
pmallick | 0:3afcd581558d | 319 | int16_t attribute_id; |
pmallick | 0:3afcd581558d | 320 | struct iio_interface *iface; |
pmallick | 0:3afcd581558d | 321 | |
pmallick | 0:3afcd581558d | 322 | if (!iio_device) |
pmallick | 0:3afcd581558d | 323 | return -ENOENT; |
pmallick | 0:3afcd581558d | 324 | |
pmallick | 0:3afcd581558d | 325 | if (!strcmp(el_info->channel_name, "")) { |
pmallick | 0:3afcd581558d | 326 | /* it is attribute of a device */ |
pmallick | 0:3afcd581558d | 327 | iface = iio_get_interface(el_info->device_name, iio_interfaces); |
pmallick | 0:3afcd581558d | 328 | |
pmallick | 0:3afcd581558d | 329 | if (!strcmp(el_info->attribute_name, "")) { |
pmallick | 0:3afcd581558d | 330 | /* read / write all device attributes */ |
pmallick | 0:3afcd581558d | 331 | if (is_write) |
pmallick | 0:3afcd581558d | 332 | return iio_write_all_attr(iface->dev_instance, buf, len, NULL, |
pmallick | 0:3afcd581558d | 333 | iio_device->attributes); |
pmallick | 0:3afcd581558d | 334 | else |
pmallick | 0:3afcd581558d | 335 | return iio_read_all_attr(iface->dev_instance, buf, len, NULL, |
pmallick | 0:3afcd581558d | 336 | iio_device->attributes); |
pmallick | 0:3afcd581558d | 337 | } else { |
pmallick | 0:3afcd581558d | 338 | /* read / write single device attribute, if attribute found */ |
pmallick | 0:3afcd581558d | 339 | attribute_id = iio_get_attribute_id(el_info->attribute_name, |
pmallick | 0:3afcd581558d | 340 | iio_device->attributes); |
pmallick | 0:3afcd581558d | 341 | if (attribute_id < 0) |
pmallick | 0:3afcd581558d | 342 | return -ENOENT; |
pmallick | 0:3afcd581558d | 343 | if (is_write) |
pmallick | 0:3afcd581558d | 344 | return iio_device->attributes[attribute_id]->store(iface->dev_instance, |
pmallick | 0:3afcd581558d | 345 | (char*)buf, len, NULL); |
pmallick | 0:3afcd581558d | 346 | else |
pmallick | 0:3afcd581558d | 347 | return iio_device->attributes[attribute_id]->show(iface->dev_instance, |
pmallick | 0:3afcd581558d | 348 | (char*)buf, len, NULL); |
pmallick | 0:3afcd581558d | 349 | } |
pmallick | 0:3afcd581558d | 350 | } else { |
pmallick | 0:3afcd581558d | 351 | /* it is attribute of a channel */ |
pmallick | 0:3afcd581558d | 352 | channel_id = iio_get_channel_id(el_info->channel_name, iio_device->channels, |
pmallick | 0:3afcd581558d | 353 | el_info->ch_out); |
pmallick | 0:3afcd581558d | 354 | return iio_rd_wr_channel_attribute(el_info, buf, len, |
pmallick | 0:3afcd581558d | 355 | iio_device->channels[channel_id], is_write); |
pmallick | 0:3afcd581558d | 356 | } |
pmallick | 0:3afcd581558d | 357 | |
pmallick | 0:3afcd581558d | 358 | return -ENOENT; |
pmallick | 0:3afcd581558d | 359 | } |
pmallick | 0:3afcd581558d | 360 | |
pmallick | 0:3afcd581558d | 361 | /** |
pmallick | 0:3afcd581558d | 362 | * @brief Check if device is supported. |
pmallick | 0:3afcd581558d | 363 | * @param device - Device name. |
pmallick | 0:3afcd581558d | 364 | * @return TRUE if device is supported, FALSE otherwise. |
pmallick | 0:3afcd581558d | 365 | */ |
pmallick | 0:3afcd581558d | 366 | static bool iio_supported_dev(const char *device) |
pmallick | 0:3afcd581558d | 367 | { |
pmallick | 0:3afcd581558d | 368 | return (NULL != iio_get_interface(device, iio_interfaces)); |
pmallick | 0:3afcd581558d | 369 | } |
pmallick | 0:3afcd581558d | 370 | |
pmallick | 0:3afcd581558d | 371 | /** |
pmallick | 0:3afcd581558d | 372 | * @brief Read global attribute of a device. |
pmallick | 0:3afcd581558d | 373 | * @param device - String containing device name. |
pmallick | 0:3afcd581558d | 374 | * @param attr - String containing attribute name. |
pmallick | 0:3afcd581558d | 375 | * @param buf - Buffer where value is read. |
pmallick | 0:3afcd581558d | 376 | * @param len - Maximum length of value to be stored in buf. |
pmallick | 0:3afcd581558d | 377 | * @param debug - Read raw value if set. |
pmallick | 0:3afcd581558d | 378 | * @return Number of bytes read. |
pmallick | 0:3afcd581558d | 379 | */ |
pmallick | 0:3afcd581558d | 380 | static ssize_t iio_read_attr(const char *device, const char *attr, char *buf, |
pmallick | 0:3afcd581558d | 381 | size_t len, bool debug) |
pmallick | 0:3afcd581558d | 382 | { |
pmallick | 0:3afcd581558d | 383 | struct iio_interface *iio_device; |
pmallick | 0:3afcd581558d | 384 | struct element_info el_info; |
pmallick | 0:3afcd581558d | 385 | |
pmallick | 0:3afcd581558d | 386 | if (!iio_supported_dev(device)) |
pmallick | 0:3afcd581558d | 387 | return FAILURE; |
pmallick | 0:3afcd581558d | 388 | |
pmallick | 0:3afcd581558d | 389 | el_info.device_name = device; |
pmallick | 0:3afcd581558d | 390 | el_info.channel_name = ""; /* there is no channel here */ |
pmallick | 0:3afcd581558d | 391 | el_info.attribute_name = attr; |
pmallick | 0:3afcd581558d | 392 | |
pmallick | 0:3afcd581558d | 393 | iio_device = iio_get_interface(device, iio_interfaces); |
pmallick | 0:3afcd581558d | 394 | if (!iio_device) |
pmallick | 0:3afcd581558d | 395 | return FAILURE; |
pmallick | 0:3afcd581558d | 396 | |
pmallick | 0:3afcd581558d | 397 | return iio_rd_wr_attribute(&el_info, buf, len, iio_device->iio, 0); |
pmallick | 0:3afcd581558d | 398 | } |
pmallick | 0:3afcd581558d | 399 | |
pmallick | 0:3afcd581558d | 400 | /** |
pmallick | 0:3afcd581558d | 401 | * @brief Write global attribute of a device. |
pmallick | 0:3afcd581558d | 402 | * @param device - String containing device name. |
pmallick | 0:3afcd581558d | 403 | * @param attr - String containing attribute name. |
pmallick | 0:3afcd581558d | 404 | * @param buf - Value to be written. |
pmallick | 0:3afcd581558d | 405 | * @param len - Length of data. |
pmallick | 0:3afcd581558d | 406 | * @param debug - Write raw value if set. |
pmallick | 0:3afcd581558d | 407 | * @return Number of written bytes. |
pmallick | 0:3afcd581558d | 408 | */ |
pmallick | 0:3afcd581558d | 409 | static ssize_t iio_write_attr(const char *device, const char *attr, |
pmallick | 0:3afcd581558d | 410 | const char *buf, |
pmallick | 0:3afcd581558d | 411 | size_t len, bool debug) |
pmallick | 0:3afcd581558d | 412 | { |
pmallick | 0:3afcd581558d | 413 | struct element_info el_info; |
pmallick | 0:3afcd581558d | 414 | struct iio_interface *iio_interface; |
pmallick | 0:3afcd581558d | 415 | |
pmallick | 0:3afcd581558d | 416 | if (!iio_supported_dev(device)) |
pmallick | 0:3afcd581558d | 417 | return -ENODEV; |
pmallick | 0:3afcd581558d | 418 | |
pmallick | 0:3afcd581558d | 419 | el_info.device_name = device; |
pmallick | 0:3afcd581558d | 420 | el_info.channel_name = ""; /* there is no channel here */ |
pmallick | 0:3afcd581558d | 421 | el_info.attribute_name = attr; |
pmallick | 0:3afcd581558d | 422 | |
pmallick | 0:3afcd581558d | 423 | iio_interface = iio_get_interface(device, iio_interfaces); |
pmallick | 0:3afcd581558d | 424 | if (!iio_interface) |
pmallick | 0:3afcd581558d | 425 | return FAILURE; |
pmallick | 0:3afcd581558d | 426 | |
pmallick | 0:3afcd581558d | 427 | return iio_rd_wr_attribute(&el_info, (char*)buf, len, iio_interface->iio, 1); |
pmallick | 0:3afcd581558d | 428 | } |
pmallick | 0:3afcd581558d | 429 | |
pmallick | 0:3afcd581558d | 430 | /** |
pmallick | 0:3afcd581558d | 431 | * @brief Read channel attribute. |
pmallick | 0:3afcd581558d | 432 | * @param device - String containing device name. |
pmallick | 0:3afcd581558d | 433 | * @param channel - String containing channel name. |
pmallick | 0:3afcd581558d | 434 | * @param ch_out -Channel type input/output. |
pmallick | 0:3afcd581558d | 435 | * @param attr - String containing attribute name. |
pmallick | 0:3afcd581558d | 436 | * @param buf - Buffer where value is stored. |
pmallick | 0:3afcd581558d | 437 | * @param len - Maximum length of value to be stored in buf. |
pmallick | 0:3afcd581558d | 438 | * @return - Number of bytes read. |
pmallick | 0:3afcd581558d | 439 | */ |
pmallick | 0:3afcd581558d | 440 | static ssize_t iio_ch_read_attr(const char *device, const char *channel, |
pmallick | 0:3afcd581558d | 441 | bool ch_out, const char *attr, char *buf, size_t len) |
pmallick | 0:3afcd581558d | 442 | { |
pmallick | 0:3afcd581558d | 443 | struct element_info el_info; |
pmallick | 0:3afcd581558d | 444 | struct iio_interface *iio_interface; |
pmallick | 0:3afcd581558d | 445 | |
pmallick | 0:3afcd581558d | 446 | if (!iio_supported_dev(device)) |
pmallick | 0:3afcd581558d | 447 | return FAILURE; |
pmallick | 0:3afcd581558d | 448 | |
pmallick | 0:3afcd581558d | 449 | el_info.device_name = device; |
pmallick | 0:3afcd581558d | 450 | el_info.channel_name = channel; |
pmallick | 0:3afcd581558d | 451 | el_info.attribute_name = attr; |
pmallick | 0:3afcd581558d | 452 | el_info.ch_out = ch_out; |
pmallick | 0:3afcd581558d | 453 | |
pmallick | 0:3afcd581558d | 454 | iio_interface = iio_get_interface(device, iio_interfaces); |
pmallick | 0:3afcd581558d | 455 | if (!device) |
pmallick | 0:3afcd581558d | 456 | return FAILURE; |
pmallick | 0:3afcd581558d | 457 | |
pmallick | 0:3afcd581558d | 458 | return iio_rd_wr_attribute(&el_info, buf, len, iio_interface->iio, 0); |
pmallick | 0:3afcd581558d | 459 | } |
pmallick | 0:3afcd581558d | 460 | |
pmallick | 0:3afcd581558d | 461 | /** |
pmallick | 0:3afcd581558d | 462 | * @brief Write channel attribute. |
pmallick | 0:3afcd581558d | 463 | * @param device - String containing device name. |
pmallick | 0:3afcd581558d | 464 | * @param channel - String containing channel name. |
pmallick | 0:3afcd581558d | 465 | * @param ch_out - Channel type input/output. |
pmallick | 0:3afcd581558d | 466 | * @param attr - String containing attribute name. |
pmallick | 0:3afcd581558d | 467 | * @param buf - Value to be written. |
pmallick | 0:3afcd581558d | 468 | * @param len - Length of data in "buf" parameter. |
pmallick | 0:3afcd581558d | 469 | * @return Number of written bytes. |
pmallick | 0:3afcd581558d | 470 | */ |
pmallick | 0:3afcd581558d | 471 | static ssize_t iio_ch_write_attr(const char *device, const char *channel, |
pmallick | 0:3afcd581558d | 472 | bool ch_out, const char *attr, const char *buf, size_t len) |
pmallick | 0:3afcd581558d | 473 | { |
pmallick | 0:3afcd581558d | 474 | struct element_info el_info; |
pmallick | 0:3afcd581558d | 475 | struct iio_interface *iio_interface; |
pmallick | 0:3afcd581558d | 476 | |
pmallick | 0:3afcd581558d | 477 | if (!iio_supported_dev(device)) |
pmallick | 0:3afcd581558d | 478 | return -ENODEV; |
pmallick | 0:3afcd581558d | 479 | |
pmallick | 0:3afcd581558d | 480 | el_info.device_name = device; |
pmallick | 0:3afcd581558d | 481 | el_info.channel_name = channel; |
pmallick | 0:3afcd581558d | 482 | el_info.attribute_name = attr; |
pmallick | 0:3afcd581558d | 483 | el_info.ch_out = ch_out; |
pmallick | 0:3afcd581558d | 484 | iio_interface = iio_get_interface(device, iio_interfaces); |
pmallick | 0:3afcd581558d | 485 | |
pmallick | 0:3afcd581558d | 486 | if (!iio_interface) |
pmallick | 0:3afcd581558d | 487 | return -ENOENT; |
pmallick | 0:3afcd581558d | 488 | |
pmallick | 0:3afcd581558d | 489 | return iio_rd_wr_attribute(&el_info, (char*)buf, len, iio_interface->iio, 1); |
pmallick | 0:3afcd581558d | 490 | } |
pmallick | 0:3afcd581558d | 491 | |
pmallick | 0:3afcd581558d | 492 | /** |
pmallick | 0:3afcd581558d | 493 | * @brief Open device. |
pmallick | 0:3afcd581558d | 494 | * @param device - String containing device name. |
pmallick | 0:3afcd581558d | 495 | * @param sample_size - Sample size. |
pmallick | 0:3afcd581558d | 496 | * @param mask - Channels to be opened. |
pmallick | 0:3afcd581558d | 497 | * @return SUCCESS, negative value in case of failure. |
pmallick | 0:3afcd581558d | 498 | */ |
pmallick | 0:3afcd581558d | 499 | static int32_t iio_open_dev(const char *device, size_t sample_size, |
pmallick | 0:3afcd581558d | 500 | uint32_t mask) |
pmallick | 0:3afcd581558d | 501 | { |
pmallick | 0:3afcd581558d | 502 | struct iio_interface *iface; |
pmallick | 0:3afcd581558d | 503 | uint32_t ch_mask; |
pmallick | 0:3afcd581558d | 504 | |
pmallick | 0:3afcd581558d | 505 | if (!iio_supported_dev(device)) |
pmallick | 0:3afcd581558d | 506 | return -ENODEV; |
pmallick | 0:3afcd581558d | 507 | |
pmallick | 0:3afcd581558d | 508 | iface = iio_get_interface(device, iio_interfaces); |
pmallick | 0:3afcd581558d | 509 | ch_mask = 0xFFFFFFFF >> (32 - iface->iio->num_ch); |
pmallick | 0:3afcd581558d | 510 | |
pmallick | 0:3afcd581558d | 511 | if (mask & ~ch_mask) |
pmallick | 0:3afcd581558d | 512 | return -ENOENT; |
pmallick | 0:3afcd581558d | 513 | |
pmallick | 0:3afcd581558d | 514 | iface->ch_mask = mask; |
pmallick | 0:3afcd581558d | 515 | |
pmallick | 0:3afcd581558d | 516 | return SUCCESS; |
pmallick | 0:3afcd581558d | 517 | } |
pmallick | 0:3afcd581558d | 518 | |
pmallick | 0:3afcd581558d | 519 | /** |
pmallick | 0:3afcd581558d | 520 | * @brief Close device. |
pmallick | 0:3afcd581558d | 521 | * @param device - String containing device name. |
pmallick | 0:3afcd581558d | 522 | * @return SUCCESS, negative value in case of failure. |
pmallick | 0:3afcd581558d | 523 | */ |
pmallick | 0:3afcd581558d | 524 | static int32_t iio_close_dev(const char *device) |
pmallick | 0:3afcd581558d | 525 | { |
pmallick | 0:3afcd581558d | 526 | struct iio_interface *iface; |
pmallick | 0:3afcd581558d | 527 | |
pmallick | 0:3afcd581558d | 528 | if (!iio_supported_dev(device)) |
pmallick | 0:3afcd581558d | 529 | return FAILURE; |
pmallick | 0:3afcd581558d | 530 | iface = iio_get_interface(device, iio_interfaces); |
pmallick | 0:3afcd581558d | 531 | iface->ch_mask = 0; |
pmallick | 0:3afcd581558d | 532 | |
pmallick | 0:3afcd581558d | 533 | return SUCCESS; |
pmallick | 0:3afcd581558d | 534 | } |
pmallick | 0:3afcd581558d | 535 | |
pmallick | 0:3afcd581558d | 536 | /** |
pmallick | 0:3afcd581558d | 537 | * @brief Get device mask, this specifies the channels that are used. |
pmallick | 0:3afcd581558d | 538 | * @param device - String containing device name. |
pmallick | 0:3afcd581558d | 539 | * @param mask - Channels that are opened. |
pmallick | 0:3afcd581558d | 540 | * @return SUCCESS, negative value in case of failure. |
pmallick | 0:3afcd581558d | 541 | */ |
pmallick | 0:3afcd581558d | 542 | static int32_t iio_get_mask(const char *device, uint32_t *mask) |
pmallick | 0:3afcd581558d | 543 | { |
pmallick | 0:3afcd581558d | 544 | struct iio_interface *iface; |
pmallick | 0:3afcd581558d | 545 | |
pmallick | 0:3afcd581558d | 546 | if (!iio_supported_dev(device)) |
pmallick | 0:3afcd581558d | 547 | return -ENODEV; |
pmallick | 0:3afcd581558d | 548 | |
pmallick | 0:3afcd581558d | 549 | iface = iio_get_interface(device, iio_interfaces); |
pmallick | 0:3afcd581558d | 550 | *mask = iface->ch_mask; |
pmallick | 0:3afcd581558d | 551 | |
pmallick | 0:3afcd581558d | 552 | return SUCCESS; |
pmallick | 0:3afcd581558d | 553 | } |
pmallick | 0:3afcd581558d | 554 | |
pmallick | 0:3afcd581558d | 555 | /** |
pmallick | 0:3afcd581558d | 556 | * @brief Transfer data from device into RAM. |
pmallick | 0:3afcd581558d | 557 | * @param device - String containing device name. |
pmallick | 0:3afcd581558d | 558 | * @param bytes_count - Number of bytes. |
pmallick | 0:3afcd581558d | 559 | * @return Bytes_count or negative value in case of error. |
pmallick | 0:3afcd581558d | 560 | */ |
pmallick | 0:3afcd581558d | 561 | static ssize_t iio_transfer_dev_to_mem(const char *device, size_t bytes_count) |
pmallick | 0:3afcd581558d | 562 | { |
pmallick | 0:3afcd581558d | 563 | struct iio_interface *iio_interface = iio_get_interface(device, iio_interfaces); |
pmallick | 0:3afcd581558d | 564 | |
pmallick | 0:3afcd581558d | 565 | if (iio_interface->transfer_dev_to_mem) |
pmallick | 0:3afcd581558d | 566 | return iio_interface->transfer_dev_to_mem(iio_interface->dev_instance, |
pmallick | 0:3afcd581558d | 567 | bytes_count, iio_interface->ch_mask); |
pmallick | 0:3afcd581558d | 568 | |
pmallick | 0:3afcd581558d | 569 | return -ENOENT; |
pmallick | 0:3afcd581558d | 570 | } |
pmallick | 0:3afcd581558d | 571 | |
pmallick | 0:3afcd581558d | 572 | /** |
pmallick | 0:3afcd581558d | 573 | * @brief Read chunk of data from RAM to pbuf. Call |
pmallick | 0:3afcd581558d | 574 | * "iio_transfer_dev_to_mem()" first. |
pmallick | 0:3afcd581558d | 575 | * This function is probably called multiple times by libtinyiiod after a |
pmallick | 0:3afcd581558d | 576 | * "iio_transfer_dev_to_mem" call, since we can only read "bytes_count" bytes. |
pmallick | 0:3afcd581558d | 577 | * @param device - String containing device name. |
pmallick | 0:3afcd581558d | 578 | * @param pbuf - Buffer where value is stored. |
pmallick | 0:3afcd581558d | 579 | * @param offset - Offset to the remaining data after reading n chunks. |
pmallick | 0:3afcd581558d | 580 | * @param bytes_count - Number of bytes to read. |
pmallick | 0:3afcd581558d | 581 | * @return: Bytes_count or negative value in case of error. |
pmallick | 0:3afcd581558d | 582 | */ |
pmallick | 0:3afcd581558d | 583 | static ssize_t iio_read_dev(const char *device, char *pbuf, size_t offset, |
pmallick | 0:3afcd581558d | 584 | size_t bytes_count) |
pmallick | 0:3afcd581558d | 585 | { |
pmallick | 0:3afcd581558d | 586 | struct iio_interface *iio_interface = iio_get_interface(device, iio_interfaces); |
pmallick | 0:3afcd581558d | 587 | |
pmallick | 0:3afcd581558d | 588 | if (iio_interface->read_data) |
pmallick | 0:3afcd581558d | 589 | return iio_interface->read_data(iio_interface->dev_instance, pbuf, offset, |
pmallick | 0:3afcd581558d | 590 | bytes_count, iio_interface->ch_mask); |
pmallick | 0:3afcd581558d | 591 | |
pmallick | 0:3afcd581558d | 592 | return -ENOENT; |
pmallick | 0:3afcd581558d | 593 | } |
pmallick | 0:3afcd581558d | 594 | |
pmallick | 0:3afcd581558d | 595 | /** |
pmallick | 0:3afcd581558d | 596 | * @brief Transfer memory to device. |
pmallick | 0:3afcd581558d | 597 | * @param device - String containing device name. |
pmallick | 0:3afcd581558d | 598 | * @param bytes_count - Number of bytes to transfer. |
pmallick | 0:3afcd581558d | 599 | * @return Bytes_count or negative value in case of error. |
pmallick | 0:3afcd581558d | 600 | */ |
pmallick | 0:3afcd581558d | 601 | static ssize_t iio_transfer_mem_to_dev(const char *device, size_t bytes_count) |
pmallick | 0:3afcd581558d | 602 | { |
pmallick | 0:3afcd581558d | 603 | struct iio_interface *iio_interface = iio_get_interface(device, iio_interfaces); |
pmallick | 0:3afcd581558d | 604 | |
pmallick | 0:3afcd581558d | 605 | if (iio_interface->transfer_mem_to_dev) |
pmallick | 0:3afcd581558d | 606 | return iio_interface->transfer_mem_to_dev(iio_interface->dev_instance, |
pmallick | 0:3afcd581558d | 607 | bytes_count, iio_interface->ch_mask); |
pmallick | 0:3afcd581558d | 608 | |
pmallick | 0:3afcd581558d | 609 | return -ENOENT; |
pmallick | 0:3afcd581558d | 610 | } |
pmallick | 0:3afcd581558d | 611 | |
pmallick | 0:3afcd581558d | 612 | /** |
pmallick | 0:3afcd581558d | 613 | * @brief Write chunk of data into RAM. |
pmallick | 0:3afcd581558d | 614 | * This function is probably called multiple times by libtinyiiod before a |
pmallick | 0:3afcd581558d | 615 | * "iio_transfer_mem_to_dev" call, since we can only write "bytes_count" bytes |
pmallick | 0:3afcd581558d | 616 | * at a time. |
pmallick | 0:3afcd581558d | 617 | * @param device - String containing device name. |
pmallick | 0:3afcd581558d | 618 | * @param buf - Values to write. |
pmallick | 0:3afcd581558d | 619 | * @param offset - Offset in memory after the nth chunk of data. |
pmallick | 0:3afcd581558d | 620 | * @param bytes_count - Number of bytes to write. |
pmallick | 0:3afcd581558d | 621 | * @return Bytes_count or negative value in case of error. |
pmallick | 0:3afcd581558d | 622 | */ |
pmallick | 0:3afcd581558d | 623 | static ssize_t iio_write_dev(const char *device, const char *buf, |
pmallick | 0:3afcd581558d | 624 | size_t offset, size_t bytes_count) |
pmallick | 0:3afcd581558d | 625 | { |
pmallick | 0:3afcd581558d | 626 | struct iio_interface *iio_interface = iio_get_interface(device, iio_interfaces); |
pmallick | 0:3afcd581558d | 627 | if(iio_interface->write_data) |
pmallick | 0:3afcd581558d | 628 | return iio_interface->write_data(iio_interface->dev_instance, (char*)buf, |
pmallick | 0:3afcd581558d | 629 | offset, bytes_count, iio_interface->ch_mask); |
pmallick | 0:3afcd581558d | 630 | |
pmallick | 0:3afcd581558d | 631 | return -ENOENT; |
pmallick | 0:3afcd581558d | 632 | } |
pmallick | 0:3afcd581558d | 633 | |
pmallick | 0:3afcd581558d | 634 | /** |
pmallick | 0:3afcd581558d | 635 | * @brief Get a merged xml containing all devices. |
pmallick | 0:3afcd581558d | 636 | * @param outxml - Generated xml. |
pmallick | 0:3afcd581558d | 637 | * @return SUCCESS in case of success or negative value otherwise. |
pmallick | 0:3afcd581558d | 638 | */ |
pmallick | 0:3afcd581558d | 639 | static ssize_t iio_get_xml(char **outxml) |
pmallick | 0:3afcd581558d | 640 | { |
pmallick | 0:3afcd581558d | 641 | char *xml, *tmp_xml, *tmp_xml2; |
pmallick | 0:3afcd581558d | 642 | uint32_t length; |
pmallick | 0:3afcd581558d | 643 | uint16_t i; |
pmallick | 0:3afcd581558d | 644 | ssize_t ret; |
pmallick | 0:3afcd581558d | 645 | |
pmallick | 0:3afcd581558d | 646 | char header[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" |
pmallick | 0:3afcd581558d | 647 | "<!DOCTYPE context [" |
pmallick | 0:3afcd581558d | 648 | "<!ELEMENT context (device | context-attribute)*>" |
pmallick | 0:3afcd581558d | 649 | "<!ELEMENT context-attribute EMPTY>" |
pmallick | 0:3afcd581558d | 650 | "<!ELEMENT device (channel | attribute | debug-attribute | buffer-attribute)*>" |
pmallick | 0:3afcd581558d | 651 | "<!ELEMENT channel (scan-element?, attribute*)>" |
pmallick | 0:3afcd581558d | 652 | "<!ELEMENT attribute EMPTY>" |
pmallick | 0:3afcd581558d | 653 | "<!ELEMENT scan-element EMPTY>" |
pmallick | 0:3afcd581558d | 654 | "<!ELEMENT debug-attribute EMPTY>" |
pmallick | 0:3afcd581558d | 655 | "<!ELEMENT buffer-attribute EMPTY>" |
pmallick | 0:3afcd581558d | 656 | "<!ATTLIST context name CDATA #REQUIRED description CDATA #IMPLIED>" |
pmallick | 0:3afcd581558d | 657 | "<!ATTLIST context-attribute name CDATA #REQUIRED value CDATA #REQUIRED>" |
pmallick | 0:3afcd581558d | 658 | "<!ATTLIST device id CDATA #REQUIRED name CDATA #IMPLIED>" |
pmallick | 0:3afcd581558d | 659 | "<!ATTLIST channel id CDATA #REQUIRED type (input|output) #REQUIRED name CDATA #IMPLIED>" |
pmallick | 0:3afcd581558d | 660 | "<!ATTLIST scan-element index CDATA #REQUIRED format CDATA #REQUIRED scale CDATA #IMPLIED>" |
pmallick | 0:3afcd581558d | 661 | "<!ATTLIST attribute name CDATA #REQUIRED filename CDATA #IMPLIED>" |
pmallick | 0:3afcd581558d | 662 | "<!ATTLIST debug-attribute name CDATA #REQUIRED>" |
pmallick | 0:3afcd581558d | 663 | "<!ATTLIST buffer-attribute name CDATA #REQUIRED>" |
pmallick | 0:3afcd581558d | 664 | "]>" |
pmallick | 0:3afcd581558d | 665 | "<context name=\"xml\" description=\"no-OS analog 1.1.0-g0000000 #1 Tue Nov 26 09:52:32 IST 2019 armv7l\" >" |
pmallick | 0:3afcd581558d | 666 | "<context-attribute name=\"no-OS\" value=\"1.1.0-g0000000\" />"; |
pmallick | 0:3afcd581558d | 667 | char header_end[] = "</context>"; |
pmallick | 0:3afcd581558d | 668 | |
pmallick | 0:3afcd581558d | 669 | if (!outxml) |
pmallick | 0:3afcd581558d | 670 | return FAILURE; |
pmallick | 0:3afcd581558d | 671 | |
pmallick | 0:3afcd581558d | 672 | xml = (char *)calloc(1, strlen(header) + 1); |
pmallick | 0:3afcd581558d | 673 | if (!xml) |
pmallick | 0:3afcd581558d | 674 | return FAILURE; |
pmallick | 0:3afcd581558d | 675 | |
pmallick | 0:3afcd581558d | 676 | strcpy(xml, header); |
pmallick | 0:3afcd581558d | 677 | for (i = 0; i < iio_interfaces->num_interfaces; i++) { |
pmallick | 0:3afcd581558d | 678 | ret = iio_interfaces->interfaces[i]->get_xml(&tmp_xml, |
pmallick | 0:3afcd581558d | 679 | iio_interfaces->interfaces[i]->iio); |
pmallick | 0:3afcd581558d | 680 | if (ret < 0) |
pmallick | 0:3afcd581558d | 681 | goto error; |
pmallick | 0:3afcd581558d | 682 | |
pmallick | 0:3afcd581558d | 683 | length = strlen(xml); |
pmallick | 0:3afcd581558d | 684 | tmp_xml2 = (char *)realloc(xml, strlen(xml) + strlen(tmp_xml) + 1); |
pmallick | 0:3afcd581558d | 685 | if (!tmp_xml2) |
pmallick | 0:3afcd581558d | 686 | goto error; |
pmallick | 0:3afcd581558d | 687 | |
pmallick | 0:3afcd581558d | 688 | xml = tmp_xml2; |
pmallick | 0:3afcd581558d | 689 | strcpy((xml + length), tmp_xml); |
pmallick | 0:3afcd581558d | 690 | } |
pmallick | 0:3afcd581558d | 691 | |
pmallick | 0:3afcd581558d | 692 | length = strlen(xml); |
pmallick | 0:3afcd581558d | 693 | tmp_xml = (char *)realloc(xml, strlen(xml) + strlen(header_end) + 1); |
pmallick | 0:3afcd581558d | 694 | if (!tmp_xml) |
pmallick | 0:3afcd581558d | 695 | goto error; |
pmallick | 0:3afcd581558d | 696 | |
pmallick | 0:3afcd581558d | 697 | xml = tmp_xml; |
pmallick | 0:3afcd581558d | 698 | strcpy((xml + length), header_end); |
pmallick | 0:3afcd581558d | 699 | |
pmallick | 0:3afcd581558d | 700 | *outxml = xml; |
pmallick | 0:3afcd581558d | 701 | |
pmallick | 0:3afcd581558d | 702 | return SUCCESS; |
pmallick | 0:3afcd581558d | 703 | error: |
pmallick | 0:3afcd581558d | 704 | free(xml); |
pmallick | 0:3afcd581558d | 705 | |
pmallick | 0:3afcd581558d | 706 | return FAILURE; |
pmallick | 0:3afcd581558d | 707 | } |
pmallick | 0:3afcd581558d | 708 | |
pmallick | 0:3afcd581558d | 709 | /** |
pmallick | 0:3afcd581558d | 710 | * @brief Register interface. |
pmallick | 0:3afcd581558d | 711 | * @param iio_interface - Structure containing physical device instance and |
pmallick | 0:3afcd581558d | 712 | * device descriptor. |
pmallick | 0:3afcd581558d | 713 | * @return SUCCESS in case of success or negative value otherwise. |
pmallick | 0:3afcd581558d | 714 | */ |
pmallick | 0:3afcd581558d | 715 | ssize_t iio_register(struct iio_interface *iio_interface) |
pmallick | 0:3afcd581558d | 716 | { |
pmallick | 0:3afcd581558d | 717 | |
pmallick | 0:3afcd581558d | 718 | struct iio_interface **temp_interfaces; |
pmallick | 0:3afcd581558d | 719 | |
pmallick | 0:3afcd581558d | 720 | if (!(iio_interfaces)) { |
pmallick | 0:3afcd581558d | 721 | iio_interfaces = (struct iio_interfaces *)calloc(1, |
pmallick | 0:3afcd581558d | 722 | sizeof(struct iio_interfaces)); |
pmallick | 0:3afcd581558d | 723 | if (!iio_interfaces) |
pmallick | 0:3afcd581558d | 724 | return -ENOMEM; |
pmallick | 0:3afcd581558d | 725 | |
pmallick | 0:3afcd581558d | 726 | iio_interfaces->num_interfaces = 1; |
pmallick | 0:3afcd581558d | 727 | iio_interfaces->interfaces = (struct iio_interface **)calloc(1, |
pmallick | 0:3afcd581558d | 728 | sizeof(struct iio_interface*)); |
pmallick | 0:3afcd581558d | 729 | if (!iio_interfaces->interfaces) |
pmallick | 0:3afcd581558d | 730 | return -ENOMEM; |
pmallick | 0:3afcd581558d | 731 | } else { |
pmallick | 0:3afcd581558d | 732 | iio_interfaces->num_interfaces++; |
pmallick | 0:3afcd581558d | 733 | temp_interfaces = (struct iio_interface **)realloc(iio_interfaces->interfaces, |
pmallick | 0:3afcd581558d | 734 | iio_interfaces->num_interfaces * sizeof(struct iio_interface*)); |
pmallick | 0:3afcd581558d | 735 | if (!temp_interfaces) { |
pmallick | 0:3afcd581558d | 736 | free(iio_interfaces->interfaces); |
pmallick | 0:3afcd581558d | 737 | return -ENOMEM; |
pmallick | 0:3afcd581558d | 738 | } |
pmallick | 0:3afcd581558d | 739 | iio_interfaces->interfaces = temp_interfaces; |
pmallick | 0:3afcd581558d | 740 | } |
pmallick | 0:3afcd581558d | 741 | |
pmallick | 0:3afcd581558d | 742 | iio_interfaces->interfaces[iio_interfaces->num_interfaces - 1] = iio_interface; |
pmallick | 0:3afcd581558d | 743 | |
pmallick | 0:3afcd581558d | 744 | return SUCCESS; |
pmallick | 0:3afcd581558d | 745 | } |
pmallick | 0:3afcd581558d | 746 | |
pmallick | 0:3afcd581558d | 747 | /** |
pmallick | 0:3afcd581558d | 748 | * @brief Unregister interface. |
pmallick | 0:3afcd581558d | 749 | * @param iio_interface - Structure containing physical device instance and |
pmallick | 0:3afcd581558d | 750 | * device descriptor. |
pmallick | 0:3afcd581558d | 751 | * @return SUCCESS in case of success or negative value otherwise. |
pmallick | 0:3afcd581558d | 752 | */ |
pmallick | 0:3afcd581558d | 753 | ssize_t iio_unregister(struct iio_interface *iio_interface) |
pmallick | 0:3afcd581558d | 754 | { |
pmallick | 0:3afcd581558d | 755 | struct iio_interfaces *interfaces; |
pmallick | 0:3afcd581558d | 756 | int16_t i, deleted = 0; |
pmallick | 0:3afcd581558d | 757 | |
pmallick | 0:3afcd581558d | 758 | interfaces = (struct iio_interfaces *)calloc(1, sizeof(struct iio_interfaces)); |
pmallick | 0:3afcd581558d | 759 | if (!interfaces) |
pmallick | 0:3afcd581558d | 760 | return FAILURE; |
pmallick | 0:3afcd581558d | 761 | |
pmallick | 0:3afcd581558d | 762 | interfaces->interfaces = (struct iio_interface **)calloc( |
pmallick | 0:3afcd581558d | 763 | iio_interfaces->num_interfaces - 1, |
pmallick | 0:3afcd581558d | 764 | sizeof(struct iio_interface*)); |
pmallick | 0:3afcd581558d | 765 | if (!interfaces->interfaces) { |
pmallick | 0:3afcd581558d | 766 | free(interfaces); |
pmallick | 0:3afcd581558d | 767 | return FAILURE; |
pmallick | 0:3afcd581558d | 768 | } |
pmallick | 0:3afcd581558d | 769 | |
pmallick | 0:3afcd581558d | 770 | for(i = 0; i < iio_interfaces->num_interfaces; i++) { |
pmallick | 0:3afcd581558d | 771 | if (!strcmp(iio_interface->name, iio_interfaces->interfaces[i]->name)) { |
pmallick | 0:3afcd581558d | 772 | iio_interface = iio_interfaces->interfaces[i]; |
pmallick | 0:3afcd581558d | 773 | deleted = 1; |
pmallick | 0:3afcd581558d | 774 | continue; |
pmallick | 0:3afcd581558d | 775 | } |
pmallick | 0:3afcd581558d | 776 | interfaces->interfaces[i - deleted] = iio_interfaces->interfaces[i]; |
pmallick | 0:3afcd581558d | 777 | } |
pmallick | 0:3afcd581558d | 778 | |
pmallick | 0:3afcd581558d | 779 | interfaces->num_interfaces = iio_interfaces->num_interfaces - 1; |
pmallick | 0:3afcd581558d | 780 | free(iio_interfaces); |
pmallick | 0:3afcd581558d | 781 | |
pmallick | 0:3afcd581558d | 782 | return deleted ? SUCCESS : FAILURE; |
pmallick | 0:3afcd581558d | 783 | } |
pmallick | 0:3afcd581558d | 784 | |
pmallick | 0:3afcd581558d | 785 | /** |
pmallick | 0:3afcd581558d | 786 | * @brief Set communication ops and read/write ops that will be called |
pmallick | 0:3afcd581558d | 787 | * from "libtinyiiod". |
pmallick | 0:3afcd581558d | 788 | * @param iiod - Structure containing new tinyiiod instance. |
pmallick | 0:3afcd581558d | 789 | * @param iio_server_ops - Structure containing read/write ops (Ex: read/write to |
pmallick | 0:3afcd581558d | 790 | * UART). |
pmallick | 0:3afcd581558d | 791 | * @return SUCCESS in case of success or negative value otherwise. |
pmallick | 0:3afcd581558d | 792 | */ |
pmallick | 0:3afcd581558d | 793 | ssize_t iio_init(struct tinyiiod **iiod, struct iio_server_ops *iio_server_ops) |
pmallick | 0:3afcd581558d | 794 | { |
pmallick | 0:3afcd581558d | 795 | struct tinyiiod_ops *ops = (struct tinyiiod_ops *)calloc(1, |
pmallick | 0:3afcd581558d | 796 | sizeof(struct tinyiiod_ops)); |
pmallick | 0:3afcd581558d | 797 | |
pmallick | 0:3afcd581558d | 798 | if (!ops) |
pmallick | 0:3afcd581558d | 799 | return FAILURE; |
pmallick | 0:3afcd581558d | 800 | |
pmallick | 0:3afcd581558d | 801 | /* device operations */ |
pmallick | 0:3afcd581558d | 802 | ops->read_attr = iio_read_attr; |
pmallick | 0:3afcd581558d | 803 | ops->write_attr = iio_write_attr; |
pmallick | 0:3afcd581558d | 804 | ops->ch_read_attr = iio_ch_read_attr; |
pmallick | 0:3afcd581558d | 805 | ops->ch_write_attr = iio_ch_write_attr; |
pmallick | 0:3afcd581558d | 806 | ops->transfer_dev_to_mem = iio_transfer_dev_to_mem; |
pmallick | 0:3afcd581558d | 807 | ops->read_data = iio_read_dev; |
pmallick | 0:3afcd581558d | 808 | ops->transfer_mem_to_dev = iio_transfer_mem_to_dev; |
pmallick | 0:3afcd581558d | 809 | ops->write_data = iio_write_dev; |
pmallick | 0:3afcd581558d | 810 | |
pmallick | 0:3afcd581558d | 811 | ops->open = iio_open_dev; |
pmallick | 0:3afcd581558d | 812 | ops->close = iio_close_dev; |
pmallick | 0:3afcd581558d | 813 | ops->get_mask = iio_get_mask; |
pmallick | 0:3afcd581558d | 814 | |
pmallick | 0:3afcd581558d | 815 | ops->read = iio_server_ops->read; |
pmallick | 0:3afcd581558d | 816 | ops->write = iio_server_ops->write; |
pmallick | 0:3afcd581558d | 817 | ops->get_xml = iio_get_xml; |
pmallick | 0:3afcd581558d | 818 | |
pmallick | 0:3afcd581558d | 819 | *iiod = tinyiiod_create(ops); |
pmallick | 0:3afcd581558d | 820 | if (!(*iiod)) { |
pmallick | 0:3afcd581558d | 821 | free(ops); |
pmallick | 0:3afcd581558d | 822 | return FAILURE; |
pmallick | 0:3afcd581558d | 823 | } else { |
pmallick | 0:3afcd581558d | 824 | return SUCCESS; |
pmallick | 0:3afcd581558d | 825 | } |
pmallick | 0:3afcd581558d | 826 | } |
pmallick | 0:3afcd581558d | 827 | |
pmallick | 0:3afcd581558d | 828 | /** |
pmallick | 0:3afcd581558d | 829 | * @brief Free the resources allocated by "iio_init()". |
pmallick | 0:3afcd581558d | 830 | * @param iiod: Structure containing tinyiiod instance. |
pmallick | 0:3afcd581558d | 831 | * @return SUCCESS in case of success or negative value otherwise. |
pmallick | 0:3afcd581558d | 832 | */ |
pmallick | 0:3afcd581558d | 833 | ssize_t iio_remove(struct tinyiiod *iiod) |
pmallick | 0:3afcd581558d | 834 | { |
pmallick | 0:3afcd581558d | 835 | uint8_t i; |
pmallick | 0:3afcd581558d | 836 | |
pmallick | 0:3afcd581558d | 837 | for (i = 0; i < iio_interfaces->num_interfaces; i++) |
pmallick | 0:3afcd581558d | 838 | free(iio_interfaces->interfaces[i]); |
pmallick | 0:3afcd581558d | 839 | |
pmallick | 0:3afcd581558d | 840 | free(iio_interfaces); |
pmallick | 0:3afcd581558d | 841 | tinyiiod_destroy(iiod); |
pmallick | 0:3afcd581558d | 842 | |
pmallick | 0:3afcd581558d | 843 | return SUCCESS; |
pmallick | 0:3afcd581558d | 844 | } |