1 /* 2 * STMicroelectronics sensors trigger library driver 3 * 4 * Copyright 2012-2013 STMicroelectronics Inc. 5 * 6 * Denis Ciocca <denis.ciocca@st.com> 7 * 8 * Licensed under the GPL-2. 9 */ 10 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" 19 20 /** 21 * st_sensors_new_samples_available() - check if more samples came in 22 * returns: 23 * 0 - no new samples available 24 * 1 - new samples available 25 * negative - error or unknown 26 */ 27 static int st_sensors_new_samples_available(struct iio_dev *indio_dev, 28 struct st_sensor_data *sdata) 29 { 30 u8 status; 31 int ret; 32 33 /* How would I know if I can't check it? */ 34 if (!sdata->sensor_settings->drdy_irq.addr_stat_drdy) 35 return -EINVAL; 36 37 /* No scan mask, no interrupt */ 38 if (!indio_dev->active_scan_mask) 39 return 0; 40 41 ret = sdata->tf->read_byte(&sdata->tb, sdata->dev, 42 sdata->sensor_settings->drdy_irq.addr_stat_drdy, 43 &status); 44 if (ret < 0) { 45 dev_err(sdata->dev, 46 "error checking samples available\n"); 47 return ret; 48 } 49 /* 50 * the lower bits of .active_scan_mask[0] is directly mapped 51 * to the channels on the sensor: either bit 0 for 52 * one-dimensional sensors, or e.g. x,y,z for accelerometers, 53 * gyroscopes or magnetometers. No sensor use more than 3 54 * channels, so cut the other status bits here. 55 */ 56 status &= 0x07; 57 58 if (status & (u8)indio_dev->active_scan_mask[0]) 59 return 1; 60 61 return 0; 62 } 63 64 /** 65 * st_sensors_irq_handler() - top half of the IRQ-based triggers 66 * @irq: irq number 67 * @p: private handler data 68 */ 69 irqreturn_t st_sensors_irq_handler(int irq, void *p) 70 { 71 struct iio_trigger *trig = p; 72 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 73 struct st_sensor_data *sdata = iio_priv(indio_dev); 74 75 /* Get the time stamp as close in time as possible */ 76 sdata->hw_timestamp = iio_get_time_ns(indio_dev); 77 return IRQ_WAKE_THREAD; 78 } 79 80 /** 81 * st_sensors_irq_thread() - bottom half of the IRQ-based triggers 82 * @irq: irq number 83 * @p: private handler data 84 */ 85 irqreturn_t st_sensors_irq_thread(int irq, void *p) 86 { 87 struct iio_trigger *trig = p; 88 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 89 struct st_sensor_data *sdata = iio_priv(indio_dev); 90 91 /* 92 * If this trigger is backed by a hardware interrupt and we have a 93 * status register, check if this IRQ came from us. Notice that 94 * we will process also if st_sensors_new_samples_available() 95 * returns negative: if we can't check status, then poll 96 * unconditionally. 97 */ 98 if (sdata->hw_irq_trigger && 99 st_sensors_new_samples_available(indio_dev, sdata)) { 100 iio_trigger_poll_chained(p); 101 } else { 102 dev_dbg(sdata->dev, "spurious IRQ\n"); 103 return IRQ_NONE; 104 } 105 106 /* 107 * If we have proper level IRQs the handler will be re-entered if 108 * the line is still active, so return here and come back in through 109 * the top half if need be. 110 */ 111 if (!sdata->edge_irq) 112 return IRQ_HANDLED; 113 114 /* 115 * If we are using egde IRQs, new samples arrived while processing 116 * the IRQ and those may be missed unless we pick them here, so poll 117 * again. If the sensor delivery frequency is very high, this thread 118 * turns into a polled loop handler. 119 */ 120 while (sdata->hw_irq_trigger && 121 st_sensors_new_samples_available(indio_dev, sdata)) { 122 dev_dbg(sdata->dev, "more samples came in during polling\n"); 123 sdata->hw_timestamp = iio_get_time_ns(indio_dev); 124 iio_trigger_poll_chained(p); 125 } 126 127 return IRQ_HANDLED; 128 } 129 130 int st_sensors_allocate_trigger(struct iio_dev *indio_dev, 131 const struct iio_trigger_ops *trigger_ops) 132 { 133 int err, irq; 134 struct st_sensor_data *sdata = iio_priv(indio_dev); 135 unsigned long irq_trig; 136 137 sdata->trig = iio_trigger_alloc("%s-trigger", indio_dev->name); 138 if (sdata->trig == NULL) { 139 dev_err(&indio_dev->dev, "failed to allocate iio trigger.\n"); 140 return -ENOMEM; 141 } 142 143 iio_trigger_set_drvdata(sdata->trig, indio_dev); 144 sdata->trig->ops = trigger_ops; 145 sdata->trig->dev.parent = sdata->dev; 146 147 irq = sdata->get_irq_data_ready(indio_dev); 148 irq_trig = irqd_get_trigger_type(irq_get_irq_data(irq)); 149 /* 150 * If the IRQ is triggered on falling edge, we need to mark the 151 * interrupt as active low, if the hardware supports this. 152 */ 153 switch(irq_trig) { 154 case IRQF_TRIGGER_FALLING: 155 case IRQF_TRIGGER_LOW: 156 if (!sdata->sensor_settings->drdy_irq.addr_ihl) { 157 dev_err(&indio_dev->dev, 158 "falling/low specified for IRQ " 159 "but hardware only support rising/high: " 160 "will request rising/high\n"); 161 if (irq_trig == IRQF_TRIGGER_FALLING) 162 irq_trig = IRQF_TRIGGER_RISING; 163 if (irq_trig == IRQF_TRIGGER_LOW) 164 irq_trig = IRQF_TRIGGER_HIGH; 165 } else { 166 /* Set up INT active low i.e. falling edge */ 167 err = st_sensors_write_data_with_mask(indio_dev, 168 sdata->sensor_settings->drdy_irq.addr_ihl, 169 sdata->sensor_settings->drdy_irq.mask_ihl, 1); 170 if (err < 0) 171 goto iio_trigger_free; 172 dev_info(&indio_dev->dev, 173 "interrupts on the falling edge or " 174 "active low level\n"); 175 } 176 break; 177 case IRQF_TRIGGER_RISING: 178 dev_info(&indio_dev->dev, 179 "interrupts on the rising edge\n"); 180 break; 181 case IRQF_TRIGGER_HIGH: 182 dev_info(&indio_dev->dev, 183 "interrupts active high level\n"); 184 break; 185 default: 186 /* This is the most preferred mode, if possible */ 187 dev_err(&indio_dev->dev, 188 "unsupported IRQ trigger specified (%lx), enforce " 189 "rising edge\n", irq_trig); 190 irq_trig = IRQF_TRIGGER_RISING; 191 } 192 193 /* Tell the interrupt handler that we're dealing with edges */ 194 if (irq_trig == IRQF_TRIGGER_FALLING || 195 irq_trig == IRQF_TRIGGER_RISING) 196 sdata->edge_irq = true; 197 else 198 /* 199 * If we're not using edges (i.e. level interrupts) we 200 * just mask off the IRQ, handle one interrupt, then 201 * if the line is still low, we return to the 202 * interrupt handler top half again and start over. 203 */ 204 irq_trig |= IRQF_ONESHOT; 205 206 /* 207 * If the interrupt pin is Open Drain, by definition this 208 * means that the interrupt line may be shared with other 209 * peripherals. But to do this we also need to have a status 210 * register and mask to figure out if this sensor was firing 211 * the IRQ or not, so we can tell the interrupt handle that 212 * it was "our" interrupt. 213 */ 214 if (sdata->int_pin_open_drain && 215 sdata->sensor_settings->drdy_irq.addr_stat_drdy) 216 irq_trig |= IRQF_SHARED; 217 218 err = request_threaded_irq(sdata->get_irq_data_ready(indio_dev), 219 st_sensors_irq_handler, 220 st_sensors_irq_thread, 221 irq_trig, 222 sdata->trig->name, 223 sdata->trig); 224 if (err) { 225 dev_err(&indio_dev->dev, "failed to request trigger IRQ.\n"); 226 goto iio_trigger_free; 227 } 228 229 err = iio_trigger_register(sdata->trig); 230 if (err < 0) { 231 dev_err(&indio_dev->dev, "failed to register iio trigger.\n"); 232 goto iio_trigger_register_error; 233 } 234 indio_dev->trig = iio_trigger_get(sdata->trig); 235 236 return 0; 237 238 iio_trigger_register_error: 239 free_irq(sdata->get_irq_data_ready(indio_dev), sdata->trig); 240 iio_trigger_free: 241 iio_trigger_free(sdata->trig); 242 return err; 243 } 244 EXPORT_SYMBOL(st_sensors_allocate_trigger); 245 246 void st_sensors_deallocate_trigger(struct iio_dev *indio_dev) 247 { 248 struct st_sensor_data *sdata = iio_priv(indio_dev); 249 250 iio_trigger_unregister(sdata->trig); 251 free_irq(sdata->get_irq_data_ready(indio_dev), sdata->trig); 252 iio_trigger_free(sdata->trig); 253 } 254 EXPORT_SYMBOL(st_sensors_deallocate_trigger); 255 256 int st_sensors_validate_device(struct iio_trigger *trig, 257 struct iio_dev *indio_dev) 258 { 259 struct iio_dev *indio = iio_trigger_get_drvdata(trig); 260 261 if (indio != indio_dev) 262 return -EINVAL; 263 264 return 0; 265 } 266 EXPORT_SYMBOL(st_sensors_validate_device); 267 268 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); 269 MODULE_DESCRIPTION("STMicroelectronics ST-sensors trigger"); 270 MODULE_LICENSE("GPL v2"); 271