2 * STMicroelectronics sensors trigger library driver
4 * Copyright 2012-2013 STMicroelectronics Inc.
6 * Denis Ciocca <denis.ciocca@st.com>
8 * Licensed under the GPL-2.
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/slab.h>
14 #include <linux/iio/iio.h>
15 #include <linux/iio/trigger.h>
16 #include <linux/interrupt.h>
17 #include <linux/iio/common/st_sensors.h>
18 #include "st_sensors_core.h"
21 * st_sensors_irq_handler() - top half of the IRQ-based triggers
23 * @p: private handler data
25 irqreturn_t
st_sensors_irq_handler(int irq
, void *p
)
27 struct iio_trigger
*trig
= p
;
28 struct iio_dev
*indio_dev
= iio_trigger_get_drvdata(trig
);
29 struct st_sensor_data
*sdata
= iio_priv(indio_dev
);
31 /* Get the time stamp as close in time as possible */
32 sdata
->hw_timestamp
= iio_get_time_ns();
33 return IRQ_WAKE_THREAD
;
37 * st_sensors_irq_thread() - bottom half of the IRQ-based triggers
39 * @p: private handler data
41 irqreturn_t
st_sensors_irq_thread(int irq
, void *p
)
43 struct iio_trigger
*trig
= p
;
44 struct iio_dev
*indio_dev
= iio_trigger_get_drvdata(trig
);
45 struct st_sensor_data
*sdata
= iio_priv(indio_dev
);
49 * If this trigger is backed by a hardware interrupt and we have a
50 * status register, check if this IRQ came from us
52 if (sdata
->sensor_settings
->drdy_irq
.addr_stat_drdy
) {
55 ret
= sdata
->tf
->read_byte(&sdata
->tb
, sdata
->dev
,
56 sdata
->sensor_settings
->drdy_irq
.addr_stat_drdy
,
59 dev_err(sdata
->dev
, "could not read channel status\n");
63 * the lower bits of .active_scan_mask[0] is directly mapped
64 * to the channels on the sensor: either bit 0 for
65 * one-dimensional sensors, or e.g. x,y,z for accelerometers,
66 * gyroscopes or magnetometers. No sensor use more than 3
67 * channels, so cut the other status bits here.
72 * If this was not caused by any channels on this sensor,
75 if (!indio_dev
->active_scan_mask
)
77 if (!(status
& (u8
)indio_dev
->active_scan_mask
[0]))
82 /* It's our IRQ: proceed to handle the register polling */
83 iio_trigger_poll_chained(p
);
87 int st_sensors_allocate_trigger(struct iio_dev
*indio_dev
,
88 const struct iio_trigger_ops
*trigger_ops
)
91 struct st_sensor_data
*sdata
= iio_priv(indio_dev
);
92 unsigned long irq_trig
;
94 sdata
->trig
= iio_trigger_alloc("%s-trigger", indio_dev
->name
);
95 if (sdata
->trig
== NULL
) {
96 dev_err(&indio_dev
->dev
, "failed to allocate iio trigger.\n");
100 iio_trigger_set_drvdata(sdata
->trig
, indio_dev
);
101 sdata
->trig
->ops
= trigger_ops
;
102 sdata
->trig
->dev
.parent
= sdata
->dev
;
104 irq
= sdata
->get_irq_data_ready(indio_dev
);
105 irq_trig
= irqd_get_trigger_type(irq_get_irq_data(irq
));
107 * If the IRQ is triggered on falling edge, we need to mark the
108 * interrupt as active low, if the hardware supports this.
110 if (irq_trig
== IRQF_TRIGGER_FALLING
) {
111 if (!sdata
->sensor_settings
->drdy_irq
.addr_ihl
) {
112 dev_err(&indio_dev
->dev
,
113 "falling edge specified for IRQ but hardware "
114 "only support rising edge, will request "
116 irq_trig
= IRQF_TRIGGER_RISING
;
118 /* Set up INT active low i.e. falling edge */
119 err
= st_sensors_write_data_with_mask(indio_dev
,
120 sdata
->sensor_settings
->drdy_irq
.addr_ihl
,
121 sdata
->sensor_settings
->drdy_irq
.mask_ihl
, 1);
123 goto iio_trigger_free
;
124 dev_info(&indio_dev
->dev
,
125 "interrupts on the falling edge\n");
127 } else if (irq_trig
== IRQF_TRIGGER_RISING
) {
128 dev_info(&indio_dev
->dev
,
129 "interrupts on the rising edge\n");
132 dev_err(&indio_dev
->dev
,
133 "unsupported IRQ trigger specified (%lx), only "
134 "rising and falling edges supported, enforce "
135 "rising edge\n", irq_trig
);
136 irq_trig
= IRQF_TRIGGER_RISING
;
140 * If the interrupt pin is Open Drain, by definition this
141 * means that the interrupt line may be shared with other
142 * peripherals. But to do this we also need to have a status
143 * register and mask to figure out if this sensor was firing
144 * the IRQ or not, so we can tell the interrupt handle that
145 * it was "our" interrupt.
147 if (sdata
->int_pin_open_drain
&&
148 sdata
->sensor_settings
->drdy_irq
.addr_stat_drdy
)
149 irq_trig
|= IRQF_SHARED
;
151 /* Let's create an interrupt thread masking the hard IRQ here */
152 irq_trig
|= IRQF_ONESHOT
;
154 err
= request_threaded_irq(sdata
->get_irq_data_ready(indio_dev
),
155 st_sensors_irq_handler
,
156 st_sensors_irq_thread
,
161 dev_err(&indio_dev
->dev
, "failed to request trigger IRQ.\n");
162 goto iio_trigger_free
;
165 err
= iio_trigger_register(sdata
->trig
);
167 dev_err(&indio_dev
->dev
, "failed to register iio trigger.\n");
168 goto iio_trigger_register_error
;
170 indio_dev
->trig
= iio_trigger_get(sdata
->trig
);
174 iio_trigger_register_error
:
175 free_irq(sdata
->get_irq_data_ready(indio_dev
), sdata
->trig
);
177 iio_trigger_free(sdata
->trig
);
180 EXPORT_SYMBOL(st_sensors_allocate_trigger
);
182 void st_sensors_deallocate_trigger(struct iio_dev
*indio_dev
)
184 struct st_sensor_data
*sdata
= iio_priv(indio_dev
);
186 iio_trigger_unregister(sdata
->trig
);
187 free_irq(sdata
->get_irq_data_ready(indio_dev
), sdata
->trig
);
188 iio_trigger_free(sdata
->trig
);
190 EXPORT_SYMBOL(st_sensors_deallocate_trigger
);
192 int st_sensors_validate_device(struct iio_trigger
*trig
,
193 struct iio_dev
*indio_dev
)
195 struct iio_dev
*indio
= iio_trigger_get_drvdata(trig
);
197 if (indio
!= indio_dev
)
202 EXPORT_SYMBOL(st_sensors_validate_device
);
204 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
205 MODULE_DESCRIPTION("STMicroelectronics ST-sensors trigger");
206 MODULE_LICENSE("GPL v2");