1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved. 4 */ 5 6 #include <linux/iio/common/ssp_sensors.h> 7 #include <linux/iio/buffer.h> 8 #include <linux/iio/kfifo_buf.h> 9 #include <linux/module.h> 10 #include <linux/slab.h> 11 #include <linux/unaligned.h> 12 #include <linux/units.h> 13 #include "ssp_iio_sensor.h" 14 15 /** 16 * ssp_common_buffer_postenable() - generic postenable callback for ssp buffer 17 * 18 * @indio_dev: iio device 19 * 20 * Returns 0 or negative value in case of error 21 */ 22 int ssp_common_buffer_postenable(struct iio_dev *indio_dev) 23 { 24 struct ssp_sensor_data *spd = iio_priv(indio_dev); 25 struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent); 26 27 /* the allocation is made in post because scan size is known in this 28 * moment 29 * */ 30 spd->buffer = kmalloc(indio_dev->scan_bytes, GFP_KERNEL | GFP_DMA); 31 if (!spd->buffer) 32 return -ENOMEM; 33 34 return ssp_enable_sensor(data, spd->type, 35 ssp_get_sensor_delay(data, spd->type)); 36 } 37 EXPORT_SYMBOL_NS(ssp_common_buffer_postenable, "IIO_SSP_SENSORS"); 38 39 /** 40 * ssp_common_buffer_postdisable() - generic postdisable callback for ssp buffer 41 * 42 * @indio_dev: iio device 43 * 44 * Returns 0 or negative value in case of error 45 */ 46 int ssp_common_buffer_postdisable(struct iio_dev *indio_dev) 47 { 48 int ret; 49 struct ssp_sensor_data *spd = iio_priv(indio_dev); 50 struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent); 51 52 ret = ssp_disable_sensor(data, spd->type); 53 if (ret < 0) 54 return ret; 55 56 kfree(spd->buffer); 57 58 return ret; 59 } 60 EXPORT_SYMBOL_NS(ssp_common_buffer_postdisable, "IIO_SSP_SENSORS"); 61 62 /** 63 * ssp_common_process_data() - Common process data callback for ssp sensors 64 * 65 * @indio_dev: iio device 66 * @buf: source buffer 67 * @len: sensor data length 68 * @timestamp: system timestamp 69 * 70 * Returns 0 or negative value in case of error 71 */ 72 int ssp_common_process_data(struct iio_dev *indio_dev, void *buf, 73 unsigned int len, int64_t timestamp) 74 { 75 int64_t calculated_time; 76 struct ssp_sensor_data *spd = iio_priv(indio_dev); 77 78 if (indio_dev->scan_bytes == 0) 79 return 0; 80 81 /* 82 * it always sends full set of samples, remember about available masks 83 */ 84 memcpy(spd->buffer, buf, len); 85 86 calculated_time = timestamp + 87 (int64_t)get_unaligned_le32(buf + len) * MEGA; 88 89 return iio_push_to_buffers_with_timestamp(indio_dev, spd->buffer, 90 calculated_time); 91 } 92 EXPORT_SYMBOL_NS(ssp_common_process_data, "IIO_SSP_SENSORS"); 93 94 MODULE_AUTHOR("Karol Wrona <k.wrona@samsung.com>"); 95 MODULE_DESCRIPTION("Samsung sensorhub commons"); 96 MODULE_LICENSE("GPL"); 97 MODULE_IMPORT_NS("IIO_SSP_SENSORS"); 98