1 /* The industrial I/O periodic RTC trigger driver
3 * Copyright (c) 2008 Jonathan Cameron
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
9 * This is a heavily rewritten version of the periodic timer system in
10 * earlier version of industrialio. It supplies the same functionality
11 * but via a trigger rather than a specific periodic timer system.
14 #include <linux/platform_device.h>
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/slab.h>
18 #include <linux/rtc.h>
19 #include <linux/iio/iio.h>
20 #include <linux/iio/trigger.h>
22 static LIST_HEAD(iio_prtc_trigger_list
);
23 static DEFINE_MUTEX(iio_prtc_trigger_list_lock
);
25 struct iio_prtc_trigger_info
{
26 struct rtc_device
*rtc
;
27 unsigned int frequency
;
32 static int iio_trig_periodic_rtc_set_state(struct iio_trigger
*trig
, bool state
)
34 struct iio_prtc_trigger_info
*trig_info
= iio_trigger_get_drvdata(trig
);
37 if (trig_info
->frequency
== 0 && state
)
39 dev_dbg(&trig_info
->rtc
->dev
, "trigger frequency is %u\n",
40 trig_info
->frequency
);
41 ret
= rtc_irq_set_state(trig_info
->rtc
, &trig_info
->task
, state
);
43 trig_info
->state
= state
;
48 static ssize_t
iio_trig_periodic_read_freq(struct device
*dev
,
49 struct device_attribute
*attr
,
52 struct iio_trigger
*trig
= to_iio_trigger(dev
);
53 struct iio_prtc_trigger_info
*trig_info
= iio_trigger_get_drvdata(trig
);
55 return sprintf(buf
, "%u\n", trig_info
->frequency
);
58 static ssize_t
iio_trig_periodic_write_freq(struct device
*dev
,
59 struct device_attribute
*attr
,
63 struct iio_trigger
*trig
= to_iio_trigger(dev
);
64 struct iio_prtc_trigger_info
*trig_info
= iio_trigger_get_drvdata(trig
);
68 ret
= kstrtouint(buf
, 10, &val
);
73 ret
= rtc_irq_set_freq(trig_info
->rtc
, &trig_info
->task
, val
);
74 if (ret
== 0 && trig_info
->state
&& trig_info
->frequency
== 0)
75 ret
= rtc_irq_set_state(trig_info
->rtc
,
78 ret
= rtc_irq_set_state(trig_info
->rtc
, &trig_info
->task
, 0);
82 trig_info
->frequency
= val
;
90 static DEVICE_ATTR(frequency
, S_IRUGO
| S_IWUSR
,
91 iio_trig_periodic_read_freq
,
92 iio_trig_periodic_write_freq
);
94 static struct attribute
*iio_trig_prtc_attrs
[] = {
95 &dev_attr_frequency
.attr
,
99 static const struct attribute_group iio_trig_prtc_attr_group
= {
100 .attrs
= iio_trig_prtc_attrs
,
103 static const struct attribute_group
*iio_trig_prtc_attr_groups
[] = {
104 &iio_trig_prtc_attr_group
,
108 static void iio_prtc_trigger_poll(void *private_data
)
110 iio_trigger_poll(private_data
);
113 static const struct iio_trigger_ops iio_prtc_trigger_ops
= {
114 .owner
= THIS_MODULE
,
115 .set_trigger_state
= &iio_trig_periodic_rtc_set_state
,
118 static int iio_trig_periodic_rtc_probe(struct platform_device
*dev
)
120 char **pdata
= dev
->dev
.platform_data
;
121 struct iio_prtc_trigger_info
*trig_info
;
122 struct iio_trigger
*trig
, *trig2
;
129 trig
= iio_trigger_alloc("periodic%s", pdata
[i
]);
132 goto error_free_completed_registrations
;
134 list_add(&trig
->alloc_list
, &iio_prtc_trigger_list
);
136 trig_info
= kzalloc(sizeof(*trig_info
), GFP_KERNEL
);
139 goto error_put_trigger_and_remove_from_list
;
141 iio_trigger_set_drvdata(trig
, trig_info
);
142 trig
->ops
= &iio_prtc_trigger_ops
;
144 trig_info
->rtc
= rtc_class_open(pdata
[i
]);
145 if (!trig_info
->rtc
) {
147 goto error_free_trig_info
;
149 trig_info
->task
.func
= iio_prtc_trigger_poll
;
150 trig_info
->task
.private_data
= trig
;
151 ret
= rtc_irq_register(trig_info
->rtc
, &trig_info
->task
);
153 goto error_close_rtc
;
154 trig
->dev
.groups
= iio_trig_prtc_attr_groups
;
155 ret
= iio_trigger_register(trig
);
157 goto error_unregister_rtc_irq
;
160 error_unregister_rtc_irq
:
161 rtc_irq_unregister(trig_info
->rtc
, &trig_info
->task
);
163 rtc_class_close(trig_info
->rtc
);
164 error_free_trig_info
:
166 error_put_trigger_and_remove_from_list
:
167 list_del(&trig
->alloc_list
);
168 iio_trigger_put(trig
);
169 error_free_completed_registrations
:
170 list_for_each_entry_safe(trig
,
172 &iio_prtc_trigger_list
,
174 trig_info
= iio_trigger_get_drvdata(trig
);
175 rtc_irq_unregister(trig_info
->rtc
, &trig_info
->task
);
176 rtc_class_close(trig_info
->rtc
);
178 iio_trigger_unregister(trig
);
183 static int iio_trig_periodic_rtc_remove(struct platform_device
*dev
)
185 struct iio_trigger
*trig
, *trig2
;
186 struct iio_prtc_trigger_info
*trig_info
;
188 mutex_lock(&iio_prtc_trigger_list_lock
);
189 list_for_each_entry_safe(trig
,
191 &iio_prtc_trigger_list
,
193 trig_info
= iio_trigger_get_drvdata(trig
);
194 rtc_irq_unregister(trig_info
->rtc
, &trig_info
->task
);
195 rtc_class_close(trig_info
->rtc
);
197 iio_trigger_unregister(trig
);
199 mutex_unlock(&iio_prtc_trigger_list_lock
);
203 static struct platform_driver iio_trig_periodic_rtc_driver
= {
204 .probe
= iio_trig_periodic_rtc_probe
,
205 .remove
= iio_trig_periodic_rtc_remove
,
207 .name
= "iio_prtc_trigger",
211 module_platform_driver(iio_trig_periodic_rtc_driver
);
213 MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
214 MODULE_DESCRIPTION("Periodic realtime clock trigger for the iio subsystem");
215 MODULE_LICENSE("GPL v2");