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 "ssp_iio_sensor.h" 12 13 /** 14 * ssp_common_buffer_postenable() - generic postenable callback for ssp buffer 15 * 16 * @indio_dev: iio device 17 * 18 * Returns 0 or negative value in case of error 19 */ 20 int ssp_common_buffer_postenable(struct iio_dev *indio_dev) 21 { 22 struct ssp_sensor_data *spd = iio_priv(indio_dev); 23 struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent); 24 25 /* the allocation is made in post because scan size is known in this 26 * moment 27 * */ 28 spd->buffer = kmalloc(indio_dev->scan_bytes, GFP_KERNEL | GFP_DMA); 29 if (!spd->buffer) 30 return -ENOMEM; 31 32 return ssp_enable_sensor(data, spd->type, 33 ssp_get_sensor_delay(data, spd->type)); 34 } 35 EXPORT_SYMBOL(ssp_common_buffer_postenable); 36 37 /** 38 * ssp_common_buffer_postdisable() - generic postdisable callback for ssp buffer 39 * 40 * @indio_dev: iio device 41 * 42 * Returns 0 or negative value in case of error 43 */ 44 int ssp_common_buffer_postdisable(struct iio_dev *indio_dev) 45 { 46 int ret; 47 struct ssp_sensor_data *spd = iio_priv(indio_dev); 48 struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent); 49 50 ret = ssp_disable_sensor(data, spd->type); 51 if (ret < 0) 52 return ret; 53 54 kfree(spd->buffer); 55 56 return ret; 57 } 58 EXPORT_SYMBOL(ssp_common_buffer_postdisable); 59 60 /** 61 * ssp_common_process_data() - Common process data callback for ssp sensors 62 * 63 * @indio_dev: iio device 64 * @buf: source buffer 65 * @len: sensor data length 66 * @timestamp: system timestamp 67 * 68 * Returns 0 or negative value in case of error 69 */ 70 int ssp_common_process_data(struct iio_dev *indio_dev, void *buf, 71 unsigned int len, int64_t timestamp) 72 { 73 __le32 time; 74 int64_t calculated_time = 0; 75 struct ssp_sensor_data *spd = iio_priv(indio_dev); 76 77 if (indio_dev->scan_bytes == 0) 78 return 0; 79 80 /* 81 * it always sends full set of samples, remember about available masks 82 */ 83 memcpy(spd->buffer, buf, len); 84 85 if (indio_dev->scan_timestamp) { 86 memcpy(&time, &((char *)buf)[len], SSP_TIME_SIZE); 87 calculated_time = 88 timestamp + (int64_t)le32_to_cpu(time) * 1000000; 89 } 90 91 return iio_push_to_buffers_with_timestamp(indio_dev, spd->buffer, 92 calculated_time); 93 } 94 EXPORT_SYMBOL(ssp_common_process_data); 95 96 MODULE_AUTHOR("Karol Wrona <k.wrona@samsung.com>"); 97 MODULE_DESCRIPTION("Samsung sensorhub commons"); 98 MODULE_LICENSE("GPL"); 99