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(void *iio_hwc
)
142 iio_hw_consumer_free(iio_hwc
);
146 * devm_iio_hw_consumer_alloc - Resource-managed iio_hw_consumer_alloc()
147 * @dev: Pointer to consumer device.
149 * Managed iio_hw_consumer_alloc. iio_hw_consumer allocated with this function
150 * is automatically freed on driver detach.
152 * returns pointer to allocated iio_hw_consumer on success, NULL on failure.
154 struct iio_hw_consumer
*devm_iio_hw_consumer_alloc(struct device
*dev
)
156 struct iio_hw_consumer
*iio_hwc
;
159 iio_hwc
= iio_hw_consumer_alloc(dev
);
163 ret
= devm_add_action_or_reset(dev
, devm_iio_hw_consumer_release
,
170 EXPORT_SYMBOL_GPL(devm_iio_hw_consumer_alloc
);
173 * iio_hw_consumer_enable() - Enable IIO hardware consumer
174 * @hwc: iio_hw_consumer to enable.
176 * Returns 0 on success.
178 int iio_hw_consumer_enable(struct iio_hw_consumer
*hwc
)
180 struct hw_consumer_buffer
*buf
;
183 list_for_each_entry(buf
, &hwc
->buffers
, head
) {
184 ret
= iio_update_buffers(buf
->indio_dev
, &buf
->buffer
, NULL
);
186 goto err_disable_buffers
;
192 list_for_each_entry_continue_reverse(buf
, &hwc
->buffers
, head
)
193 iio_update_buffers(buf
->indio_dev
, NULL
, &buf
->buffer
);
196 EXPORT_SYMBOL_GPL(iio_hw_consumer_enable
);
199 * iio_hw_consumer_disable() - Disable IIO hardware consumer
200 * @hwc: iio_hw_consumer to disable.
202 void iio_hw_consumer_disable(struct iio_hw_consumer
*hwc
)
204 struct hw_consumer_buffer
*buf
;
206 list_for_each_entry(buf
, &hwc
->buffers
, head
)
207 iio_update_buffers(buf
->indio_dev
, NULL
, &buf
->buffer
);
209 EXPORT_SYMBOL_GPL(iio_hw_consumer_disable
);
211 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
212 MODULE_DESCRIPTION("Hardware consumer buffer the IIO framework");
213 MODULE_LICENSE("GPL v2");