/**
 * @file sensor.h
 *
 * @brief Public APIs for the sensor driver.
 */

/*
 * Copyright (c) 2016 Intel Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef __SENSOR_H__
#define __SENSOR_H__

/**
 * @brief Sensor Interface
 * @defgroup sensor_interface Sensor Interface
 * @ingroup io_interfaces
 * @{
 */

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>
#include <device.h>
#include <errno.h>

/** @brief Sensor value types. */
enum sensor_value_type {
	/** val1 contains an integer value, val2 is unused. */
	SENSOR_VALUE_TYPE_INT,
	/**
	 * val1 contains an integer value, val2 is the fractional value.
	 * To obtain the final value, use the formula: val1 + val2 *
	 * 10^(-6).
	 */
	SENSOR_VALUE_TYPE_INT_PLUS_MICRO,
	/**
	 * @brief val1 contains a Q16.16 representation, val2 is
	 * unused.
	 */
	SENSOR_VALUE_TYPE_Q16_16,
	/** @brief dval contains a floating point value. */
	SENSOR_VALUE_TYPE_DOUBLE,
};

/**
 * @brief Representation of a sensor readout value.
 *
 * The meaning of the fields is dictated by the type field.
 */
struct sensor_value {
	enum sensor_value_type type;
	union  {
		struct {
			int32_t val1;
			int32_t val2;
		};
		double dval;
	};
};

/**
 * @brief Sensor channels.
 */
enum sensor_channel {
	/** Acceleration on the X axis, in m/s^2. */
	SENSOR_CHAN_ACCEL_X,
	/** Acceleration on the Y axis, in m/s^2. */
	SENSOR_CHAN_ACCEL_Y,
	/** Acceleration on the Z axis, in m/s^2. */
	SENSOR_CHAN_ACCEL_Z,
	/** Acceleration on any axis. */
	SENSOR_CHAN_ACCEL_ANY,
	/** Angular velocity around the X axis, in radians/s. */
	SENSOR_CHAN_GYRO_X,
	/** Angular velocity around the Y axis, in radians/s. */
	SENSOR_CHAN_GYRO_Y,
	/** Angular velocity around the Z axis, in radians/s. */
	SENSOR_CHAN_GYRO_Z,
	/** Angular velocity on any axis. */
	SENSOR_CHAN_GYRO_ANY,
	/** Magnetic field on the X axis, in Gauss. */
	SENSOR_CHAN_MAGN_X,
	/** Magnetic field on the Y axis, in Gauss. */
	SENSOR_CHAN_MAGN_Y,
	/** Magnetic field on the Z axis, in Gauss. */
	SENSOR_CHAN_MAGN_Z,
	/** Magnetic field on any axis. */
	SENSOR_CHAN_MAGN_ANY,
	/** Temperature in degrees Celsius. */
	SENSOR_CHAN_TEMP,
	/** Pressure in kilopascal. */
	SENSOR_CHAN_PRESS,
	/**
	 * Proximity.  Adimensional.  A value of 1 indicates that an
	 * object is close.
	 */
	SENSOR_CHAN_PROX,
	/** Humidity, in milli percent. */
	SENSOR_CHAN_HUMIDITY,
	/** Illuminance in visible spectrum, in lux. */
	SENSOR_CHAN_LIGHT,
	/** Illuminance in infra-red spectrum, in lux. */
	SENSOR_CHAN_IR,
	/** Altitude, in meters */
	SENSOR_CHAN_ALTITUDE,
	/** All channels. */
	SENSOR_CHAN_ALL,
};

/**
 * @brief Sensor trigger types.
 */
enum sensor_trigger_type {
	/**
	 * Timer-based trigger, useful when the sensor does not have an
	 * interrupt line.
	 */
	SENSOR_TRIG_TIMER,
	/** Trigger fires whenever new data is ready. */
	SENSOR_TRIG_DATA_READY,
	/**
	 * Trigger fires when the selected channel varies significantly.
	 * This includes any-motion detection when the channel is
	 * acceleration or gyro. If detection is based on slope between
	 * successive channel readings, the slope threshold is configured
	 * via the @ref SENSOR_ATTR_SLOPE_TH and @ref SENSOR_ATTR_SLOPE_DUR
	 * attributes.
	 */
	SENSOR_TRIG_DELTA,
	/** Trigger fires when a near/far event is detected. */
	SENSOR_TRIG_NEAR_FAR,
	/**
	 * Trigger fires when channel reading transitions configured
	 * thresholds.  The thresholds are configured via the @ref
	 * SENSOR_ATTR_LOWER_THRESH and @ref SENSOR_ATTR_UPPER_THRESH
	 * attributes.
	 */
	SENSOR_TRIG_THRESHOLD,
};

/**
 * @brief Sensor trigger spec.
 */
struct sensor_trigger {
	/** Trigger type. */
	enum sensor_trigger_type type;
	/** Channel the trigger is set on. */
	enum sensor_channel chan;
};

/**
 * @brief Sensor attribute types.
 */
enum sensor_attribute {
	/**
	 * Sensor sampling frequency, i.e. how many times a second the
	 * sensor takes a measurement.
	 */
	SENSOR_ATTR_SAMPLING_FREQUENCY,
	/** Lower threshold for trigger. */
	SENSOR_ATTR_LOWER_THRESH,
	/** Upper threshold for trigger. */
	SENSOR_ATTR_UPPER_THRESH,
	/** Threshold for any-motion (slope) trigger. */
	SENSOR_ATTR_SLOPE_TH,
	/**
	 * Duration for which the slope values needs to be
	 * outside the threshold for the trigger to fire.
	 */
	SENSOR_ATTR_SLOPE_DUR,
	/** Oversampling factor */
	SENSOR_ATTR_OVERSAMPLING,
	/** Sensor range, in SI units. */
	SENSOR_ATTR_FULL_SCALE,
	/**
	 * The sensor value returned will be altered by the amount indicated by
	 * offset: final_value = sensor_value + offset.
	 */
	SENSOR_ATTR_OFFSET,
	/**
	 * Calibration target. This will be used by the internal chip's
	 * algorithms to calibrate itself on a certain axis, or all of them.
	 */
	SENSOR_ATTR_CALIB_TARGET,
};

/**
 * @typedef sensor_trigger_handler_t
 * @brief Callback API upon firing of a trigger
 *
 * @param "struct device *dev" Pointer to the sensor device
 * @param "struct sensor_trigger *trigger" The trigger
 */
typedef void (*sensor_trigger_handler_t)(struct device *dev,
					 struct sensor_trigger *trigger);

/**
 * @typedef sensor_attr_set_t
 * @brief Callback API upon setting a sensor's attributes
 *
 * See sensor_attr_set() for argument description
 */
typedef int (*sensor_attr_set_t)(struct device *dev,
				 enum sensor_channel chan,
				 enum sensor_attribute attr,
				 const struct sensor_value *val);
/**
 * @typedef sensor_trigger_set_t
 * @brief Callback API for setting a sensor's trigger and handler
 *
 * See sensor_trigger_set() for argument description
 */
typedef int (*sensor_trigger_set_t)(struct device *dev,
				    const struct sensor_trigger *trig,
				    sensor_trigger_handler_t handler);
/**
 * @typedef sensor_sample_fetch_t
 * @brief Callback API for fetching data from a sensor
 *
 * See sensor_sample_fetch() for argument descriptor
 */
typedef int (*sensor_sample_fetch_t)(struct device *dev,
				     enum sensor_channel chan);
/**
 * @typedef sensor_channel_get_t
 * @brief Callback API for getting a reading from a sensor
 *
 * See sensor_channel_get() for argument descriptor
 */
typedef int (*sensor_channel_get_t)(struct device *dev,
				    enum sensor_channel chan,
				    struct sensor_value *val);

struct sensor_driver_api {
	sensor_attr_set_t attr_set;
	sensor_trigger_set_t trigger_set;
	sensor_sample_fetch_t sample_fetch;
	sensor_channel_get_t channel_get;
};

/**
 * @brief Set an attribute for a sensor
 *
 * @param dev Pointer to the sensor device
 * @param chan The channel the attribute belongs to, if any.  Some
 * attributes may only be set for all channels of a device, depending on
 * device capabilities.
 * @param attr The attribute to set
 * @param val The value to set the attribute to
 *
 * @return 0 if successful, negative errno code if failure.
 */
static inline int sensor_attr_set(struct device *dev,
				  enum sensor_channel chan,
				  enum sensor_attribute attr,
				  const struct sensor_value *val)
{
	struct sensor_driver_api *api;

	api = (struct sensor_driver_api *)dev->driver_api;
	if (!api->attr_set) {
		return -ENOTSUP;
	}

	return api->attr_set(dev, chan, attr, val);
}

/**
 * @brief Activate a sensor's trigger and set the trigger handler
 *
 * The handler will be called from a fiber, so I2C or SPI operations are
 * safe.  However, the fiber's stack is limited and defined by the
 * driver.  It is currently up to the caller to ensure that the handler
 * does not overflow the stack.
 *
 * @param dev Pointer to the sensor device
 * @param trig The trigger to activate
 * @param handler The function that should be called when the trigger
 * fires
 *
 * @return 0 if successful, negative errno code if failure.
 */
static inline int sensor_trigger_set(struct device *dev,
				     struct sensor_trigger *trig,
				     sensor_trigger_handler_t handler)
{
	struct sensor_driver_api *api;

	api = (struct sensor_driver_api *)dev->driver_api;
	if (!api->trigger_set) {
		return -ENOTSUP;
	}

	return api->trigger_set(dev, trig, handler);
}

/**
 * @brief Fetch a sample from the sensor and store it in an internal
 * driver buffer
 *
 * Read all of a sensor's active channels and, if necessary, perform any
 * additional operations necessary to make the values useful.  The user
 * may then get individual channel values by calling @ref
 * sensor_channel_get.
 *
 * Since the function communicates with the sensor device, it is unsafe
 * to call it in an ISR if the device is connected via I2C or SPI.
 *
 * @param dev Pointer to the sensor device
 *
 * @return 0 if successful, negative errno code if failure.
 */
static inline int sensor_sample_fetch(struct device *dev)
{
	struct sensor_driver_api *api;

	api = (struct sensor_driver_api *)dev->driver_api;

	return api->sample_fetch(dev, SENSOR_CHAN_ALL);
}

/**
 * @brief Fetch a sample from the sensor and store it in an internal
 * driver buffer
 *
 * Read and compute compensation for one type of sensor data (magnetometer,
 * accelerometer, etc). The user may then get individual channel values by
 * calling @ref sensor_channel_get.
 *
 * This is mostly implemented by multi function devices enabling reading at
 * different sampling rates.
 *
 * Since the function communicates with the sensor device, it is unsafe
 * to call it in an ISR if the device is connected via I2C or SPI.
 *
 * @param dev Pointer to the sensor device
 * @param type The channel that needs updated
 *
 * @return 0 if successful, negative errno code if failure.
 */
static inline int sensor_sample_fetch_chan(struct device *dev,
					   enum sensor_channel type)
{
	struct sensor_driver_api *api;

	api = (struct sensor_driver_api *)dev->driver_api;

	return api->sample_fetch(dev, type);
}

/**
 * @brief Get a reading from a sensor device
 *
 * Return a useful value for a particular channel, from the driver's
 * internal data.  Before calling this function, a sample must be
 * obtained by calling @ref sensor_sample_fetch or
 * @ref sensor_sample_fetch_chan. It is guaranteed that two subsequent
 * calls of this function for the same channels will yield the same
 * value, if @ref sensor_sample_fetch or @ref sensor_sample_fetch_chan
 * has not been called in the meantime.
 *
 * For vectorial data samples you can request all axes in just one call
 * by passing the specific channel with _ANY suffix. The sample will be
 * returned at val[0], val[1] and val[2] (X, Y and Z in that order).
 *
 * @param dev Pointer to the sensor device
 * @param chan The channel to read
 * @param val Where to store the value
 *
 * @return 0 if successful, negative errno code if failure.
 */
static inline int sensor_channel_get(struct device *dev,
				     enum sensor_channel chan,
				     struct sensor_value *val)
{
	struct sensor_driver_api *api;

	api = (struct sensor_driver_api *)dev->driver_api;

	return api->channel_get(dev, chan, val);
}

/**
 * @brief The value of gravitational constant in micro m/s^2.
 */
#define SENSOR_G		9806650LL

/**
 * @brief The value of constant PI in micros.
 */
#define SENSOR_PI		3141592LL

/**
 * @brief Helper function to convert acceleration from m/s^2 to Gs
 *
 * @param ms2 A pointer to a sensor_value struct holding the acceleration,
 *            in m/s^2.
 *
 * @return The converted value, in Gs.
 */
static inline int32_t sensor_ms2_to_g(const struct sensor_value *ms2)
{
	int64_t micro_ms2 = ms2->val1 * 1000000LL + ms2->val2;

	if (micro_ms2 > 0) {
		return (micro_ms2 + SENSOR_G / 2) / SENSOR_G;
	} else {
		return (micro_ms2 - SENSOR_G / 2) / SENSOR_G;
	}
}

/**
 * @brief Helper function to convert acceleration from Gs to m/s^2
 *
 * @param g The G value to be converted.
 * @param ms2 A pointer to a sensor_value struct, where the result is stored.
 */
static inline void sensor_g_to_ms2(int32_t g, struct sensor_value *ms2)
{
	ms2->type = SENSOR_VALUE_TYPE_INT_PLUS_MICRO;
	ms2->val1 = ((int64_t)g * SENSOR_G) / 1000000LL;
	ms2->val2 = ((int64_t)g * SENSOR_G) % 1000000LL;
}

/**
 * @brief Helper function for converting radians to degrees.
 *
 * @param rad A pointer to a sensor_value struct, holding the value in radians.
 *
 * @return The converted value, in degrees.
 */
static inline int32_t sensor_rad_to_degrees(const struct sensor_value *rad)
{
	int64_t micro_rad_s = rad->val1 * 1000000LL + rad->val2;

	if (micro_rad_s > 0) {
		return (micro_rad_s * 180LL + SENSOR_PI / 2) / SENSOR_PI;
	} else {
		return (micro_rad_s * 180LL - SENSOR_PI / 2) / SENSOR_PI;
	}
}

/**
 * @brief Helper function for converting degrees to radians.
 *
 * @param d The value (in degrees) to be converted.
 * @param rad A pointer to a sensor_value struct, where the result is stored.
 */
static inline void sensor_degrees_to_rad(int32_t d, struct sensor_value *rad)
{
	rad->type = SENSOR_VALUE_TYPE_INT_PLUS_MICRO;
	rad->val1 = ((int64_t)d * SENSOR_PI / 180LL) / 1000000LL;
	rad->val2 = ((int64_t)d * SENSOR_PI / 180LL) % 1000000LL;
}

/**
 * @brief configuration parameters for sensor triggers.
 */
enum sensor_trigger_mode {
	/** Do not use triggering. */
	SENSOR_TRIG_MODE_NONE,
	/**
	 * Driver should start a workqueue specifically for this
	 * device.  See @ref sensor_trig_or_wq_config for instruction on
	 * how to specify the parameters of the workqueue.
	 */
	SENSOR_TRIG_MODE_OWN_WQ,
	/** Use the system workqueue. */
	SENSOR_TRIG_MODE_GLOBAL_WQ,
};

/**
 * @brief configuration parameters for sensor triggers.
 */
struct sensor_trigger_config {
	/**
	 * This is always set to NULL when using a @ref
	 * sensor_trigger_config.  See the comment in @ref
	 * sensor_trig_or_wq_config.
	 */
	void *always_null;
	enum sensor_trigger_mode mode;
};

/**
 * @brief Structure used for sensor trigger configuration.
 *
 * If fiber_config.stack is non-NULL, the driver should start its
 * own fiber based on @ref fiber_config.  Otherwise, use
 * sensor_interface::sensor_trigger_mode to decide if and how to use
 * triggering.
 */
union sensor_trig_or_wq_config {
	struct fiber_config fiber_config;
	struct sensor_trigger_config trig_config;
};

#define SENSOR_DECLARE_TRIG_CONFIG		\
	union sensor_trig_or_wq_config trig_or_wq_config

#define SENSOR_TRIG_WQ_OWN(_stack, _prio)			\
	.trig_or_wq_config = {					\
		.fiber_config = {				\
			.stack = (_stack),			\
			.stack_size = sizeof(_stack),		\
			.prio = (_prio),			\
		}						\
	}

#define SENSOR_TRIG_WQ_GLOBAL					\
	.trig_or_wq_config = {					\
		.trig_config = {				\
			.always_null = NULL,			\
			.mode = SENSOR_TRIG_MODE_GLOBAL_WQ,	\
		}						\
	}

#define SENSOR_TRIG_NONE					\
	.trig_or_wq_config = {					\
		.trig_config = {				\
			.always_null = NULL,			\
			.mode = SENSOR_TRIG_MODE_NONE,		\
		}						\
	}

#define SENSOR_GET_TRIG_MODE(_conf)				\
	(!(_conf)->trig_or_wq_config.fiber_config.stack		\
	 ? SENSOR_TRIG_MODE_OWN_WQ :				\
	 (_conf)->trig_or_wq_config.trig_config.mode)
#define SENSOR_GET_WQ_CONFIG(_conf)				\
	((_conf)->trig_or_wq_config.fiber_config)

#ifdef __cplusplus
}
#endif

/**
 * @}
 */

#endif /* __SENSOR_H__ */
