mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-19 11:43:40 +00:00
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>
This commit is contained in:
parent
f04df4ebee
commit
7e3a8b446b
@ -3,6 +3,16 @@
|
||||
#
|
||||
menu "SSP Sensor Common"
|
||||
|
||||
config IIO_SSP_SENSORS_COMMONS
|
||||
tristate "Commons for all SSP Sensor IIO drivers"
|
||||
depends on IIO_SSP_SENSORHUB
|
||||
select IIO_BUFFER
|
||||
select IIO_KFIFO_BUF
|
||||
help
|
||||
Say yes here to build commons for SSP sensors.
|
||||
To compile this as a module, choose M here: the module
|
||||
will be called ssp_iio.
|
||||
|
||||
config IIO_SSP_SENSORHUB
|
||||
tristate "Samsung Sensorhub driver"
|
||||
depends on SPI
|
||||
|
@ -4,3 +4,5 @@
|
||||
|
||||
sensorhub-objs := ssp_dev.o ssp_spi.o
|
||||
obj-$(CONFIG_IIO_SSP_SENSORHUB) += sensorhub.o
|
||||
|
||||
obj-$(CONFIG_IIO_SSP_SENSORS_COMMONS) += ssp_iio.o
|
||||
|
107
drivers/iio/common/ssp_sensors/ssp_iio.c
Normal file
107
drivers/iio/common/ssp_sensors/ssp_iio.c
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/iio/common/ssp_sensors.h>
|
||||
#include <linux/iio/kfifo_buf.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include "ssp_iio_sensor.h"
|
||||
|
||||
/**
|
||||
* ssp_common_buffer_postenable() - generic postenable callback for ssp buffer
|
||||
*
|
||||
* @indio_dev: iio device
|
||||
*
|
||||
* Returns 0 or negative value in case of error
|
||||
*/
|
||||
int ssp_common_buffer_postenable(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct ssp_sensor_data *spd = iio_priv(indio_dev);
|
||||
struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
|
||||
|
||||
/* the allocation is made in post because scan size is known in this
|
||||
* moment
|
||||
* */
|
||||
spd->buffer = kmalloc(indio_dev->scan_bytes, GFP_KERNEL | GFP_DMA);
|
||||
if (!spd->buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
return ssp_enable_sensor(data, spd->type,
|
||||
ssp_get_sensor_delay(data, spd->type));
|
||||
}
|
||||
EXPORT_SYMBOL(ssp_common_buffer_postenable);
|
||||
|
||||
/**
|
||||
* ssp_common_buffer_postdisable() - generic postdisable callback for ssp buffer
|
||||
*
|
||||
* @indio_dev: iio device
|
||||
*
|
||||
* Returns 0 or negative value in case of error
|
||||
*/
|
||||
int ssp_common_buffer_postdisable(struct iio_dev *indio_dev)
|
||||
{
|
||||
int ret;
|
||||
struct ssp_sensor_data *spd = iio_priv(indio_dev);
|
||||
struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
|
||||
|
||||
ret = ssp_disable_sensor(data, spd->type);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
kfree(spd->buffer);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(ssp_common_buffer_postdisable);
|
||||
|
||||
/**
|
||||
* ssp_common_process_data() - Common process data callback for ssp sensors
|
||||
*
|
||||
* @indio_dev: iio device
|
||||
* @buf: source buffer
|
||||
* @len: sensor data length
|
||||
* @timestamp: system timestamp
|
||||
*
|
||||
* Returns 0 or negative value in case of error
|
||||
*/
|
||||
int ssp_common_process_data(struct iio_dev *indio_dev, void *buf,
|
||||
unsigned int len, int64_t timestamp)
|
||||
{
|
||||
__le32 time;
|
||||
int64_t calculated_time;
|
||||
struct ssp_sensor_data *spd = iio_priv(indio_dev);
|
||||
|
||||
if (indio_dev->scan_bytes == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* it always sends full set of samples, remember about available masks
|
||||
*/
|
||||
memcpy(spd->buffer, buf, len);
|
||||
|
||||
if (indio_dev->scan_timestamp) {
|
||||
memcpy(&time, &((char *)buf)[len], SSP_TIME_SIZE);
|
||||
calculated_time =
|
||||
timestamp + (int64_t)le32_to_cpu(time) * 1000000;
|
||||
}
|
||||
|
||||
return iio_push_to_buffers_with_timestamp(indio_dev, spd->buffer,
|
||||
calculated_time);
|
||||
}
|
||||
EXPORT_SYMBOL(ssp_common_process_data);
|
||||
|
||||
MODULE_AUTHOR("Karol Wrona <k.wrona@samsung.com>");
|
||||
MODULE_DESCRIPTION("Samsung sensorhub commons");
|
||||
MODULE_LICENSE("GPL");
|
70
drivers/iio/common/ssp_sensors/ssp_iio_sensor.h
Normal file
70
drivers/iio/common/ssp_sensors/ssp_iio_sensor.h
Normal file
@ -0,0 +1,70 @@
|
||||
#ifndef __SSP_IIO_SENSOR_H__
|
||||
#define __SSP_IIO_SENSOR_H__
|
||||
|
||||
#define SSP_CHANNEL_AG(_type, _mod, _index) \
|
||||
{ \
|
||||
.type = _type,\
|
||||
.modified = 1,\
|
||||
.channel2 = _mod,\
|
||||
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ),\
|
||||
.scan_index = _index,\
|
||||
.scan_type = {\
|
||||
.sign = 's',\
|
||||
.realbits = 16,\
|
||||
.storagebits = 16,\
|
||||
.shift = 0,\
|
||||
.endianness = IIO_LE,\
|
||||
},\
|
||||
}
|
||||
|
||||
/* It is defined here as it is a mixed timestamp */
|
||||
#define SSP_CHAN_TIMESTAMP(_si) { \
|
||||
.type = IIO_TIMESTAMP, \
|
||||
.channel = -1, \
|
||||
.scan_index = _si, \
|
||||
.scan_type = { \
|
||||
.sign = 's', \
|
||||
.realbits = 64, \
|
||||
.storagebits = 64, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define SSP_MS_PER_S 1000
|
||||
#define SSP_INVERTED_SCALING_FACTOR 1000000ULL
|
||||
|
||||
#define SSP_FACTOR_WITH_MS \
|
||||
(SSP_INVERTED_SCALING_FACTOR * SSP_MS_PER_S)
|
||||
|
||||
int ssp_common_buffer_postenable(struct iio_dev *indio_dev);
|
||||
|
||||
int ssp_common_buffer_postdisable(struct iio_dev *indio_dev);
|
||||
|
||||
int ssp_common_process_data(struct iio_dev *indio_dev, void *buf,
|
||||
unsigned int len, int64_t timestamp);
|
||||
|
||||
/* Converts time in ms to frequency */
|
||||
static inline void ssp_convert_to_freq(u32 time, int *integer_part,
|
||||
int *fractional)
|
||||
{
|
||||
if (time == 0) {
|
||||
*fractional = 0;
|
||||
*integer_part = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
*integer_part = SSP_FACTOR_WITH_MS / time;
|
||||
*fractional = do_div(*integer_part, SSP_INVERTED_SCALING_FACTOR);
|
||||
}
|
||||
|
||||
/* Converts frequency to time in ms */
|
||||
static inline int ssp_convert_to_time(int integer_part, int fractional)
|
||||
{
|
||||
u64 value;
|
||||
|
||||
value = integer_part * SSP_INVERTED_SCALING_FACTOR + fractional;
|
||||
if (value == 0)
|
||||
return 0;
|
||||
|
||||
return div_u64(SSP_FACTOR_WITH_MS, value);
|
||||
}
|
||||
#endif /* __SSP_IIO_SENSOR_H__ */
|
Loading…
x
Reference in New Issue
Block a user