aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio
diff options
context:
space:
mode:
authorKarol Wrona <k.wrona@samsung.com>2015-01-28 09:05:52 -0500
committerJonathan Cameron <jic23@kernel.org>2015-01-29 13:49:53 -0500
commit7e3a8b446b5afa53cf8d3287da286105684137ff (patch)
tree3bfadad509e35c6fe75647cd56e358dd709dfb3d /drivers/iio
parentf04df4ebee932376a630e0a3be1703a2f678c60d (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/Kconfig10
-rw-r--r--drivers/iio/common/ssp_sensors/Makefile2
-rw-r--r--drivers/iio/common/ssp_sensors/ssp_iio.c107
-rw-r--r--drivers/iio/common/ssp_sensors/ssp_iio_sensor.h70
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#
4menu "SSP Sensor Common" 4menu "SSP Sensor Common"
5 5
6config 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
6config IIO_SSP_SENSORHUB 16config 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
5sensorhub-objs := ssp_dev.o ssp_spi.o 5sensorhub-objs := ssp_dev.o ssp_spi.o
6obj-$(CONFIG_IIO_SSP_SENSORHUB) += sensorhub.o 6obj-$(CONFIG_IIO_SSP_SENSORHUB) += sensorhub.o
7
8obj-$(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 */
29int 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}
44EXPORT_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 */
53int 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}
67EXPORT_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 */
79int 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}
103EXPORT_SYMBOL(ssp_common_process_data);
104
105MODULE_AUTHOR("Karol Wrona <k.wrona@samsung.com>");
106MODULE_DESCRIPTION("Samsung sensorhub commons");
107MODULE_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
38int ssp_common_buffer_postenable(struct iio_dev *indio_dev);
39
40int ssp_common_buffer_postdisable(struct iio_dev *indio_dev);
41
42int 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 */
46static 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 */
60static 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__ */