1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright 2017 Analog Devices Inc.
4 * Author: Lars-Peter Clausen <lars@metafoo.de>
8 #include <linux/export.h>
9 #include <linux/slab.h>
10 #include <linux/module.h>
12 #include <linux/iio/iio.h>
13 #include <linux/iio/consumer.h>
14 #include <linux/iio/hw-consumer.h>
15 #include <linux/iio/buffer_impl.h>
18 * struct iio_hw_consumer - IIO hw consumer block
19 * @buffers: hardware buffers list head.
20 * @channels: IIO provider channels.
22 struct iio_hw_consumer
{
23 struct list_head buffers
;
24 struct iio_channel
*channels
;
27 struct hw_consumer_buffer
{
28 struct list_head head
;
29 struct iio_dev
*indio_dev
;
30 struct iio_buffer buffer
;
34 static struct hw_consumer_buffer
*iio_buffer_to_hw_consumer_buffer(
35 struct iio_buffer
*buffer
)
37 return container_of(buffer
, struct hw_consumer_buffer
, buffer
);
40 static void iio_hw_buf_release(struct iio_buffer
*buffer
)
42 struct hw_consumer_buffer
*hw_buf
=
43 iio_buffer_to_hw_consumer_buffer(buffer
);
47 static const struct iio_buffer_access_funcs iio_hw_buf_access
= {
48 .release
= &iio_hw_buf_release
,
49 .modes
= INDIO_BUFFER_HARDWARE
,
52 static struct hw_consumer_buffer
*iio_hw_consumer_get_buffer(
53 struct iio_hw_consumer
*hwc
, struct iio_dev
*indio_dev
)
55 size_t mask_size
= BITS_TO_LONGS(indio_dev
->masklength
) * sizeof(long);
56 struct hw_consumer_buffer
*buf
;
58 list_for_each_entry(buf
, &hwc
->buffers
, head
) {
59 if (buf
->indio_dev
== indio_dev
)
63 buf
= kzalloc(sizeof(*buf
) + mask_size
, GFP_KERNEL
);
67 buf
->buffer
.access
= &iio_hw_buf_access
;
68 buf
->indio_dev
= indio_dev
;
69 buf
->buffer
.scan_mask
= buf
->scan_mask
;
71 iio_buffer_init(&buf
->buffer
);
72 list_add_tail(&buf
->head
, &hwc
->buffers
);
78 * iio_hw_consumer_alloc() - Allocate IIO hardware consumer
79 * @dev: Pointer to consumer device.
81 * Returns a valid iio_hw_consumer on success or a ERR_PTR() on failure.
83 struct iio_hw_consumer
*iio_hw_consumer_alloc(struct device
*dev
)
85 struct hw_consumer_buffer
*buf
;
86 struct iio_hw_consumer
*hwc
;
87 struct iio_channel
*chan
;
90 hwc
= kzalloc(sizeof(*hwc
), GFP_KERNEL
);
92 return ERR_PTR(-ENOMEM
);
94 INIT_LIST_HEAD(&hwc
->buffers
);
96 hwc
->channels
= iio_channel_get_all(dev
);
97 if (IS_ERR(hwc
->channels
)) {
98 ret
= PTR_ERR(hwc
->channels
);
102 chan
= &hwc
->channels
[0];
103 while (chan
->indio_dev
) {
104 buf
= iio_hw_consumer_get_buffer(hwc
, chan
->indio_dev
);
107 goto err_put_buffers
;
109 set_bit(chan
->channel
->scan_index
, buf
->buffer
.scan_mask
);
116 list_for_each_entry(buf
, &hwc
->buffers
, head
)
117 iio_buffer_put(&buf
->buffer
);
118 iio_channel_release_all(hwc
->channels
);
123 EXPORT_SYMBOL_GPL(iio_hw_consumer_alloc
);
126 * iio_hw_consumer_free() - Free IIO hardware consumer
127 * @hwc: hw consumer to free.
129 void iio_hw_consumer_free(struct iio_hw_consumer
*hwc
)
131 struct hw_consumer_buffer
*buf
, *n
;
133 iio_channel_release_all(hwc
->channels
);
134 list_for_each_entry_safe(buf
, n
, &hwc
->buffers
, head
)
135 iio_buffer_put(&buf
->buffer
);
138 EXPORT_SYMBOL_GPL(iio_hw_consumer_free
);
140 static void devm_iio_hw_consumer_release(struct device
*dev
, void *res
)
142 iio_hw_consumer_free(*(struct iio_hw_consumer
**)res
);
145 static int devm_iio_hw_consumer_match(struct device
*dev
, void *res
, void *data
)
147 struct iio_hw_consumer
**r
= res
;
157 * devm_iio_hw_consumer_alloc - Resource-managed iio_hw_consumer_alloc()
158 * @dev: Pointer to consumer device.
160 * Managed iio_hw_consumer_alloc. iio_hw_consumer allocated with this function
161 * is automatically freed on driver detach.
163 * If an iio_hw_consumer allocated with this function needs to be freed
164 * separately, devm_iio_hw_consumer_free() must be used.
166 * returns pointer to allocated iio_hw_consumer on success, NULL on failure.
168 struct iio_hw_consumer
*devm_iio_hw_consumer_alloc(struct device
*dev
)
170 struct iio_hw_consumer
**ptr
, *iio_hwc
;
172 ptr
= devres_alloc(devm_iio_hw_consumer_release
, sizeof(*ptr
),
177 iio_hwc
= iio_hw_consumer_alloc(dev
);
178 if (IS_ERR(iio_hwc
)) {
182 devres_add(dev
, ptr
);
187 EXPORT_SYMBOL_GPL(devm_iio_hw_consumer_alloc
);
190 * devm_iio_hw_consumer_free - Resource-managed iio_hw_consumer_free()
191 * @dev: Pointer to consumer device.
192 * @hwc: iio_hw_consumer to free.
194 * Free iio_hw_consumer allocated with devm_iio_hw_consumer_alloc().
196 void devm_iio_hw_consumer_free(struct device
*dev
, struct iio_hw_consumer
*hwc
)
200 rc
= devres_release(dev
, devm_iio_hw_consumer_release
,
201 devm_iio_hw_consumer_match
, hwc
);
204 EXPORT_SYMBOL_GPL(devm_iio_hw_consumer_free
);
207 * iio_hw_consumer_enable() - Enable IIO hardware consumer
208 * @hwc: iio_hw_consumer to enable.
210 * Returns 0 on success.
212 int iio_hw_consumer_enable(struct iio_hw_consumer
*hwc
)
214 struct hw_consumer_buffer
*buf
;
217 list_for_each_entry(buf
, &hwc
->buffers
, head
) {
218 ret
= iio_update_buffers(buf
->indio_dev
, &buf
->buffer
, NULL
);
220 goto err_disable_buffers
;
226 list_for_each_entry_continue_reverse(buf
, &hwc
->buffers
, head
)
227 iio_update_buffers(buf
->indio_dev
, NULL
, &buf
->buffer
);
230 EXPORT_SYMBOL_GPL(iio_hw_consumer_enable
);
233 * iio_hw_consumer_disable() - Disable IIO hardware consumer
234 * @hwc: iio_hw_consumer to disable.
236 void iio_hw_consumer_disable(struct iio_hw_consumer
*hwc
)
238 struct hw_consumer_buffer
*buf
;
240 list_for_each_entry(buf
, &hwc
->buffers
, head
)
241 iio_update_buffers(buf
->indio_dev
, NULL
, &buf
->buffer
);
243 EXPORT_SYMBOL_GPL(iio_hw_consumer_disable
);
245 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
246 MODULE_DESCRIPTION("Hardware consumer buffer the IIO framework");
247 MODULE_LICENSE("GPL v2");