1 // SPDX-License-Identifier: GPL-2.0-only
3 * The industrial I/O periodic hrtimer trigger driver
5 * Copyright (C) Intuitive Aerial AB
6 * Written by Marten Svanfeldt, marten@intuitiveaerial.com
7 * Copyright (C) 2012, Analog Devices Inc.
8 * Author: Lars-Peter Clausen <lars@metafoo.de>
9 * Copyright (C) 2015, Intel Corporation
11 #include <linux/kernel.h>
12 #include <linux/slab.h>
13 #include <linux/hrtimer.h>
15 #include <linux/iio/iio.h>
16 #include <linux/iio/trigger.h>
17 #include <linux/iio/sw_trigger.h>
19 /* default sampling frequency - 100Hz */
20 #define HRTIMER_DEFAULT_SAMPLING_FREQUENCY 100
22 struct iio_hrtimer_info
{
23 struct iio_sw_trigger swt
;
25 unsigned long sampling_frequency
;
29 static const struct config_item_type iio_hrtimer_type
= {
30 .ct_owner
= THIS_MODULE
,
34 ssize_t
iio_hrtimer_show_sampling_frequency(struct device
*dev
,
35 struct device_attribute
*attr
,
38 struct iio_trigger
*trig
= to_iio_trigger(dev
);
39 struct iio_hrtimer_info
*info
= iio_trigger_get_drvdata(trig
);
41 return snprintf(buf
, PAGE_SIZE
, "%lu\n", info
->sampling_frequency
);
45 ssize_t
iio_hrtimer_store_sampling_frequency(struct device
*dev
,
46 struct device_attribute
*attr
,
47 const char *buf
, size_t len
)
49 struct iio_trigger
*trig
= to_iio_trigger(dev
);
50 struct iio_hrtimer_info
*info
= iio_trigger_get_drvdata(trig
);
54 ret
= kstrtoul(buf
, 10, &val
);
58 if (!val
|| val
> NSEC_PER_SEC
)
61 info
->sampling_frequency
= val
;
62 info
->period
= NSEC_PER_SEC
/ val
;
67 static DEVICE_ATTR(sampling_frequency
, S_IRUGO
| S_IWUSR
,
68 iio_hrtimer_show_sampling_frequency
,
69 iio_hrtimer_store_sampling_frequency
);
71 static struct attribute
*iio_hrtimer_attrs
[] = {
72 &dev_attr_sampling_frequency
.attr
,
76 static const struct attribute_group iio_hrtimer_attr_group
= {
77 .attrs
= iio_hrtimer_attrs
,
80 static const struct attribute_group
*iio_hrtimer_attr_groups
[] = {
81 &iio_hrtimer_attr_group
,
85 static enum hrtimer_restart
iio_hrtimer_trig_handler(struct hrtimer
*timer
)
87 struct iio_hrtimer_info
*info
;
89 info
= container_of(timer
, struct iio_hrtimer_info
, timer
);
91 hrtimer_forward_now(timer
, info
->period
);
92 iio_trigger_poll(info
->swt
.trigger
);
94 return HRTIMER_RESTART
;
97 static int iio_trig_hrtimer_set_state(struct iio_trigger
*trig
, bool state
)
99 struct iio_hrtimer_info
*trig_info
;
101 trig_info
= iio_trigger_get_drvdata(trig
);
104 hrtimer_start(&trig_info
->timer
, trig_info
->period
,
105 HRTIMER_MODE_REL_HARD
);
107 hrtimer_cancel(&trig_info
->timer
);
112 static const struct iio_trigger_ops iio_hrtimer_trigger_ops
= {
113 .set_trigger_state
= iio_trig_hrtimer_set_state
,
116 static struct iio_sw_trigger
*iio_trig_hrtimer_probe(const char *name
)
118 struct iio_hrtimer_info
*trig_info
;
121 trig_info
= kzalloc(sizeof(*trig_info
), GFP_KERNEL
);
123 return ERR_PTR(-ENOMEM
);
125 trig_info
->swt
.trigger
= iio_trigger_alloc("%s", name
);
126 if (!trig_info
->swt
.trigger
) {
128 goto err_free_trig_info
;
131 iio_trigger_set_drvdata(trig_info
->swt
.trigger
, trig_info
);
132 trig_info
->swt
.trigger
->ops
= &iio_hrtimer_trigger_ops
;
133 trig_info
->swt
.trigger
->dev
.groups
= iio_hrtimer_attr_groups
;
135 hrtimer_init(&trig_info
->timer
, CLOCK_MONOTONIC
, HRTIMER_MODE_REL_HARD
);
136 trig_info
->timer
.function
= iio_hrtimer_trig_handler
;
138 trig_info
->sampling_frequency
= HRTIMER_DEFAULT_SAMPLING_FREQUENCY
;
139 trig_info
->period
= NSEC_PER_SEC
/ trig_info
->sampling_frequency
;
141 ret
= iio_trigger_register(trig_info
->swt
.trigger
);
143 goto err_free_trigger
;
145 iio_swt_group_init_type_name(&trig_info
->swt
, name
, &iio_hrtimer_type
);
146 return &trig_info
->swt
;
148 iio_trigger_free(trig_info
->swt
.trigger
);
155 static int iio_trig_hrtimer_remove(struct iio_sw_trigger
*swt
)
157 struct iio_hrtimer_info
*trig_info
;
159 trig_info
= iio_trigger_get_drvdata(swt
->trigger
);
161 iio_trigger_unregister(swt
->trigger
);
163 /* cancel the timer after unreg to make sure no one rearms it */
164 hrtimer_cancel(&trig_info
->timer
);
165 iio_trigger_free(swt
->trigger
);
171 static const struct iio_sw_trigger_ops iio_trig_hrtimer_ops
= {
172 .probe
= iio_trig_hrtimer_probe
,
173 .remove
= iio_trig_hrtimer_remove
,
176 static struct iio_sw_trigger_type iio_trig_hrtimer
= {
178 .owner
= THIS_MODULE
,
179 .ops
= &iio_trig_hrtimer_ops
,
182 module_iio_sw_trigger_driver(iio_trig_hrtimer
);
184 MODULE_AUTHOR("Marten Svanfeldt <marten@intuitiveaerial.com>");
185 MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
186 MODULE_DESCRIPTION("Periodic hrtimer trigger for the IIO subsystem");
187 MODULE_LICENSE("GPL v2");