xref: /linux/drivers/iio/inkern.c (revision 1a371190a375f98c9b106f758ea41558c3f92556)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* The industrial I/O core in kernel channel mapping
3  *
4  * Copyright (c) 2011 Jonathan Cameron
5  */
6 #include <linux/cleanup.h>
7 #include <linux/err.h>
8 #include <linux/export.h>
9 #include <linux/minmax.h>
10 #include <linux/mutex.h>
11 #include <linux/property.h>
12 #include <linux/slab.h>
13 
14 #include <linux/iio/iio.h>
15 #include <linux/iio/iio-opaque.h>
16 #include "iio_core.h"
17 #include <linux/iio/machine.h>
18 #include <linux/iio/driver.h>
19 #include <linux/iio/consumer.h>
20 
21 struct iio_map_internal {
22 	struct iio_dev *indio_dev;
23 	struct iio_map *map;
24 	struct list_head l;
25 };
26 
27 static LIST_HEAD(iio_map_list);
28 static DEFINE_MUTEX(iio_map_list_lock);
29 
iio_map_array_unregister_locked(struct iio_dev * indio_dev)30 static int iio_map_array_unregister_locked(struct iio_dev *indio_dev)
31 {
32 	int ret = -ENODEV;
33 	struct iio_map_internal *mapi, *next;
34 
35 	list_for_each_entry_safe(mapi, next, &iio_map_list, l) {
36 		if (indio_dev == mapi->indio_dev) {
37 			list_del(&mapi->l);
38 			kfree(mapi);
39 			ret = 0;
40 		}
41 	}
42 	return ret;
43 }
44 
iio_map_array_register(struct iio_dev * indio_dev,struct iio_map * maps)45 int iio_map_array_register(struct iio_dev *indio_dev, struct iio_map *maps)
46 {
47 	struct iio_map_internal *mapi;
48 	int i = 0;
49 	int ret;
50 
51 	if (!maps)
52 		return 0;
53 
54 	guard(mutex)(&iio_map_list_lock);
55 	while (maps[i].consumer_dev_name) {
56 		mapi = kzalloc(sizeof(*mapi), GFP_KERNEL);
57 		if (!mapi) {
58 			ret = -ENOMEM;
59 			goto error_ret;
60 		}
61 		mapi->map = &maps[i];
62 		mapi->indio_dev = indio_dev;
63 		list_add_tail(&mapi->l, &iio_map_list);
64 		i++;
65 	}
66 
67 	return 0;
68 error_ret:
69 	iio_map_array_unregister_locked(indio_dev);
70 	return ret;
71 }
72 EXPORT_SYMBOL_GPL(iio_map_array_register);
73 
74 /*
75  * Remove all map entries associated with the given iio device
76  */
iio_map_array_unregister(struct iio_dev * indio_dev)77 int iio_map_array_unregister(struct iio_dev *indio_dev)
78 {
79 	guard(mutex)(&iio_map_list_lock);
80 	return iio_map_array_unregister_locked(indio_dev);
81 }
82 EXPORT_SYMBOL_GPL(iio_map_array_unregister);
83 
iio_map_array_unregister_cb(void * indio_dev)84 static void iio_map_array_unregister_cb(void *indio_dev)
85 {
86 	iio_map_array_unregister(indio_dev);
87 }
88 
devm_iio_map_array_register(struct device * dev,struct iio_dev * indio_dev,struct iio_map * maps)89 int devm_iio_map_array_register(struct device *dev, struct iio_dev *indio_dev, struct iio_map *maps)
90 {
91 	int ret;
92 
93 	ret = iio_map_array_register(indio_dev, maps);
94 	if (ret)
95 		return ret;
96 
97 	return devm_add_action_or_reset(dev, iio_map_array_unregister_cb, indio_dev);
98 }
99 EXPORT_SYMBOL_GPL(devm_iio_map_array_register);
100 
101 static const struct iio_chan_spec
iio_chan_spec_from_name(const struct iio_dev * indio_dev,const char * name)102 *iio_chan_spec_from_name(const struct iio_dev *indio_dev, const char *name)
103 {
104 	int i;
105 	const struct iio_chan_spec *chan = NULL;
106 
107 	for (i = 0; i < indio_dev->num_channels; i++)
108 		if (indio_dev->channels[i].datasheet_name &&
109 		    strcmp(name, indio_dev->channels[i].datasheet_name) == 0) {
110 			chan = &indio_dev->channels[i];
111 			break;
112 		}
113 	return chan;
114 }
115 
116 /**
117  * __fwnode_iio_simple_xlate - translate iiospec to the IIO channel index
118  * @indio_dev:	pointer to the iio_dev structure
119  * @iiospec:	IIO specifier as found in the device tree
120  *
121  * This is simple translation function, suitable for the most 1:1 mapped
122  * channels in IIO chips. This function performs only one sanity check:
123  * whether IIO index is less than num_channels (that is specified in the
124  * iio_dev).
125  */
__fwnode_iio_simple_xlate(struct iio_dev * indio_dev,const struct fwnode_reference_args * iiospec)126 static int __fwnode_iio_simple_xlate(struct iio_dev *indio_dev,
127 				     const struct fwnode_reference_args *iiospec)
128 {
129 	if (!iiospec->nargs)
130 		return 0;
131 
132 	if (iiospec->args[0] >= indio_dev->num_channels) {
133 		dev_err(&indio_dev->dev, "invalid channel index %llu\n",
134 			iiospec->args[0]);
135 		return -EINVAL;
136 	}
137 
138 	return iiospec->args[0];
139 }
140 
__fwnode_iio_channel_get(struct iio_channel * channel,struct fwnode_handle * fwnode,int index)141 static int __fwnode_iio_channel_get(struct iio_channel *channel,
142 				    struct fwnode_handle *fwnode, int index)
143 {
144 	struct fwnode_reference_args iiospec;
145 	struct device *idev;
146 	struct iio_dev *indio_dev;
147 	int err;
148 
149 	err = fwnode_property_get_reference_args(fwnode, "io-channels",
150 						 "#io-channel-cells", 0,
151 						 index, &iiospec);
152 	if (err)
153 		return err;
154 
155 	idev = bus_find_device_by_fwnode(&iio_bus_type, iiospec.fwnode);
156 	if (!idev) {
157 		fwnode_handle_put(iiospec.fwnode);
158 		return -EPROBE_DEFER;
159 	}
160 
161 	indio_dev = dev_to_iio_dev(idev);
162 	channel->indio_dev = indio_dev;
163 	if (indio_dev->info->fwnode_xlate)
164 		index = indio_dev->info->fwnode_xlate(indio_dev, &iiospec);
165 	else
166 		index = __fwnode_iio_simple_xlate(indio_dev, &iiospec);
167 	fwnode_handle_put(iiospec.fwnode);
168 	if (index < 0)
169 		goto err_put;
170 	channel->channel = &indio_dev->channels[index];
171 
172 	return 0;
173 
174 err_put:
175 	iio_device_put(indio_dev);
176 	return index;
177 }
178 
fwnode_iio_channel_get(struct fwnode_handle * fwnode,int index)179 static struct iio_channel *fwnode_iio_channel_get(struct fwnode_handle *fwnode,
180 						  int index)
181 {
182 	int err;
183 
184 	if (index < 0)
185 		return ERR_PTR(-EINVAL);
186 
187 	struct iio_channel *channel __free(kfree) =
188 		kzalloc(sizeof(*channel), GFP_KERNEL);
189 	if (!channel)
190 		return ERR_PTR(-ENOMEM);
191 
192 	err = __fwnode_iio_channel_get(channel, fwnode, index);
193 	if (err)
194 		return ERR_PTR(err);
195 
196 	return_ptr(channel);
197 }
198 
199 static struct iio_channel *
__fwnode_iio_channel_get_by_name(struct fwnode_handle * fwnode,const char * name)200 __fwnode_iio_channel_get_by_name(struct fwnode_handle *fwnode, const char *name)
201 {
202 	struct iio_channel *chan;
203 	int index = 0;
204 
205 	/*
206 	 * For named iio channels, first look up the name in the
207 	 * "io-channel-names" property.  If it cannot be found, the
208 	 * index will be an error code, and fwnode_iio_channel_get()
209 	 * will fail.
210 	 */
211 	if (name)
212 		index = fwnode_property_match_string(fwnode, "io-channel-names",
213 						     name);
214 
215 	chan = fwnode_iio_channel_get(fwnode, index);
216 	if (!IS_ERR(chan) || PTR_ERR(chan) == -EPROBE_DEFER)
217 		return chan;
218 	if (name) {
219 		if (index >= 0) {
220 			pr_err("ERROR: could not get IIO channel %pfw:%s(%i)\n",
221 			       fwnode, name, index);
222 			/*
223 			 * In this case, we found 'name' in 'io-channel-names'
224 			 * but somehow we still fail so that we should not proceed
225 			 * with any other lookup. Hence, explicitly return -EINVAL
226 			 * (maybe not the better error code) so that the caller
227 			 * won't do a system lookup.
228 			 */
229 			return ERR_PTR(-EINVAL);
230 		}
231 		/*
232 		 * If index < 0, then fwnode_property_get_reference_args() fails
233 		 * with -EINVAL or -ENOENT (ACPI case) which is expected. We
234 		 * should not proceed if we get any other error.
235 		 */
236 		if (PTR_ERR(chan) != -EINVAL && PTR_ERR(chan) != -ENOENT)
237 			return chan;
238 	} else if (PTR_ERR(chan) != -ENOENT) {
239 		/*
240 		 * if !name, then we should only proceed the lookup if
241 		 * fwnode_property_get_reference_args() returns -ENOENT.
242 		 */
243 		return chan;
244 	}
245 
246 	/* so we continue the lookup */
247 	return ERR_PTR(-ENODEV);
248 }
249 
fwnode_iio_channel_get_by_name(struct fwnode_handle * fwnode,const char * name)250 struct iio_channel *fwnode_iio_channel_get_by_name(struct fwnode_handle *fwnode,
251 						   const char *name)
252 {
253 	struct fwnode_handle *parent;
254 	struct iio_channel *chan;
255 
256 	/* Walk up the tree of devices looking for a matching iio channel */
257 	chan = __fwnode_iio_channel_get_by_name(fwnode, name);
258 	if (!IS_ERR(chan) || PTR_ERR(chan) != -ENODEV)
259 		return chan;
260 
261 	/*
262 	 * No matching IIO channel found on this node.
263 	 * If the parent node has a "io-channel-ranges" property,
264 	 * then we can try one of its channels.
265 	 */
266 	fwnode_for_each_parent_node(fwnode, parent) {
267 		if (!fwnode_property_present(parent, "io-channel-ranges")) {
268 			fwnode_handle_put(parent);
269 			return ERR_PTR(-ENODEV);
270 		}
271 
272 		chan = __fwnode_iio_channel_get_by_name(fwnode, name);
273 		if (!IS_ERR(chan) || PTR_ERR(chan) != -ENODEV) {
274 			fwnode_handle_put(parent);
275  			return chan;
276 		}
277 	}
278 
279 	return ERR_PTR(-ENODEV);
280 }
281 EXPORT_SYMBOL_GPL(fwnode_iio_channel_get_by_name);
282 
fwnode_iio_channel_get_all(struct device * dev)283 static struct iio_channel *fwnode_iio_channel_get_all(struct device *dev)
284 {
285 	struct fwnode_handle *fwnode = dev_fwnode(dev);
286 	int i, mapind, nummaps = 0;
287 	int ret;
288 
289 	do {
290 		ret = fwnode_property_get_reference_args(fwnode, "io-channels",
291 							 "#io-channel-cells", 0,
292 							 nummaps, NULL);
293 		if (ret < 0)
294 			break;
295 	} while (++nummaps);
296 
297 	if (nummaps == 0)
298 		return ERR_PTR(-ENODEV);
299 
300 	/* NULL terminated array to save passing size */
301 	struct iio_channel *chans __free(kfree) =
302 		kcalloc(nummaps + 1, sizeof(*chans), GFP_KERNEL);
303 	if (!chans)
304 		return ERR_PTR(-ENOMEM);
305 
306 	/* Search for FW matches */
307 	for (mapind = 0; mapind < nummaps; mapind++) {
308 		ret = __fwnode_iio_channel_get(&chans[mapind], fwnode, mapind);
309 		if (ret)
310 			goto error_free_chans;
311 	}
312 	return_ptr(chans);
313 
314 error_free_chans:
315 	for (i = 0; i < mapind; i++)
316 		iio_device_put(chans[i].indio_dev);
317 	return ERR_PTR(ret);
318 }
319 
iio_channel_get_sys(const char * name,const char * channel_name)320 static struct iio_channel *iio_channel_get_sys(const char *name,
321 					       const char *channel_name)
322 {
323 	struct iio_map_internal *c_i = NULL, *c = NULL;
324 	int err;
325 
326 	if (!(name || channel_name))
327 		return ERR_PTR(-ENODEV);
328 
329 	/* first find matching entry the channel map */
330 	scoped_guard(mutex, &iio_map_list_lock) {
331 		list_for_each_entry(c_i, &iio_map_list, l) {
332 			if ((name && strcmp(name, c_i->map->consumer_dev_name) != 0) ||
333 			    (channel_name &&
334 			     strcmp(channel_name, c_i->map->consumer_channel) != 0))
335 				continue;
336 			c = c_i;
337 			iio_device_get(c->indio_dev);
338 			break;
339 		}
340 	}
341 	if (!c)
342 		return ERR_PTR(-ENODEV);
343 
344 	struct iio_channel *channel __free(kfree) =
345 		kzalloc(sizeof(*channel), GFP_KERNEL);
346 	if (!channel) {
347 		err = -ENOMEM;
348 		goto error_no_mem;
349 	}
350 
351 	channel->indio_dev = c->indio_dev;
352 
353 	if (c->map->adc_channel_label) {
354 		channel->channel =
355 			iio_chan_spec_from_name(channel->indio_dev,
356 						c->map->adc_channel_label);
357 
358 		if (!channel->channel) {
359 			err = -EINVAL;
360 			goto error_no_mem;
361 		}
362 	}
363 
364 	return_ptr(channel);
365 
366 error_no_mem:
367 	iio_device_put(c->indio_dev);
368 	return ERR_PTR(err);
369 }
370 
iio_channel_get(struct device * dev,const char * channel_name)371 struct iio_channel *iio_channel_get(struct device *dev,
372 				    const char *channel_name)
373 {
374 	const char *name = dev ? dev_name(dev) : NULL;
375 	struct iio_channel *channel;
376 
377 	if (dev) {
378 		channel = fwnode_iio_channel_get_by_name(dev_fwnode(dev),
379 							 channel_name);
380 		if (!IS_ERR(channel) || PTR_ERR(channel) != -ENODEV)
381 			return channel;
382 	}
383 
384 	return iio_channel_get_sys(name, channel_name);
385 }
386 EXPORT_SYMBOL_GPL(iio_channel_get);
387 
iio_channel_release(struct iio_channel * channel)388 void iio_channel_release(struct iio_channel *channel)
389 {
390 	if (!channel)
391 		return;
392 	iio_device_put(channel->indio_dev);
393 	kfree(channel);
394 }
395 EXPORT_SYMBOL_GPL(iio_channel_release);
396 
devm_iio_channel_free(void * iio_channel)397 static void devm_iio_channel_free(void *iio_channel)
398 {
399 	iio_channel_release(iio_channel);
400 }
401 
devm_iio_channel_get(struct device * dev,const char * channel_name)402 struct iio_channel *devm_iio_channel_get(struct device *dev,
403 					 const char *channel_name)
404 {
405 	struct iio_channel *channel;
406 	int ret;
407 
408 	channel = iio_channel_get(dev, channel_name);
409 	if (IS_ERR(channel))
410 		return channel;
411 
412 	ret = devm_add_action_or_reset(dev, devm_iio_channel_free, channel);
413 	if (ret)
414 		return ERR_PTR(ret);
415 
416 	return channel;
417 }
418 EXPORT_SYMBOL_GPL(devm_iio_channel_get);
419 
devm_fwnode_iio_channel_get_by_name(struct device * dev,struct fwnode_handle * fwnode,const char * channel_name)420 struct iio_channel *devm_fwnode_iio_channel_get_by_name(struct device *dev,
421 							struct fwnode_handle *fwnode,
422 							const char *channel_name)
423 {
424 	struct iio_channel *channel;
425 	int ret;
426 
427 	channel = fwnode_iio_channel_get_by_name(fwnode, channel_name);
428 	if (IS_ERR(channel))
429 		return channel;
430 
431 	ret = devm_add_action_or_reset(dev, devm_iio_channel_free, channel);
432 	if (ret)
433 		return ERR_PTR(ret);
434 
435 	return channel;
436 }
437 EXPORT_SYMBOL_GPL(devm_fwnode_iio_channel_get_by_name);
438 
iio_channel_get_all(struct device * dev)439 struct iio_channel *iio_channel_get_all(struct device *dev)
440 {
441 	const char *name;
442 	struct iio_map_internal *c = NULL;
443 	struct iio_channel *fw_chans;
444 	int nummaps = 0;
445 	int mapind = 0;
446 	int i, ret;
447 
448 	if (!dev)
449 		return ERR_PTR(-EINVAL);
450 
451 	fw_chans = fwnode_iio_channel_get_all(dev);
452 	/*
453 	 * We only want to carry on if the error is -ENODEV.  Anything else
454 	 * should be reported up the stack.
455 	 */
456 	if (!IS_ERR(fw_chans) || PTR_ERR(fw_chans) != -ENODEV)
457 		return fw_chans;
458 
459 	name = dev_name(dev);
460 
461 	guard(mutex)(&iio_map_list_lock);
462 	/* first count the matching maps */
463 	list_for_each_entry(c, &iio_map_list, l)
464 		if (name && strcmp(name, c->map->consumer_dev_name) != 0)
465 			continue;
466 		else
467 			nummaps++;
468 
469 	if (nummaps == 0)
470 		return ERR_PTR(-ENODEV);
471 
472 	/* NULL terminated array to save passing size */
473 	struct iio_channel *chans __free(kfree) =
474 		kcalloc(nummaps + 1, sizeof(*chans), GFP_KERNEL);
475 	if (!chans)
476 		return ERR_PTR(-ENOMEM);
477 
478 	/* for each map fill in the chans element */
479 	list_for_each_entry(c, &iio_map_list, l) {
480 		if (name && strcmp(name, c->map->consumer_dev_name) != 0)
481 			continue;
482 		chans[mapind].indio_dev = c->indio_dev;
483 		chans[mapind].data = c->map->consumer_data;
484 		chans[mapind].channel =
485 			iio_chan_spec_from_name(chans[mapind].indio_dev,
486 						c->map->adc_channel_label);
487 		if (!chans[mapind].channel) {
488 			ret = -EINVAL;
489 			goto error_free_chans;
490 		}
491 		iio_device_get(chans[mapind].indio_dev);
492 		mapind++;
493 	}
494 	if (mapind == 0) {
495 		ret = -ENODEV;
496 		goto error_free_chans;
497 	}
498 
499 	return_ptr(chans);
500 
501 error_free_chans:
502 	for (i = 0; i < nummaps; i++)
503 		iio_device_put(chans[i].indio_dev);
504 	return ERR_PTR(ret);
505 }
506 EXPORT_SYMBOL_GPL(iio_channel_get_all);
507 
iio_channel_release_all(struct iio_channel * channels)508 void iio_channel_release_all(struct iio_channel *channels)
509 {
510 	struct iio_channel *chan = &channels[0];
511 
512 	while (chan->indio_dev) {
513 		iio_device_put(chan->indio_dev);
514 		chan++;
515 	}
516 	kfree(channels);
517 }
518 EXPORT_SYMBOL_GPL(iio_channel_release_all);
519 
devm_iio_channel_free_all(void * iio_channels)520 static void devm_iio_channel_free_all(void *iio_channels)
521 {
522 	iio_channel_release_all(iio_channels);
523 }
524 
devm_iio_channel_get_all(struct device * dev)525 struct iio_channel *devm_iio_channel_get_all(struct device *dev)
526 {
527 	struct iio_channel *channels;
528 	int ret;
529 
530 	channels = iio_channel_get_all(dev);
531 	if (IS_ERR(channels))
532 		return channels;
533 
534 	ret = devm_add_action_or_reset(dev, devm_iio_channel_free_all,
535 				       channels);
536 	if (ret)
537 		return ERR_PTR(ret);
538 
539 	return channels;
540 }
541 EXPORT_SYMBOL_GPL(devm_iio_channel_get_all);
542 
iio_channel_read(struct iio_channel * chan,int * val,int * val2,enum iio_chan_info_enum info)543 static int iio_channel_read(struct iio_channel *chan, int *val, int *val2,
544 			    enum iio_chan_info_enum info)
545 {
546 	const struct iio_info *iio_info = chan->indio_dev->info;
547 	int unused;
548 	int vals[INDIO_MAX_RAW_ELEMENTS];
549 	int ret;
550 	int val_len = 2;
551 
552 	if (!val2)
553 		val2 = &unused;
554 
555 	if (!iio_channel_has_info(chan->channel, info))
556 		return -EINVAL;
557 
558 	if (iio_info->read_raw_multi) {
559 		ret = iio_info->read_raw_multi(chan->indio_dev,
560 					       chan->channel,
561 					       INDIO_MAX_RAW_ELEMENTS,
562 					       vals, &val_len, info);
563 		*val = vals[0];
564 		*val2 = vals[1];
565 	} else if (iio_info->read_raw) {
566 		ret = iio_info->read_raw(chan->indio_dev,
567 					 chan->channel, val, val2, info);
568 	} else {
569 		return -EINVAL;
570 	}
571 
572 	return ret;
573 }
574 
iio_read_channel_raw(struct iio_channel * chan,int * val)575 int iio_read_channel_raw(struct iio_channel *chan, int *val)
576 {
577 	struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev);
578 
579 	guard(mutex)(&iio_dev_opaque->info_exist_lock);
580 	if (!chan->indio_dev->info)
581 		return -ENODEV;
582 
583 	return iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW);
584 }
585 EXPORT_SYMBOL_GPL(iio_read_channel_raw);
586 
iio_read_channel_average_raw(struct iio_channel * chan,int * val)587 int iio_read_channel_average_raw(struct iio_channel *chan, int *val)
588 {
589 	struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev);
590 
591 	guard(mutex)(&iio_dev_opaque->info_exist_lock);
592 	if (!chan->indio_dev->info)
593 		return -ENODEV;
594 
595 	return iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_AVERAGE_RAW);
596 }
597 EXPORT_SYMBOL_GPL(iio_read_channel_average_raw);
598 
iio_convert_raw_to_processed_unlocked(struct iio_channel * chan,int raw,int * processed,unsigned int scale)599 static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
600 						 int raw, int *processed,
601 						 unsigned int scale)
602 {
603 	int scale_type, scale_val, scale_val2;
604 	int offset_type, offset_val, offset_val2;
605 	s64 raw64 = raw;
606 
607 	offset_type = iio_channel_read(chan, &offset_val, &offset_val2,
608 				       IIO_CHAN_INFO_OFFSET);
609 	if (offset_type >= 0) {
610 		switch (offset_type) {
611 		case IIO_VAL_INT:
612 			break;
613 		case IIO_VAL_INT_PLUS_MICRO:
614 		case IIO_VAL_INT_PLUS_NANO:
615 			/*
616 			 * Both IIO_VAL_INT_PLUS_MICRO and IIO_VAL_INT_PLUS_NANO
617 			 * implicitely truncate the offset to it's integer form.
618 			 */
619 			break;
620 		case IIO_VAL_FRACTIONAL:
621 			offset_val /= offset_val2;
622 			break;
623 		case IIO_VAL_FRACTIONAL_LOG2:
624 			offset_val >>= offset_val2;
625 			break;
626 		default:
627 			return -EINVAL;
628 		}
629 
630 		raw64 += offset_val;
631 	}
632 
633 	scale_type = iio_channel_read(chan, &scale_val, &scale_val2,
634 				      IIO_CHAN_INFO_SCALE);
635 	if (scale_type < 0) {
636 		/*
637 		 * If no channel scaling is available apply consumer scale to
638 		 * raw value and return.
639 		 */
640 		*processed = raw * scale;
641 		return 0;
642 	}
643 
644 	switch (scale_type) {
645 	case IIO_VAL_INT:
646 		*processed = raw64 * scale_val * scale;
647 		break;
648 	case IIO_VAL_INT_PLUS_MICRO:
649 		if (scale_val2 < 0)
650 			*processed = -raw64 * scale_val * scale;
651 		else
652 			*processed = raw64 * scale_val * scale;
653 		*processed += div_s64(raw64 * (s64)scale_val2 * scale,
654 				      1000000LL);
655 		break;
656 	case IIO_VAL_INT_PLUS_NANO:
657 		if (scale_val2 < 0)
658 			*processed = -raw64 * scale_val * scale;
659 		else
660 			*processed = raw64 * scale_val * scale;
661 		*processed += div_s64(raw64 * (s64)scale_val2 * scale,
662 				      1000000000LL);
663 		break;
664 	case IIO_VAL_FRACTIONAL:
665 		*processed = div_s64(raw64 * (s64)scale_val * scale,
666 				     scale_val2);
667 		break;
668 	case IIO_VAL_FRACTIONAL_LOG2:
669 		*processed = (raw64 * (s64)scale_val * scale) >> scale_val2;
670 		break;
671 	default:
672 		return -EINVAL;
673 	}
674 
675 	return 0;
676 }
677 
iio_convert_raw_to_processed(struct iio_channel * chan,int raw,int * processed,unsigned int scale)678 int iio_convert_raw_to_processed(struct iio_channel *chan, int raw,
679 				 int *processed, unsigned int scale)
680 {
681 	struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev);
682 
683 	guard(mutex)(&iio_dev_opaque->info_exist_lock);
684 	if (!chan->indio_dev->info)
685 		return -ENODEV;
686 
687 	return iio_convert_raw_to_processed_unlocked(chan, raw, processed,
688 						     scale);
689 }
690 EXPORT_SYMBOL_GPL(iio_convert_raw_to_processed);
691 
iio_read_channel_attribute(struct iio_channel * chan,int * val,int * val2,enum iio_chan_info_enum attribute)692 int iio_read_channel_attribute(struct iio_channel *chan, int *val, int *val2,
693 			       enum iio_chan_info_enum attribute)
694 {
695 	struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev);
696 
697 	guard(mutex)(&iio_dev_opaque->info_exist_lock);
698 	if (!chan->indio_dev->info)
699 		return -ENODEV;
700 
701 	return iio_channel_read(chan, val, val2, attribute);
702 }
703 EXPORT_SYMBOL_GPL(iio_read_channel_attribute);
704 
iio_read_channel_offset(struct iio_channel * chan,int * val,int * val2)705 int iio_read_channel_offset(struct iio_channel *chan, int *val, int *val2)
706 {
707 	return iio_read_channel_attribute(chan, val, val2, IIO_CHAN_INFO_OFFSET);
708 }
709 EXPORT_SYMBOL_GPL(iio_read_channel_offset);
710 
iio_read_channel_processed_scale(struct iio_channel * chan,int * val,unsigned int scale)711 int iio_read_channel_processed_scale(struct iio_channel *chan, int *val,
712 				     unsigned int scale)
713 {
714 	struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev);
715 	int ret;
716 
717 	guard(mutex)(&iio_dev_opaque->info_exist_lock);
718 	if (!chan->indio_dev->info)
719 		return -ENODEV;
720 
721 	if (iio_channel_has_info(chan->channel, IIO_CHAN_INFO_PROCESSED)) {
722 		ret = iio_channel_read(chan, val, NULL,
723 				       IIO_CHAN_INFO_PROCESSED);
724 		if (ret < 0)
725 			return ret;
726 		*val *= scale;
727 
728 		return ret;
729 	} else {
730 		ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW);
731 		if (ret < 0)
732 			return ret;
733 
734 		return iio_convert_raw_to_processed_unlocked(chan, *val, val,
735 							     scale);
736 	}
737 }
738 EXPORT_SYMBOL_GPL(iio_read_channel_processed_scale);
739 
iio_read_channel_processed(struct iio_channel * chan,int * val)740 int iio_read_channel_processed(struct iio_channel *chan, int *val)
741 {
742 	/* This is just a special case with scale factor 1 */
743 	return iio_read_channel_processed_scale(chan, val, 1);
744 }
745 EXPORT_SYMBOL_GPL(iio_read_channel_processed);
746 
iio_read_channel_scale(struct iio_channel * chan,int * val,int * val2)747 int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2)
748 {
749 	return iio_read_channel_attribute(chan, val, val2, IIO_CHAN_INFO_SCALE);
750 }
751 EXPORT_SYMBOL_GPL(iio_read_channel_scale);
752 
iio_channel_read_avail(struct iio_channel * chan,const int ** vals,int * type,int * length,enum iio_chan_info_enum info)753 static int iio_channel_read_avail(struct iio_channel *chan,
754 				  const int **vals, int *type, int *length,
755 				  enum iio_chan_info_enum info)
756 {
757 	const struct iio_info *iio_info = chan->indio_dev->info;
758 
759 	if (!iio_channel_has_available(chan->channel, info))
760 		return -EINVAL;
761 
762 	if (iio_info->read_avail)
763 		return iio_info->read_avail(chan->indio_dev, chan->channel,
764 					    vals, type, length, info);
765 	return -EINVAL;
766 }
767 
iio_read_avail_channel_attribute(struct iio_channel * chan,const int ** vals,int * type,int * length,enum iio_chan_info_enum attribute)768 int iio_read_avail_channel_attribute(struct iio_channel *chan,
769 				     const int **vals, int *type, int *length,
770 				     enum iio_chan_info_enum attribute)
771 {
772 	struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev);
773 
774 	guard(mutex)(&iio_dev_opaque->info_exist_lock);
775 	if (!chan->indio_dev->info)
776 		return -ENODEV;
777 
778 	return iio_channel_read_avail(chan, vals, type, length, attribute);
779 }
780 EXPORT_SYMBOL_GPL(iio_read_avail_channel_attribute);
781 
iio_read_avail_channel_raw(struct iio_channel * chan,const int ** vals,int * length)782 int iio_read_avail_channel_raw(struct iio_channel *chan,
783 			       const int **vals, int *length)
784 {
785 	int ret;
786 	int type;
787 
788 	ret = iio_read_avail_channel_attribute(chan, vals, &type, length,
789 					       IIO_CHAN_INFO_RAW);
790 
791 	if (ret >= 0 && type != IIO_VAL_INT)
792 		/* raw values are assumed to be IIO_VAL_INT */
793 		ret = -EINVAL;
794 
795 	return ret;
796 }
797 EXPORT_SYMBOL_GPL(iio_read_avail_channel_raw);
798 
iio_channel_read_max(struct iio_channel * chan,int * val,int * val2,int * type,enum iio_chan_info_enum info)799 static int iio_channel_read_max(struct iio_channel *chan,
800 				int *val, int *val2, int *type,
801 				enum iio_chan_info_enum info)
802 {
803 	const int *vals;
804 	int length;
805 	int ret;
806 
807 	ret = iio_channel_read_avail(chan, &vals, type, &length, info);
808 	if (ret < 0)
809 		return ret;
810 
811 	switch (ret) {
812 	case IIO_AVAIL_RANGE:
813 		switch (*type) {
814 		case IIO_VAL_INT:
815 			*val = vals[2];
816 			break;
817 		default:
818 			*val = vals[4];
819 			if (val2)
820 				*val2 = vals[5];
821 		}
822 		return 0;
823 
824 	case IIO_AVAIL_LIST:
825 		if (length <= 0)
826 			return -EINVAL;
827 		switch (*type) {
828 		case IIO_VAL_INT:
829 			*val = max_array(vals, length);
830 			break;
831 		default:
832 			/* TODO: learn about max for other iio values */
833 			return -EINVAL;
834 		}
835 		return 0;
836 
837 	default:
838 		return -EINVAL;
839 	}
840 }
841 
iio_read_max_channel_raw(struct iio_channel * chan,int * val)842 int iio_read_max_channel_raw(struct iio_channel *chan, int *val)
843 {
844 	struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev);
845 	int type;
846 
847 	guard(mutex)(&iio_dev_opaque->info_exist_lock);
848 	if (!chan->indio_dev->info)
849 		return -ENODEV;
850 
851 	return iio_channel_read_max(chan, val, NULL, &type, IIO_CHAN_INFO_RAW);
852 }
853 EXPORT_SYMBOL_GPL(iio_read_max_channel_raw);
854 
iio_channel_read_min(struct iio_channel * chan,int * val,int * val2,int * type,enum iio_chan_info_enum info)855 static int iio_channel_read_min(struct iio_channel *chan,
856 				int *val, int *val2, int *type,
857 				enum iio_chan_info_enum info)
858 {
859 	const int *vals;
860 	int length;
861 	int ret;
862 
863 	ret = iio_channel_read_avail(chan, &vals, type, &length, info);
864 	if (ret < 0)
865 		return ret;
866 
867 	switch (ret) {
868 	case IIO_AVAIL_RANGE:
869 		switch (*type) {
870 		case IIO_VAL_INT:
871 			*val = vals[0];
872 			break;
873 		default:
874 			*val = vals[0];
875 			if (val2)
876 				*val2 = vals[1];
877 		}
878 		return 0;
879 
880 	case IIO_AVAIL_LIST:
881 		if (length <= 0)
882 			return -EINVAL;
883 		switch (*type) {
884 		case IIO_VAL_INT:
885 			*val = min_array(vals, length);
886 			break;
887 		default:
888 			/* TODO: learn about min for other iio values */
889 			return -EINVAL;
890 		}
891 		return 0;
892 
893 	default:
894 		return -EINVAL;
895 	}
896 }
897 
iio_read_min_channel_raw(struct iio_channel * chan,int * val)898 int iio_read_min_channel_raw(struct iio_channel *chan, int *val)
899 {
900 	struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev);
901 	int type;
902 
903 	guard(mutex)(&iio_dev_opaque->info_exist_lock);
904 	if (!chan->indio_dev->info)
905 		return -ENODEV;
906 
907 	return iio_channel_read_min(chan, val, NULL, &type, IIO_CHAN_INFO_RAW);
908 }
909 EXPORT_SYMBOL_GPL(iio_read_min_channel_raw);
910 
iio_get_channel_type(struct iio_channel * chan,enum iio_chan_type * type)911 int iio_get_channel_type(struct iio_channel *chan, enum iio_chan_type *type)
912 {
913 	struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev);
914 
915 	guard(mutex)(&iio_dev_opaque->info_exist_lock);
916 	if (!chan->indio_dev->info)
917 		return -ENODEV;
918 
919 	*type = chan->channel->type;
920 
921 	return 0;
922 }
923 EXPORT_SYMBOL_GPL(iio_get_channel_type);
924 
iio_channel_write(struct iio_channel * chan,int val,int val2,enum iio_chan_info_enum info)925 static int iio_channel_write(struct iio_channel *chan, int val, int val2,
926 			     enum iio_chan_info_enum info)
927 {
928 	const struct iio_info *iio_info = chan->indio_dev->info;
929 
930 	if (iio_info->write_raw)
931 		return iio_info->write_raw(chan->indio_dev,
932 					   chan->channel, val, val2, info);
933 	return -EINVAL;
934 }
935 
iio_write_channel_attribute(struct iio_channel * chan,int val,int val2,enum iio_chan_info_enum attribute)936 int iio_write_channel_attribute(struct iio_channel *chan, int val, int val2,
937 				enum iio_chan_info_enum attribute)
938 {
939 	struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev);
940 
941 	guard(mutex)(&iio_dev_opaque->info_exist_lock);
942 	if (!chan->indio_dev->info)
943 		return -ENODEV;
944 
945 	return iio_channel_write(chan, val, val2, attribute);
946 }
947 EXPORT_SYMBOL_GPL(iio_write_channel_attribute);
948 
iio_write_channel_raw(struct iio_channel * chan,int val)949 int iio_write_channel_raw(struct iio_channel *chan, int val)
950 {
951 	return iio_write_channel_attribute(chan, val, 0, IIO_CHAN_INFO_RAW);
952 }
953 EXPORT_SYMBOL_GPL(iio_write_channel_raw);
954 
iio_get_channel_ext_info_count(struct iio_channel * chan)955 unsigned int iio_get_channel_ext_info_count(struct iio_channel *chan)
956 {
957 	const struct iio_chan_spec_ext_info *ext_info;
958 	unsigned int i = 0;
959 
960 	if (!chan->channel->ext_info)
961 		return i;
962 
963 	for (ext_info = chan->channel->ext_info; ext_info->name; ext_info++)
964 		++i;
965 
966 	return i;
967 }
968 EXPORT_SYMBOL_GPL(iio_get_channel_ext_info_count);
969 
970 static const struct iio_chan_spec_ext_info *
iio_lookup_ext_info(const struct iio_channel * chan,const char * attr)971 iio_lookup_ext_info(const struct iio_channel *chan, const char *attr)
972 {
973 	const struct iio_chan_spec_ext_info *ext_info;
974 
975 	if (!chan->channel->ext_info)
976 		return NULL;
977 
978 	for (ext_info = chan->channel->ext_info; ext_info->name; ++ext_info) {
979 		if (!strcmp(attr, ext_info->name))
980 			return ext_info;
981 	}
982 
983 	return NULL;
984 }
985 
iio_read_channel_ext_info(struct iio_channel * chan,const char * attr,char * buf)986 ssize_t iio_read_channel_ext_info(struct iio_channel *chan,
987 				  const char *attr, char *buf)
988 {
989 	const struct iio_chan_spec_ext_info *ext_info;
990 
991 	ext_info = iio_lookup_ext_info(chan, attr);
992 	if (!ext_info)
993 		return -EINVAL;
994 
995 	return ext_info->read(chan->indio_dev, ext_info->private,
996 			      chan->channel, buf);
997 }
998 EXPORT_SYMBOL_GPL(iio_read_channel_ext_info);
999 
iio_write_channel_ext_info(struct iio_channel * chan,const char * attr,const char * buf,size_t len)1000 ssize_t iio_write_channel_ext_info(struct iio_channel *chan, const char *attr,
1001 				   const char *buf, size_t len)
1002 {
1003 	const struct iio_chan_spec_ext_info *ext_info;
1004 
1005 	ext_info = iio_lookup_ext_info(chan, attr);
1006 	if (!ext_info)
1007 		return -EINVAL;
1008 
1009 	return ext_info->write(chan->indio_dev, ext_info->private,
1010 			       chan->channel, buf, len);
1011 }
1012 EXPORT_SYMBOL_GPL(iio_write_channel_ext_info);
1013 
iio_read_channel_label(struct iio_channel * chan,char * buf)1014 ssize_t iio_read_channel_label(struct iio_channel *chan, char *buf)
1015 {
1016 	return do_iio_read_channel_label(chan->indio_dev, chan->channel, buf);
1017 }
1018 EXPORT_SYMBOL_GPL(iio_read_channel_label);
1019