Commit 974e6f02 authored by Enric Balletbo i Serra's avatar Enric Balletbo i Serra Committed by Jonathan Cameron

iio: cros_ec_sensors_core: Add common functions for the ChromeOS EC Sensor Hub.

Add the core functions to be able to support the sensors attached behind
the ChromeOS Embedded Controller and used by other IIO cros-ec sensor
drivers.

The cros_ec_sensor_core driver matches with current driver in ChromeOS
4.4 tree, so it includes all the fixes at the moment. The support for
this driver was made by Gwendal Grignou. The original patch and all the
fixes has been squashed and rebased on top of mainline.
Signed-off-by: default avatarGwendal Grignou <gwendal@chromium.org>
Signed-off-by: default avatarGuenter Roeck <groeck@chromium.org>
[eballetbo: split, squash and rebase on top of mainline the patches
found in ChromeOS tree]
Signed-off-by: default avatarEnric Balletbo i Serra <enric.balletbo@collabora.com>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
parent 1001354c
What: /sys/bus/iio/devices/iio:deviceX/calibrate
Date: July 2015
KernelVersion: 4.7
Contact: linux-iio@vger.kernel.org
Description:
Writing '1' will perform a FOC (Fast Online Calibration). The
corresponding calibration offsets can be read from *_calibbias
entries.
What: /sys/bus/iio/devices/iio:deviceX/location
Date: July 2015
KernelVersion: 4.7
Contact: linux-iio@vger.kernel.org
Description:
This attribute returns a string with the physical location where
the motion sensor is placed. For example, in a laptop a motion
sensor can be located on the base or on the lid. Current valid
values are 'base' and 'lid'.
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
# IIO common modules # IIO common modules
# #
source "drivers/iio/common/cros_ec_sensors/Kconfig"
source "drivers/iio/common/hid-sensors/Kconfig" source "drivers/iio/common/hid-sensors/Kconfig"
source "drivers/iio/common/ms_sensors/Kconfig" source "drivers/iio/common/ms_sensors/Kconfig"
source "drivers/iio/common/ssp_sensors/Kconfig" source "drivers/iio/common/ssp_sensors/Kconfig"
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
# #
# When adding new entries keep the list in alphabetical order # When adding new entries keep the list in alphabetical order
obj-y += cros_ec_sensors/
obj-y += hid-sensors/ obj-y += hid-sensors/
obj-y += ms_sensors/ obj-y += ms_sensors/
obj-y += ssp_sensors/ obj-y += ssp_sensors/
......
#
# Chrome OS Embedded Controller managed sensors library
#
config IIO_CROS_EC_SENSORS_CORE
tristate "ChromeOS EC Sensors Core"
depends on SYSFS && MFD_CROS_EC
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
Base module for the ChromeOS EC Sensors module.
Contains core functions used by other IIO CrosEC sensor
drivers.
Define common attributes and sysfs interrupt handler.
#
# Makefile for sensors seen through the ChromeOS EC sensor hub.
#
obj-$(CONFIG_IIO_CROS_EC_SENSORS_CORE) += cros_ec_sensors_core.o
This diff is collapsed.
/*
* ChromeOS EC sensor hub
*
* Copyright (C) 2016 Google, Inc
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*/
#ifndef __CROS_EC_SENSORS_CORE_H
#define __CROS_EC_SENSORS_CORE_H
#include <linux/irqreturn.h>
enum {
CROS_EC_SENSOR_X,
CROS_EC_SENSOR_Y,
CROS_EC_SENSOR_Z,
CROS_EC_SENSOR_MAX_AXIS,
};
/* EC returns sensor values using signed 16 bit registers */
#define CROS_EC_SENSOR_BITS 16
/*
* 4 16 bit channels are allowed.
* Good enough for current sensors, they use up to 3 16 bit vectors.
*/
#define CROS_EC_SAMPLE_SIZE (sizeof(s64) * 2)
/* Minimum sampling period to use when device is suspending */
#define CROS_EC_MIN_SUSPEND_SAMPLING_FREQUENCY 1000 /* 1 second */
/**
* struct cros_ec_sensors_core_state - state data for EC sensors IIO driver
* @ec: cros EC device structure
* @cmd_lock: lock used to prevent simultaneous access to the
* commands.
* @msg: cros EC command structure
* @param: motion sensor parameters structure
* @resp: motion sensor response structure
* @type: type of motion sensor
* @loc: location where the motion sensor is placed
* @calib: calibration parameters. Note that trigger
* captured data will always provide the calibrated
* data
* @samples: static array to hold data from a single capture.
* For each channel we need 2 bytes, except for
* the timestamp. The timestamp is always last and
* is always 8-byte aligned.
* @read_ec_sensors_data: function used for accessing sensors values
* @cuur_sampl_freq: current sampling period
*/
struct cros_ec_sensors_core_state {
struct cros_ec_device *ec;
struct mutex cmd_lock;
struct cros_ec_command *msg;
struct ec_params_motion_sense param;
struct ec_response_motion_sense *resp;
enum motionsensor_type type;
enum motionsensor_location loc;
s16 calib[CROS_EC_SENSOR_MAX_AXIS];
u8 samples[CROS_EC_SAMPLE_SIZE];
int (*read_ec_sensors_data)(struct iio_dev *indio_dev,
unsigned long scan_mask, s16 *data);
int curr_sampl_freq;
};
/**
* cros_ec_sensors_read_lpc() - retrieve data from EC shared memory
* @indio_dev: pointer to IIO device
* @scan_mask: bitmap of the sensor indices to scan
* @data: location to store data
*
* This is the safe function for reading the EC data. It guarantees that the
* data sampled was not modified by the EC while being read.
*
* Return: 0 on success, -errno on failure.
*/
int cros_ec_sensors_read_lpc(struct iio_dev *indio_dev, unsigned long scan_mask,
s16 *data);
/**
* cros_ec_sensors_read_cmd() - retrieve data using the EC command protocol
* @indio_dev: pointer to IIO device
* @scan_mask: bitmap of the sensor indices to scan
* @data: location to store data
*
* Return: 0 on success, -errno on failure.
*/
int cros_ec_sensors_read_cmd(struct iio_dev *indio_dev, unsigned long scan_mask,
s16 *data);
/**
* cros_ec_sensors_core_init() - basic initialization of the core structure
* @pdev: platform device created for the sensors
* @indio_dev: iio device structure of the device
* @physical_device: true if the device refers to a physical device
*
* Return: 0 on success, -errno on failure.
*/
int cros_ec_sensors_core_init(struct platform_device *pdev,
struct iio_dev *indio_dev, bool physical_device);
/**
* cros_ec_sensors_capture() - the trigger handler function
* @irq: the interrupt number.
* @p: a pointer to the poll function.
*
* On a trigger event occurring, if the pollfunc is attached then this
* handler is called as a threaded interrupt (and hence may sleep). It
* is responsible for grabbing data from the device and pushing it into
* the associated buffer.
*
* Return: IRQ_HANDLED
*/
irqreturn_t cros_ec_sensors_capture(int irq, void *p);
/**
* cros_ec_motion_send_host_cmd() - send motion sense host command
* @st: pointer to state information for device
* @opt_length: optional length to reduce the response size, useful on the data
* path. Otherwise, the maximal allowed response size is used
*
* When called, the sub-command is assumed to be set in param->cmd.
*
* Return: 0 on success, -errno on failure.
*/
int cros_ec_motion_send_host_cmd(struct cros_ec_sensors_core_state *st,
u16 opt_length);
/**
* cros_ec_sensors_core_read() - function to request a value from the sensor
* @st: pointer to state information for device
* @chan: channel specification structure table
* @val: will contain one element making up the returned value
* @val2: will contain another element making up the returned value
* @mask: specifies which values to be requested
*
* Return: the type of value returned by the device
*/
int cros_ec_sensors_core_read(struct cros_ec_sensors_core_state *st,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask);
/**
* cros_ec_sensors_core_write() - function to write a value to the sensor
* @st: pointer to state information for device
* @chan: channel specification structure table
* @val: first part of value to write
* @val2: second part of value to write
* @mask: specifies which values to write
*
* Return: the type of value returned by the device
*/
int cros_ec_sensors_core_write(struct cros_ec_sensors_core_state *st,
struct iio_chan_spec const *chan,
int val, int val2, long mask);
/* List of extended channel specification for all sensors */
extern const struct iio_chan_spec_ext_info cros_ec_sensors_ext_info[];
#endif /* __CROS_EC_SENSORS_CORE_H */
...@@ -148,6 +148,15 @@ struct cros_ec_device { ...@@ -148,6 +148,15 @@ struct cros_ec_device {
int event_size; int event_size;
}; };
/**
* struct cros_ec_sensor_platform - ChromeOS EC sensor platform information
*
* @sensor_num: Id of the sensor, as reported by the EC.
*/
struct cros_ec_sensor_platform {
u8 sensor_num;
};
/* struct cros_ec_platform - ChromeOS EC platform information /* struct cros_ec_platform - ChromeOS EC platform information
* *
* @ec_name: name of EC device (e.g. 'cros-ec', 'cros-pd', ...) * @ec_name: name of EC device (e.g. 'cros-ec', 'cros-pd', ...)
......
...@@ -1315,6 +1315,24 @@ enum motionsense_command { ...@@ -1315,6 +1315,24 @@ enum motionsense_command {
*/ */
MOTIONSENSE_CMD_KB_WAKE_ANGLE = 5, MOTIONSENSE_CMD_KB_WAKE_ANGLE = 5,
/*
* Returns a single sensor data.
*/
MOTIONSENSE_CMD_DATA = 6,
/*
* Perform low level calibration.. On sensors that support it, ask to
* do offset calibration.
*/
MOTIONSENSE_CMD_PERFORM_CALIB = 10,
/*
* Sensor Offset command is a setter/getter command for the offset used
* for calibration. The offsets can be calculated by the host, or via
* PERFORM_CALIB command.
*/
MOTIONSENSE_CMD_SENSOR_OFFSET = 11,
/* Number of motionsense sub-commands. */ /* Number of motionsense sub-commands. */
MOTIONSENSE_NUM_CMDS MOTIONSENSE_NUM_CMDS
}; };
...@@ -1335,12 +1353,18 @@ enum motionsensor_id { ...@@ -1335,12 +1353,18 @@ enum motionsensor_id {
enum motionsensor_type { enum motionsensor_type {
MOTIONSENSE_TYPE_ACCEL = 0, MOTIONSENSE_TYPE_ACCEL = 0,
MOTIONSENSE_TYPE_GYRO = 1, MOTIONSENSE_TYPE_GYRO = 1,
MOTIONSENSE_TYPE_MAG = 2,
MOTIONSENSE_TYPE_PROX = 3,
MOTIONSENSE_TYPE_LIGHT = 4,
MOTIONSENSE_TYPE_ACTIVITY = 5,
MOTIONSENSE_TYPE_MAX
}; };
/* List of motion sensor locations. */ /* List of motion sensor locations. */
enum motionsensor_location { enum motionsensor_location {
MOTIONSENSE_LOC_BASE = 0, MOTIONSENSE_LOC_BASE = 0,
MOTIONSENSE_LOC_LID = 1, MOTIONSENSE_LOC_LID = 1,
MOTIONSENSE_LOC_MAX,
}; };
/* List of motion sensor chips. */ /* List of motion sensor chips. */
...@@ -1361,6 +1385,31 @@ enum motionsensor_chip { ...@@ -1361,6 +1385,31 @@ enum motionsensor_chip {
*/ */
#define EC_MOTION_SENSE_NO_VALUE -1 #define EC_MOTION_SENSE_NO_VALUE -1
#define EC_MOTION_SENSE_INVALID_CALIB_TEMP 0x8000
/* Set Calibration information */
#define MOTION_SENSE_SET_OFFSET 1
struct ec_response_motion_sensor_data {
/* Flags for each sensor. */
uint8_t flags;
/* Sensor number the data comes from */
uint8_t sensor_num;
/* Each sensor is up to 3-axis. */
union {
int16_t data[3];
struct {
uint16_t rsvd;
uint32_t timestamp;
} __packed;
struct {
uint8_t activity; /* motionsensor_activity */
uint8_t state;
int16_t add_info[2];
};
};
} __packed;
struct ec_params_motion_sense { struct ec_params_motion_sense {
uint8_t cmd; uint8_t cmd;
union { union {
...@@ -1378,9 +1427,37 @@ struct ec_params_motion_sense { ...@@ -1378,9 +1427,37 @@ struct ec_params_motion_sense {
int16_t data; int16_t data;
} ec_rate, kb_wake_angle; } ec_rate, kb_wake_angle;
/* Used for MOTIONSENSE_CMD_SENSOR_OFFSET */
struct {
uint8_t sensor_num;
/*
* bit 0: If set (MOTION_SENSE_SET_OFFSET), set
* the calibration information in the EC.
* If unset, just retrieve calibration information.
*/
uint16_t flags;
/*
* Temperature at calibration, in units of 0.01 C
* 0x8000: invalid / unknown.
* 0x0: 0C
* 0x7fff: +327.67C
*/
int16_t temp;
/*
* Offset for calibration.
* Unit:
* Accelerometer: 1/1024 g
* Gyro: 1/1024 deg/s
* Compass: 1/16 uT
*/
int16_t offset[3];
} __packed sensor_offset;
/* Used for MOTIONSENSE_CMD_INFO. */ /* Used for MOTIONSENSE_CMD_INFO. */
struct { struct {
/* Should be element of enum motionsensor_id. */
uint8_t sensor_num; uint8_t sensor_num;
} info; } info;
...@@ -1410,11 +1487,14 @@ struct ec_response_motion_sense { ...@@ -1410,11 +1487,14 @@ struct ec_response_motion_sense {
/* Flags representing the motion sensor module. */ /* Flags representing the motion sensor module. */
uint8_t module_flags; uint8_t module_flags;
/* Flags for each sensor in enum motionsensor_id. */ /* Number of sensors managed directly by the EC. */
uint8_t sensor_flags[EC_MOTION_SENSOR_COUNT]; uint8_t sensor_count;
/* Array of all sensor data. Each sensor is 3-axis. */ /*
int16_t data[3*EC_MOTION_SENSOR_COUNT]; * Sensor data is truncated if response_max is too small
* for holding all the data.
*/
struct ec_response_motion_sensor_data sensor[0];
} dump; } dump;
/* Used for MOTIONSENSE_CMD_INFO. */ /* Used for MOTIONSENSE_CMD_INFO. */
...@@ -1429,6 +1509,9 @@ struct ec_response_motion_sense { ...@@ -1429,6 +1509,9 @@ struct ec_response_motion_sense {
uint8_t chip; uint8_t chip;
} info; } info;
/* Used for MOTIONSENSE_CMD_DATA */
struct ec_response_motion_sensor_data data;
/* /*
* Used for MOTIONSENSE_CMD_EC_RATE, MOTIONSENSE_CMD_SENSOR_ODR, * Used for MOTIONSENSE_CMD_EC_RATE, MOTIONSENSE_CMD_SENSOR_ODR,
* MOTIONSENSE_CMD_SENSOR_RANGE, and * MOTIONSENSE_CMD_SENSOR_RANGE, and
...@@ -1438,6 +1521,12 @@ struct ec_response_motion_sense { ...@@ -1438,6 +1521,12 @@ struct ec_response_motion_sense {
/* Current value of the parameter queried. */ /* Current value of the parameter queried. */
int32_t ret; int32_t ret;
} ec_rate, sensor_odr, sensor_range, kb_wake_angle; } ec_rate, sensor_odr, sensor_range, kb_wake_angle;
/* Used for MOTIONSENSE_CMD_SENSOR_OFFSET */
struct {
int16_t temp;
int16_t offset[3];
} sensor_offset, perform_calib;
}; };
} __packed; } __packed;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment