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 that a fully
11 * fledged trigger driver.
15 * Add board config elements to allow specification of startup settings.
16 * Add configuration settings (irq type etc)
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/platform_device.h>
22 #include <linux/interrupt.h>
23 #include <linux/gpio.h>
26 #include "../trigger.h"
28 LIST_HEAD(iio_gpio_trigger_list
);
29 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 iio_trigger_poll(private);
49 static DEVICE_ATTR(name
, S_IRUGO
, iio_trigger_read_name
, NULL
);
51 static struct attribute
*iio_gpio_trigger_attrs
[] = {
56 static const struct attribute_group iio_gpio_trigger_attr_group
= {
57 .attrs
= iio_gpio_trigger_attrs
,
60 static int iio_gpio_trigger_probe(struct platform_device
*dev
)
62 int *pdata
= dev
->dev
.platform_data
;
63 struct iio_gpio_trigger_info
*trig_info
;
64 struct iio_trigger
*trig
, *trig2
;
67 printk(KERN_ERR
"No IIO gpio trigger platform data found\n");
71 if (!gpio_is_valid(pdata
[i
]))
73 trig
= iio_allocate_trigger();
76 goto error_free_completed_registrations
;
79 trig_info
= kzalloc(sizeof(*trig_info
), GFP_KERNEL
);
82 goto error_put_trigger
;
84 trig
->control_attrs
= &iio_gpio_trigger_attr_group
;
85 trig
->private_data
= trig_info
;
86 trig_info
->gpio
= pdata
[i
];
87 trig
->owner
= THIS_MODULE
;
88 trig
->name
= kmalloc(IIO_TRIGGER_NAME_LENGTH
, GFP_KERNEL
);
91 goto error_free_trig_info
;
93 snprintf((char *)trig
->name
,
94 IIO_TRIGGER_NAME_LENGTH
,
97 ret
= gpio_request(trig_info
->gpio
, trig
->name
);
101 ret
= gpio_direction_input(trig_info
->gpio
);
103 goto error_release_gpio
;
105 irq
= gpio_to_irq(trig_info
->gpio
);
108 goto error_release_gpio
;
111 ret
= request_irq(irq
, iio_gpio_trigger_poll
,
116 goto error_release_gpio
;
118 ret
= iio_trigger_register(trig
);
120 goto error_release_irq
;
122 list_add_tail(&trig
->alloc_list
, &iio_gpio_trigger_list
);
127 /* First clean up the partly allocated trigger */
131 gpio_free(trig_info
->gpio
);
134 error_free_trig_info
:
137 iio_put_trigger(trig
);
138 error_free_completed_registrations
:
139 /* The rest should have been added to the iio_gpio_trigger_list */
140 list_for_each_entry_safe(trig
,
142 &iio_gpio_trigger_list
,
144 trig_info
= trig
->private_data
;
145 free_irq(gpio_to_irq(trig_info
->gpio
), trig
);
146 gpio_free(trig_info
->gpio
);
149 iio_trigger_unregister(trig
);
156 static int iio_gpio_trigger_remove(struct platform_device
*dev
)
158 struct iio_trigger
*trig
, *trig2
;
159 struct iio_gpio_trigger_info
*trig_info
;
161 mutex_lock(&iio_gpio_trigger_list_lock
);
162 list_for_each_entry_safe(trig
,
164 &iio_gpio_trigger_list
,
166 trig_info
= trig
->private_data
;
167 iio_trigger_unregister(trig
);
168 free_irq(gpio_to_irq(trig_info
->gpio
), trig
);
169 gpio_free(trig_info
->gpio
);
172 iio_put_trigger(trig
);
174 mutex_unlock(&iio_gpio_trigger_list_lock
);
179 static struct platform_driver iio_gpio_trigger_driver
= {
180 .probe
= iio_gpio_trigger_probe
,
181 .remove
= iio_gpio_trigger_remove
,
183 .name
= "iio_gpio_trigger",
184 .owner
= THIS_MODULE
,
188 static int __init
iio_gpio_trig_init(void)
190 return platform_driver_register(&iio_gpio_trigger_driver
);
192 module_init(iio_gpio_trig_init
);
194 static void __exit
iio_gpio_trig_exit(void)
196 platform_driver_unregister(&iio_gpio_trigger_driver
);
198 module_exit(iio_gpio_trig_exit
);
200 MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
201 MODULE_DESCRIPTION("Example gpio trigger for the iio subsystem");
202 MODULE_LICENSE("GPL v2");