2 * The industrial I/O periodic hrtimer trigger driver
4 * Copyright (C) Intuitive Aerial AB
5 * Written by Marten Svanfeldt, marten@intuitiveaerial.com
6 * Copyright (C) 2012, Analog Device Inc.
7 * Author: Lars-Peter Clausen <lars@metafoo.de>
8 * Copyright (C) 2015, Intel Corporation
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published by
12 * the Free Software Foundation.
15 #include <linux/kernel.h>
16 #include <linux/slab.h>
17 #include <linux/hrtimer.h>
19 #include <linux/iio/iio.h>
20 #include <linux/iio/trigger.h>
21 #include <linux/iio/sw_trigger.h>
23 /* default sampling frequency - 100Hz */
24 #define HRTIMER_DEFAULT_SAMPLING_FREQUENCY 100
26 struct iio_hrtimer_info
{
27 struct iio_sw_trigger swt
;
29 unsigned long sampling_frequency
;
33 static struct config_item_type iio_hrtimer_type
= {
34 .ct_owner
= THIS_MODULE
,
38 ssize_t
iio_hrtimer_show_sampling_frequency(struct device
*dev
,
39 struct device_attribute
*attr
,
42 struct iio_trigger
*trig
= to_iio_trigger(dev
);
43 struct iio_hrtimer_info
*info
= iio_trigger_get_drvdata(trig
);
45 return snprintf(buf
, PAGE_SIZE
, "%lu\n", info
->sampling_frequency
);
49 ssize_t
iio_hrtimer_store_sampling_frequency(struct device
*dev
,
50 struct device_attribute
*attr
,
51 const char *buf
, size_t len
)
53 struct iio_trigger
*trig
= to_iio_trigger(dev
);
54 struct iio_hrtimer_info
*info
= iio_trigger_get_drvdata(trig
);
58 ret
= kstrtoul(buf
, 10, &val
);
62 if (!val
|| val
> NSEC_PER_SEC
)
65 info
->sampling_frequency
= val
;
66 info
->period
= ktime_set(0, NSEC_PER_SEC
/ val
);
71 static DEVICE_ATTR(sampling_frequency
, S_IRUGO
| S_IWUSR
,
72 iio_hrtimer_show_sampling_frequency
,
73 iio_hrtimer_store_sampling_frequency
);
75 static struct attribute
*iio_hrtimer_attrs
[] = {
76 &dev_attr_sampling_frequency
.attr
,
80 static const struct attribute_group iio_hrtimer_attr_group
= {
81 .attrs
= iio_hrtimer_attrs
,
84 static const struct attribute_group
*iio_hrtimer_attr_groups
[] = {
85 &iio_hrtimer_attr_group
,
89 static enum hrtimer_restart
iio_hrtimer_trig_handler(struct hrtimer
*timer
)
91 struct iio_hrtimer_info
*info
;
93 info
= container_of(timer
, struct iio_hrtimer_info
, timer
);
95 hrtimer_forward_now(timer
, info
->period
);
96 iio_trigger_poll(info
->swt
.trigger
);
98 return HRTIMER_RESTART
;
101 static int iio_trig_hrtimer_set_state(struct iio_trigger
*trig
, bool state
)
103 struct iio_hrtimer_info
*trig_info
;
105 trig_info
= iio_trigger_get_drvdata(trig
);
108 hrtimer_start(&trig_info
->timer
, trig_info
->period
,
111 hrtimer_cancel(&trig_info
->timer
);
116 static const struct iio_trigger_ops iio_hrtimer_trigger_ops
= {
117 .owner
= THIS_MODULE
,
118 .set_trigger_state
= iio_trig_hrtimer_set_state
,
121 static struct iio_sw_trigger
*iio_trig_hrtimer_probe(const char *name
)
123 struct iio_hrtimer_info
*trig_info
;
126 trig_info
= kzalloc(sizeof(*trig_info
), GFP_KERNEL
);
128 return ERR_PTR(-ENOMEM
);
130 trig_info
->swt
.trigger
= iio_trigger_alloc("%s", name
);
131 if (!trig_info
->swt
.trigger
) {
133 goto err_free_trig_info
;
136 iio_trigger_set_drvdata(trig_info
->swt
.trigger
, trig_info
);
137 trig_info
->swt
.trigger
->ops
= &iio_hrtimer_trigger_ops
;
138 trig_info
->swt
.trigger
->dev
.groups
= iio_hrtimer_attr_groups
;
140 hrtimer_init(&trig_info
->timer
, CLOCK_MONOTONIC
, HRTIMER_MODE_REL
);
141 trig_info
->timer
.function
= iio_hrtimer_trig_handler
;
143 trig_info
->sampling_frequency
= HRTIMER_DEFAULT_SAMPLING_FREQUENCY
;
144 trig_info
->period
= ktime_set(0, NSEC_PER_SEC
/
145 trig_info
->sampling_frequency
);
147 ret
= iio_trigger_register(trig_info
->swt
.trigger
);
149 goto err_free_trigger
;
151 iio_swt_group_init_type_name(&trig_info
->swt
, name
, &iio_hrtimer_type
);
152 return &trig_info
->swt
;
154 iio_trigger_free(trig_info
->swt
.trigger
);
161 static int iio_trig_hrtimer_remove(struct iio_sw_trigger
*swt
)
163 struct iio_hrtimer_info
*trig_info
;
165 trig_info
= iio_trigger_get_drvdata(swt
->trigger
);
167 iio_trigger_unregister(swt
->trigger
);
169 /* cancel the timer after unreg to make sure no one rearms it */
170 hrtimer_cancel(&trig_info
->timer
);
171 iio_trigger_free(swt
->trigger
);
177 static const struct iio_sw_trigger_ops iio_trig_hrtimer_ops
= {
178 .probe
= iio_trig_hrtimer_probe
,
179 .remove
= iio_trig_hrtimer_remove
,
182 static struct iio_sw_trigger_type iio_trig_hrtimer
= {
184 .owner
= THIS_MODULE
,
185 .ops
= &iio_trig_hrtimer_ops
,
188 module_iio_sw_trigger_driver(iio_trig_hrtimer
);
190 MODULE_AUTHOR("Marten Svanfeldt <marten@intuitiveaerial.com>");
191 MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
192 MODULE_DESCRIPTION("Periodic hrtimer trigger for the IIO subsystem");
193 MODULE_LICENSE("GPL v2");