2 * Industrial I/O - gpio based trigger support
4 * Copyright (c) 2008 Jonathan Cameron
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
10 * Currently this is more of a functioning proof of concept than a full
11 * fledged trigger driver.
15 * Add board config elements to allow specification of startup settings.
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/platform_device.h>
21 #include <linux/interrupt.h>
22 #include <linux/gpio.h>
23 #include <linux/slab.h>
26 #include "../trigger.h"
28 static LIST_HEAD(iio_gpio_trigger_list
);
29 static DEFINE_MUTEX(iio_gpio_trigger_list_lock
);
31 struct iio_gpio_trigger_info
{
36 * Need to reference count these triggers and only enable gpio interrupts
40 /* So what functionality do we want in here?... */
41 /* set high / low as interrupt type? */
43 static irqreturn_t
iio_gpio_trigger_poll(int irq
, void *private)
45 /* Timestamp not currently provided */
46 iio_trigger_poll(private, 0);
50 static const struct iio_trigger_ops iio_gpio_trigger_ops
= {
54 static int iio_gpio_trigger_probe(struct platform_device
*pdev
)
56 struct iio_gpio_trigger_info
*trig_info
;
57 struct iio_trigger
*trig
, *trig2
;
58 unsigned long irqflags
;
59 struct resource
*irq_res
;
60 int irq
, ret
= 0, irq_res_cnt
= 0;
63 irq_res
= platform_get_resource(pdev
,
64 IORESOURCE_IRQ
, irq_res_cnt
);
66 if (irq_res
== NULL
) {
68 dev_err(&pdev
->dev
, "No GPIO IRQs specified");
71 irqflags
= (irq_res
->flags
& IRQF_TRIGGER_MASK
) | IRQF_SHARED
;
73 for (irq
= irq_res
->start
; irq
<= irq_res
->end
; irq
++) {
75 trig
= iio_allocate_trigger("irqtrig%d", irq
);
78 goto error_free_completed_registrations
;
81 trig_info
= kzalloc(sizeof(*trig_info
), GFP_KERNEL
);
84 goto error_put_trigger
;
86 trig
->private_data
= trig_info
;
88 trig
->ops
= &iio_gpio_trigger_ops
;
89 ret
= request_irq(irq
, iio_gpio_trigger_poll
,
90 irqflags
, trig
->name
, trig
);
93 "request IRQ-%d failed", irq
);
94 goto error_free_trig_info
;
97 ret
= iio_trigger_register(trig
);
99 goto error_release_irq
;
101 list_add_tail(&trig
->alloc_list
,
102 &iio_gpio_trigger_list
);
106 } while (irq_res
!= NULL
);
111 /* First clean up the partly allocated trigger */
114 error_free_trig_info
:
117 iio_put_trigger(trig
);
118 error_free_completed_registrations
:
119 /* The rest should have been added to the iio_gpio_trigger_list */
120 list_for_each_entry_safe(trig
,
122 &iio_gpio_trigger_list
,
124 trig_info
= trig
->private_data
;
125 free_irq(gpio_to_irq(trig_info
->irq
), trig
);
127 iio_trigger_unregister(trig
);
133 static int iio_gpio_trigger_remove(struct platform_device
*pdev
)
135 struct iio_trigger
*trig
, *trig2
;
136 struct iio_gpio_trigger_info
*trig_info
;
138 mutex_lock(&iio_gpio_trigger_list_lock
);
139 list_for_each_entry_safe(trig
,
141 &iio_gpio_trigger_list
,
143 trig_info
= trig
->private_data
;
144 iio_trigger_unregister(trig
);
145 free_irq(trig_info
->irq
, trig
);
147 iio_put_trigger(trig
);
149 mutex_unlock(&iio_gpio_trigger_list_lock
);
154 static struct platform_driver iio_gpio_trigger_driver
= {
155 .probe
= iio_gpio_trigger_probe
,
156 .remove
= iio_gpio_trigger_remove
,
158 .name
= "iio_gpio_trigger",
159 .owner
= THIS_MODULE
,
163 static int __init
iio_gpio_trig_init(void)
165 return platform_driver_register(&iio_gpio_trigger_driver
);
167 module_init(iio_gpio_trig_init
);
169 static void __exit
iio_gpio_trig_exit(void)
171 platform_driver_unregister(&iio_gpio_trigger_driver
);
173 module_exit(iio_gpio_trig_exit
);
175 MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
176 MODULE_DESCRIPTION("Example gpio trigger for the iio subsystem");
177 MODULE_LICENSE("GPL v2");