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(dev: 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(size: indio_dev->scan_bytes, GFP_KERNEL | GFP_DMA); |
29 | if (!spd->buffer) |
30 | return -ENOMEM; |
31 | |
32 | return ssp_enable_sensor(data, type: spd->type, |
33 | delay: ssp_get_sensor_delay(data, spd->type)); |
34 | } |
35 | EXPORT_SYMBOL_NS(ssp_common_buffer_postenable, IIO_SSP_SENSORS); |
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(dev: indio_dev->dev.parent->parent); |
49 | |
50 | ret = ssp_disable_sensor(data, type: spd->type); |
51 | if (ret < 0) |
52 | return ret; |
53 | |
54 | kfree(objp: spd->buffer); |
55 | |
56 | return ret; |
57 | } |
58 | EXPORT_SYMBOL_NS(ssp_common_buffer_postdisable, IIO_SSP_SENSORS); |
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, data: spd->buffer, |
92 | timestamp: calculated_time); |
93 | } |
94 | EXPORT_SYMBOL_NS(ssp_common_process_data, IIO_SSP_SENSORS); |
95 | |
96 | MODULE_AUTHOR("Karol Wrona <k.wrona@samsung.com>" ); |
97 | MODULE_DESCRIPTION("Samsung sensorhub commons" ); |
98 | MODULE_LICENSE("GPL" ); |
99 | MODULE_IMPORT_NS(IIO_SSP_SENSORS); |
100 | |