diff options
author | Karol Wrona <k.wrona@samsung.com> | 2015-01-28 09:05:52 -0500 |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2015-01-29 13:49:53 -0500 |
commit | 7e3a8b446b5afa53cf8d3287da286105684137ff (patch) | |
tree | 3bfadad509e35c6fe75647cd56e358dd709dfb3d /drivers/iio | |
parent | f04df4ebee932376a630e0a3be1703a2f678c60d (diff) |
iio: common: ssp_sensors: Add sensorhub iio commons
This patch adds common library for sensorhub iio drivers.
Signed-off-by: Karol Wrona <k.wrona@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio')
-rw-r--r-- | drivers/iio/common/ssp_sensors/Kconfig | 10 | ||||
-rw-r--r-- | drivers/iio/common/ssp_sensors/Makefile | 2 | ||||
-rw-r--r-- | drivers/iio/common/ssp_sensors/ssp_iio.c | 107 | ||||
-rw-r--r-- | drivers/iio/common/ssp_sensors/ssp_iio_sensor.h | 70 |
4 files changed, 189 insertions, 0 deletions
diff --git a/drivers/iio/common/ssp_sensors/Kconfig b/drivers/iio/common/ssp_sensors/Kconfig index 759b975e2b40..0ea4faf016d8 100644 --- a/drivers/iio/common/ssp_sensors/Kconfig +++ b/drivers/iio/common/ssp_sensors/Kconfig | |||
@@ -3,6 +3,16 @@ | |||
3 | # | 3 | # |
4 | menu "SSP Sensor Common" | 4 | menu "SSP Sensor Common" |
5 | 5 | ||
6 | config IIO_SSP_SENSORS_COMMONS | ||
7 | tristate "Commons for all SSP Sensor IIO drivers" | ||
8 | depends on IIO_SSP_SENSORHUB | ||
9 | select IIO_BUFFER | ||
10 | select IIO_KFIFO_BUF | ||
11 | help | ||
12 | Say yes here to build commons for SSP sensors. | ||
13 | To compile this as a module, choose M here: the module | ||
14 | will be called ssp_iio. | ||
15 | |||
6 | config IIO_SSP_SENSORHUB | 16 | config IIO_SSP_SENSORHUB |
7 | tristate "Samsung Sensorhub driver" | 17 | tristate "Samsung Sensorhub driver" |
8 | depends on SPI | 18 | depends on SPI |
diff --git a/drivers/iio/common/ssp_sensors/Makefile b/drivers/iio/common/ssp_sensors/Makefile index 07d3d6a6763b..1e0389eb0905 100644 --- a/drivers/iio/common/ssp_sensors/Makefile +++ b/drivers/iio/common/ssp_sensors/Makefile | |||
@@ -4,3 +4,5 @@ | |||
4 | 4 | ||
5 | sensorhub-objs := ssp_dev.o ssp_spi.o | 5 | sensorhub-objs := ssp_dev.o ssp_spi.o |
6 | obj-$(CONFIG_IIO_SSP_SENSORHUB) += sensorhub.o | 6 | obj-$(CONFIG_IIO_SSP_SENSORHUB) += sensorhub.o |
7 | |||
8 | obj-$(CONFIG_IIO_SSP_SENSORS_COMMONS) += ssp_iio.o | ||
diff --git a/drivers/iio/common/ssp_sensors/ssp_iio.c b/drivers/iio/common/ssp_sensors/ssp_iio.c new file mode 100644 index 000000000000..a3ae165f8d9f --- /dev/null +++ b/drivers/iio/common/ssp_sensors/ssp_iio.c | |||
@@ -0,0 +1,107 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/iio/common/ssp_sensors.h> | ||
17 | #include <linux/iio/kfifo_buf.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include "ssp_iio_sensor.h" | ||
21 | |||
22 | /** | ||
23 | * ssp_common_buffer_postenable() - generic postenable callback for ssp buffer | ||
24 | * | ||
25 | * @indio_dev: iio device | ||
26 | * | ||
27 | * Returns 0 or negative value in case of error | ||
28 | */ | ||
29 | int ssp_common_buffer_postenable(struct iio_dev *indio_dev) | ||
30 | { | ||
31 | struct ssp_sensor_data *spd = iio_priv(indio_dev); | ||
32 | struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent); | ||
33 | |||
34 | /* the allocation is made in post because scan size is known in this | ||
35 | * moment | ||
36 | * */ | ||
37 | spd->buffer = kmalloc(indio_dev->scan_bytes, GFP_KERNEL | GFP_DMA); | ||
38 | if (!spd->buffer) | ||
39 | return -ENOMEM; | ||
40 | |||
41 | return ssp_enable_sensor(data, spd->type, | ||
42 | ssp_get_sensor_delay(data, spd->type)); | ||
43 | } | ||
44 | EXPORT_SYMBOL(ssp_common_buffer_postenable); | ||
45 | |||
46 | /** | ||
47 | * ssp_common_buffer_postdisable() - generic postdisable callback for ssp buffer | ||
48 | * | ||
49 | * @indio_dev: iio device | ||
50 | * | ||
51 | * Returns 0 or negative value in case of error | ||
52 | */ | ||
53 | int ssp_common_buffer_postdisable(struct iio_dev *indio_dev) | ||
54 | { | ||
55 | int ret; | ||
56 | struct ssp_sensor_data *spd = iio_priv(indio_dev); | ||
57 | struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent); | ||
58 | |||
59 | ret = ssp_disable_sensor(data, spd->type); | ||
60 | if (ret < 0) | ||
61 | return ret; | ||
62 | |||
63 | kfree(spd->buffer); | ||
64 | |||
65 | return ret; | ||
66 | } | ||
67 | EXPORT_SYMBOL(ssp_common_buffer_postdisable); | ||
68 | |||
69 | /** | ||
70 | * ssp_common_process_data() - Common process data callback for ssp sensors | ||
71 | * | ||
72 | * @indio_dev: iio device | ||
73 | * @buf: source buffer | ||
74 | * @len: sensor data length | ||
75 | * @timestamp: system timestamp | ||
76 | * | ||
77 | * Returns 0 or negative value in case of error | ||
78 | */ | ||
79 | int ssp_common_process_data(struct iio_dev *indio_dev, void *buf, | ||
80 | unsigned int len, int64_t timestamp) | ||
81 | { | ||
82 | __le32 time; | ||
83 | int64_t calculated_time; | ||
84 | struct ssp_sensor_data *spd = iio_priv(indio_dev); | ||
85 | |||
86 | if (indio_dev->scan_bytes == 0) | ||
87 | return 0; | ||
88 | |||
89 | /* | ||
90 | * it always sends full set of samples, remember about available masks | ||
91 | */ | ||
92 | memcpy(spd->buffer, buf, len); | ||
93 | |||
94 | if (indio_dev->scan_timestamp) { | ||
95 | memcpy(&time, &((char *)buf)[len], SSP_TIME_SIZE); | ||
96 | calculated_time = | ||
97 | timestamp + (int64_t)le32_to_cpu(time) * 1000000; | ||
98 | } | ||
99 | |||
100 | return iio_push_to_buffers_with_timestamp(indio_dev, spd->buffer, | ||
101 | calculated_time); | ||
102 | } | ||
103 | EXPORT_SYMBOL(ssp_common_process_data); | ||
104 | |||
105 | MODULE_AUTHOR("Karol Wrona <k.wrona@samsung.com>"); | ||
106 | MODULE_DESCRIPTION("Samsung sensorhub commons"); | ||
107 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/iio/common/ssp_sensors/ssp_iio_sensor.h b/drivers/iio/common/ssp_sensors/ssp_iio_sensor.h new file mode 100644 index 000000000000..dda267c9bd2a --- /dev/null +++ b/drivers/iio/common/ssp_sensors/ssp_iio_sensor.h | |||
@@ -0,0 +1,70 @@ | |||
1 | #ifndef __SSP_IIO_SENSOR_H__ | ||
2 | #define __SSP_IIO_SENSOR_H__ | ||
3 | |||
4 | #define SSP_CHANNEL_AG(_type, _mod, _index) \ | ||
5 | { \ | ||
6 | .type = _type,\ | ||
7 | .modified = 1,\ | ||
8 | .channel2 = _mod,\ | ||
9 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ),\ | ||
10 | .scan_index = _index,\ | ||
11 | .scan_type = {\ | ||
12 | .sign = 's',\ | ||
13 | .realbits = 16,\ | ||
14 | .storagebits = 16,\ | ||
15 | .shift = 0,\ | ||
16 | .endianness = IIO_LE,\ | ||
17 | },\ | ||
18 | } | ||
19 | |||
20 | /* It is defined here as it is a mixed timestamp */ | ||
21 | #define SSP_CHAN_TIMESTAMP(_si) { \ | ||
22 | .type = IIO_TIMESTAMP, \ | ||
23 | .channel = -1, \ | ||
24 | .scan_index = _si, \ | ||
25 | .scan_type = { \ | ||
26 | .sign = 's', \ | ||
27 | .realbits = 64, \ | ||
28 | .storagebits = 64, \ | ||
29 | }, \ | ||
30 | } | ||
31 | |||
32 | #define SSP_MS_PER_S 1000 | ||
33 | #define SSP_INVERTED_SCALING_FACTOR 1000000ULL | ||
34 | |||
35 | #define SSP_FACTOR_WITH_MS \ | ||
36 | (SSP_INVERTED_SCALING_FACTOR * SSP_MS_PER_S) | ||
37 | |||
38 | int ssp_common_buffer_postenable(struct iio_dev *indio_dev); | ||
39 | |||
40 | int ssp_common_buffer_postdisable(struct iio_dev *indio_dev); | ||
41 | |||
42 | int ssp_common_process_data(struct iio_dev *indio_dev, void *buf, | ||
43 | unsigned int len, int64_t timestamp); | ||
44 | |||
45 | /* Converts time in ms to frequency */ | ||
46 | static inline void ssp_convert_to_freq(u32 time, int *integer_part, | ||
47 | int *fractional) | ||
48 | { | ||
49 | if (time == 0) { | ||
50 | *fractional = 0; | ||
51 | *integer_part = 0; | ||
52 | return; | ||
53 | } | ||
54 | |||
55 | *integer_part = SSP_FACTOR_WITH_MS / time; | ||
56 | *fractional = do_div(*integer_part, SSP_INVERTED_SCALING_FACTOR); | ||
57 | } | ||
58 | |||
59 | /* Converts frequency to time in ms */ | ||
60 | static inline int ssp_convert_to_time(int integer_part, int fractional) | ||
61 | { | ||
62 | u64 value; | ||
63 | |||
64 | value = integer_part * SSP_INVERTED_SCALING_FACTOR + fractional; | ||
65 | if (value == 0) | ||
66 | return 0; | ||
67 | |||
68 | return div_u64(SSP_FACTOR_WITH_MS, value); | ||
69 | } | ||
70 | #endif /* __SSP_IIO_SENSOR_H__ */ | ||