1 /* 2 * STMicroelectronics sensors buffer 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/buffer.h> 18 #include <linux/iio/trigger_consumer.h> 19 #include <linux/iio/triggered_buffer.h> 20 #include <linux/irqreturn.h> 21 22 #include <linux/iio/common/st_sensors.h> 23 24 25 int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf) 26 { 27 int i, len; 28 int total = 0; 29 struct st_sensor_data *sdata = iio_priv(indio_dev); 30 unsigned int num_data_channels = sdata->num_data_channels; 31 32 for (i = 0; i < num_data_channels; i++) { 33 unsigned int bytes_to_read; 34 35 if (test_bit(i, indio_dev->active_scan_mask)) { 36 bytes_to_read = indio_dev->channels[i].scan_type.storagebits >> 3; 37 len = sdata->tf->read_multiple_byte(&sdata->tb, 38 sdata->dev, indio_dev->channels[i].address, 39 bytes_to_read, 40 buf + total, sdata->multiread_bit); 41 42 if (len < bytes_to_read) 43 return -EIO; 44 45 /* Advance the buffer pointer */ 46 total += len; 47 } 48 } 49 50 return total; 51 } 52 EXPORT_SYMBOL(st_sensors_get_buffer_element); 53 54 irqreturn_t st_sensors_trigger_handler(int irq, void *p) 55 { 56 int len; 57 struct iio_poll_func *pf = p; 58 struct iio_dev *indio_dev = pf->indio_dev; 59 struct st_sensor_data *sdata = iio_priv(indio_dev); 60 61 /* If we have a status register, check if this IRQ came from us */ 62 if (sdata->sensor_settings->drdy_irq.addr_stat_drdy) { 63 u8 status; 64 65 len = sdata->tf->read_byte(&sdata->tb, sdata->dev, 66 sdata->sensor_settings->drdy_irq.addr_stat_drdy, 67 &status); 68 if (len < 0) 69 dev_err(sdata->dev, "could not read channel status\n"); 70 71 /* 72 * If this was not caused by any channels on this sensor, 73 * return IRQ_NONE 74 */ 75 if (!(status & (u8)indio_dev->active_scan_mask[0])) 76 return IRQ_NONE; 77 } 78 79 len = st_sensors_get_buffer_element(indio_dev, sdata->buffer_data); 80 if (len < 0) 81 goto st_sensors_get_buffer_element_error; 82 83 iio_push_to_buffers_with_timestamp(indio_dev, sdata->buffer_data, 84 pf->timestamp); 85 86 st_sensors_get_buffer_element_error: 87 iio_trigger_notify_done(indio_dev->trig); 88 89 return IRQ_HANDLED; 90 } 91 EXPORT_SYMBOL(st_sensors_trigger_handler); 92 93 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); 94 MODULE_DESCRIPTION("STMicroelectronics ST-sensors buffer"); 95 MODULE_LICENSE("GPL v2"); 96