mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-27 18:25:05 +00:00
Refactor accel / gyro driver to accomodate various configurations
Previously our accel / gyro drivers assumed that we had exactly two of each identical part in the system. Some systems may have different configurations, so allow this to be specified at the board-level. Note that our motion_sense algorithm currently assumes that we have one accelerometer in the lid and one in the base -- we'll need to fix that in another CL. BUG=chrome-os-partner:27320 TEST=Compile-only. Tested in future Samus commit. BRANCH=None. Change-Id: I1fae1f6c578fedebe78b473a5d66a5794ccaae00 Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/212321 Reviewed-by: Alec Berg <alecaberg@chromium.org>
This commit is contained in:
committed by
chrome-internal-fetch
parent
be060242e3
commit
a048d76e0d
@@ -5,7 +5,6 @@
|
||||
|
||||
/* Motion sensor calibration code. */
|
||||
|
||||
#include "accelerometer.h"
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "math_util.h"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
/* Motion sense module to read from various motion sensors. */
|
||||
|
||||
#include "accelerometer.h"
|
||||
#include "accelgyro.h"
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "hooks.h"
|
||||
@@ -24,6 +24,9 @@
|
||||
/* Minimum time in between running motion sense task loop. */
|
||||
#define MIN_MOTION_SENSE_WAIT_TIME (1 * MSEC)
|
||||
|
||||
static const struct motion_sensor_t *base;
|
||||
static const struct motion_sensor_t *lid;
|
||||
|
||||
/* Current acceleration vectors and current lid angle. */
|
||||
static vector_3_t acc_lid_raw, acc_lid, acc_base;
|
||||
static vector_3_t acc_lid_host, acc_base_host;
|
||||
@@ -186,6 +189,7 @@ void motion_sense_task(void)
|
||||
uint8_t *lpc_status;
|
||||
uint16_t *lpc_data;
|
||||
int sample_id = 0;
|
||||
int i;
|
||||
|
||||
lpc_status = host_get_memmap(EC_MEMMAP_ACC_STATUS);
|
||||
lpc_data = (uint16_t *)host_get_memmap(EC_MEMMAP_ACC_DATA);
|
||||
@@ -193,14 +197,25 @@ void motion_sense_task(void)
|
||||
/*
|
||||
* TODO(crosbug.com/p/27320): The motion_sense task currently assumes
|
||||
* one configuration of motion sensors. Namely, it assumes there is
|
||||
* one accel in the base, one in the lid, and they both use the same
|
||||
* driver. Eventually, all of these assumptions will have to be removed
|
||||
* when we have other configurations of motion sensors.
|
||||
* one accel in the base, one in the lid. Eventually, these
|
||||
* assumptions will have to be removed when we have other
|
||||
* configurations of motion sensors.
|
||||
*/
|
||||
for (i = 0; i < motion_sensor_count; ++i) {
|
||||
if (motion_sensors[i].location == LOCATION_LID)
|
||||
lid = &motion_sensors[i];
|
||||
else if (motion_sensors[i].location == LOCATION_BASE)
|
||||
base = &motion_sensors[i];
|
||||
}
|
||||
|
||||
if (lid == NULL || base == NULL) {
|
||||
CPRINTS("Invalid motion_sensors list, lid and base required");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize accelerometers. */
|
||||
ret = accel_init(ACCEL_LID);
|
||||
ret |= accel_init(ACCEL_BASE);
|
||||
ret = lid->drv->init(lid->drv_data, lid->i2c_addr);
|
||||
ret |= base->drv->init(base->drv_data, base->i2c_addr);
|
||||
|
||||
/* If accelerometers do not initialize, then end task. */
|
||||
if (ret != EC_SUCCESS) {
|
||||
@@ -212,12 +227,12 @@ void motion_sense_task(void)
|
||||
accel_interval_ms = accel_interval_ap_suspend_ms;
|
||||
|
||||
/* Set default accelerometer parameters. */
|
||||
accel_set_range(ACCEL_LID, 2, 1);
|
||||
accel_set_range(ACCEL_BASE, 2, 1);
|
||||
accel_set_resolution(ACCEL_LID, 12, 1);
|
||||
accel_set_resolution(ACCEL_BASE, 12, 1);
|
||||
accel_set_datarate(ACCEL_LID, 100000, 1);
|
||||
accel_set_datarate(ACCEL_BASE, 100000, 1);
|
||||
lid->drv->set_range(lid->drv_data, 2, 1);
|
||||
lid->drv->set_resolution(lid->drv_data, 12, 1);
|
||||
lid->drv->set_datarate(lid->drv_data, 100000, 1);
|
||||
base->drv->set_range(base->drv_data, 2, 1);
|
||||
base->drv->set_resolution(base->drv_data, 12, 1);
|
||||
base->drv->set_datarate(base->drv_data, 100000, 1);
|
||||
|
||||
/* Write to status byte to represent that accelerometers are present. */
|
||||
*lpc_status |= EC_MEMMAP_ACC_STATUS_PRESENCE_BIT;
|
||||
@@ -226,9 +241,9 @@ void motion_sense_task(void)
|
||||
ts0 = get_time();
|
||||
|
||||
/* Read all accelerations. */
|
||||
accel_read(ACCEL_LID, &acc_lid_raw[X], &acc_lid_raw[Y],
|
||||
lid->drv->read(lid->drv_data, &acc_lid_raw[X], &acc_lid_raw[Y],
|
||||
&acc_lid_raw[Z]);
|
||||
accel_read(ACCEL_BASE, &acc_base[X], &acc_base[Y],
|
||||
base->drv->read(base->drv_data, &acc_base[X], &acc_base[Y],
|
||||
&acc_base[Z]);
|
||||
|
||||
/*
|
||||
@@ -333,32 +348,27 @@ void accel_int_base(enum gpio_signal signal)
|
||||
/*****************************************************************************/
|
||||
/* Host commands */
|
||||
|
||||
/**
|
||||
* Temporary function to map host sensor IDs to EC sensor IDs.
|
||||
*
|
||||
* TODO(crosbug.com/p/27320): Eventually we need a board specific table
|
||||
* specifying which motion sensors are attached and which driver to use to
|
||||
* access that sensor. Once we have this, this function should be able to go
|
||||
* away.
|
||||
*/
|
||||
static int host_sensor_id_to_ec_sensor_id(int host_id)
|
||||
/* Function to map host sensor IDs to motion sensor. */
|
||||
static const struct motion_sensor_t
|
||||
*host_sensor_id_to_motion_sensor(int host_id)
|
||||
{
|
||||
switch (host_id) {
|
||||
case EC_MOTION_SENSOR_ACCEL_BASE:
|
||||
return ACCEL_BASE;
|
||||
return base;
|
||||
case EC_MOTION_SENSOR_ACCEL_LID:
|
||||
return ACCEL_LID;
|
||||
return lid;
|
||||
}
|
||||
|
||||
/* If no match then the EC currently doesn't support ID received. */
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int host_cmd_motion_sense(struct host_cmd_handler_args *args)
|
||||
{
|
||||
const struct ec_params_motion_sense *in = args->params;
|
||||
struct ec_response_motion_sense *out = args->response;
|
||||
int id, data;
|
||||
const struct motion_sensor_t *sensor;
|
||||
int data;
|
||||
|
||||
switch (in->cmd) {
|
||||
case MOTIONSENSE_CMD_DUMP:
|
||||
@@ -390,24 +400,25 @@ static int host_cmd_motion_sense(struct host_cmd_handler_args *args)
|
||||
* use some motion_sense data structure from the board file to
|
||||
* help fill in this response.
|
||||
*/
|
||||
id = host_sensor_id_to_ec_sensor_id(in->sensor_odr.sensor_num);
|
||||
if (id < 0)
|
||||
sensor = host_sensor_id_to_motion_sensor(
|
||||
in->sensor_odr.sensor_num);
|
||||
if (sensor == NULL)
|
||||
return EC_RES_INVALID_PARAM;
|
||||
|
||||
switch (id) {
|
||||
case ACCEL_BASE:
|
||||
if (sensor->drv->sensor_type == SENSOR_ACCELEROMETER)
|
||||
out->info.type = MOTIONSENSE_TYPE_ACCEL;
|
||||
else if (sensor->drv->sensor_type == SENSOR_GYRO)
|
||||
out->info.type = MOTIONSENSE_TYPE_GYRO;
|
||||
|
||||
if (sensor->location == LOCATION_BASE)
|
||||
out->info.location = MOTIONSENSE_LOC_BASE;
|
||||
out->info.chip = MOTIONSENSE_CHIP_KXCJ9;
|
||||
break;
|
||||
case ACCEL_LID:
|
||||
out->info.type = MOTIONSENSE_TYPE_ACCEL;
|
||||
else if (sensor->location == LOCATION_LID)
|
||||
out->info.location = MOTIONSENSE_LOC_LID;
|
||||
|
||||
if (sensor->drv->chip_type == CHIP_KXCJ9)
|
||||
out->info.chip = MOTIONSENSE_CHIP_KXCJ9;
|
||||
break;
|
||||
default:
|
||||
return EC_RES_INVALID_PARAM;
|
||||
}
|
||||
else if (sensor->drv->chip_type == CHIP_LSM6DS0)
|
||||
out->info.chip = MOTIONSENSE_CHIP_LSM6DS0;
|
||||
|
||||
args->response_size = sizeof(out->info);
|
||||
break;
|
||||
@@ -436,21 +447,24 @@ static int host_cmd_motion_sense(struct host_cmd_handler_args *args)
|
||||
|
||||
case MOTIONSENSE_CMD_SENSOR_ODR:
|
||||
/* Verify sensor number is valid. */
|
||||
id = host_sensor_id_to_ec_sensor_id(in->sensor_odr.sensor_num);
|
||||
if (id < 0)
|
||||
sensor = host_sensor_id_to_motion_sensor(
|
||||
in->sensor_odr.sensor_num);
|
||||
if (sensor == NULL)
|
||||
return EC_RES_INVALID_PARAM;
|
||||
|
||||
/* Set new datarate if the data arg has a value. */
|
||||
if (in->sensor_odr.data != EC_MOTION_SENSE_NO_VALUE) {
|
||||
if (accel_set_datarate(id, in->sensor_odr.data,
|
||||
in->sensor_odr.roundup) != EC_SUCCESS) {
|
||||
if (sensor->drv->set_datarate(sensor->drv_data,
|
||||
in->sensor_odr.data,
|
||||
in->sensor_odr.roundup)
|
||||
!= EC_SUCCESS) {
|
||||
CPRINTS("MS bad sensor rate %d",
|
||||
in->sensor_odr.data);
|
||||
return EC_RES_INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
accel_get_datarate(id, &data);
|
||||
sensor->drv->get_datarate(sensor->drv_data, &data);
|
||||
out->sensor_odr.ret = data;
|
||||
|
||||
args->response_size = sizeof(out->sensor_odr);
|
||||
@@ -458,21 +472,24 @@ static int host_cmd_motion_sense(struct host_cmd_handler_args *args)
|
||||
|
||||
case MOTIONSENSE_CMD_SENSOR_RANGE:
|
||||
/* Verify sensor number is valid. */
|
||||
id = host_sensor_id_to_ec_sensor_id(in->sensor_odr.sensor_num);
|
||||
if (id < 0)
|
||||
sensor = host_sensor_id_to_motion_sensor(
|
||||
in->sensor_odr.sensor_num);
|
||||
if (sensor == NULL)
|
||||
return EC_RES_INVALID_PARAM;
|
||||
|
||||
/* Set new datarate if the data arg has a value. */
|
||||
if (in->sensor_range.data != EC_MOTION_SENSE_NO_VALUE) {
|
||||
if (accel_set_range(id, in->sensor_range.data,
|
||||
in->sensor_range.roundup) != EC_SUCCESS) {
|
||||
if (sensor->drv->set_range(sensor->drv_data,
|
||||
in->sensor_range.data,
|
||||
in->sensor_range.roundup)
|
||||
!= EC_SUCCESS) {
|
||||
CPRINTS("MS bad sensor range %d",
|
||||
in->sensor_range.data);
|
||||
return EC_RES_INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
accel_get_range(id, &data);
|
||||
sensor->drv->get_range(sensor->drv_data, &data);
|
||||
out->sensor_range.ret = data;
|
||||
|
||||
args->response_size = sizeof(out->sensor_range);
|
||||
@@ -548,14 +565,16 @@ static int command_accelrange(int argc, char **argv)
|
||||
{
|
||||
char *e;
|
||||
int id, data, round = 1;
|
||||
struct motion_sensor_t *sensor;
|
||||
|
||||
if (argc < 2 || argc > 4)
|
||||
return EC_ERROR_PARAM_COUNT;
|
||||
|
||||
/* First argument is sensor id. */
|
||||
id = strtoi(argv[1], &e, 0);
|
||||
if (*e || id < 0 || id > ACCEL_COUNT)
|
||||
if (*e || id < 0 || id > motion_sensor_count)
|
||||
return EC_ERROR_PARAM1;
|
||||
sensor = motion_sensors[id];
|
||||
|
||||
if (argc >= 3) {
|
||||
/* Second argument is data to write. */
|
||||
@@ -574,10 +593,12 @@ static int command_accelrange(int argc, char **argv)
|
||||
* Write new range, if it returns invalid arg, then return
|
||||
* a parameter error.
|
||||
*/
|
||||
if (accel_set_range(id, data, round) == EC_ERROR_INVAL)
|
||||
if (sensor->drv->set_range(sensor->drv_data,
|
||||
data,
|
||||
round) == EC_ERROR_INVAL)
|
||||
return EC_ERROR_PARAM2;
|
||||
} else {
|
||||
accel_get_range(id, &data);
|
||||
sensor->drv->get_range(sensor->drv_data, &data);
|
||||
ccprintf("Range for sensor %d: %d\n", id, data);
|
||||
}
|
||||
|
||||
@@ -591,14 +612,16 @@ static int command_accelresolution(int argc, char **argv)
|
||||
{
|
||||
char *e;
|
||||
int id, data, round = 1;
|
||||
struct motion_sensor_t *sensor;
|
||||
|
||||
if (argc < 2 || argc > 4)
|
||||
return EC_ERROR_PARAM_COUNT;
|
||||
|
||||
/* First argument is sensor id. */
|
||||
id = strtoi(argv[1], &e, 0);
|
||||
if (*e || id < 0 || id > ACCEL_COUNT)
|
||||
if (*e || id < 0 || id > motion_sensor_count)
|
||||
return EC_ERROR_PARAM1;
|
||||
sensor = motion_sensors[id];
|
||||
|
||||
if (argc >= 3) {
|
||||
/* Second argument is data to write. */
|
||||
@@ -617,10 +640,11 @@ static int command_accelresolution(int argc, char **argv)
|
||||
* Write new resolution, if it returns invalid arg, then
|
||||
* return a parameter error.
|
||||
*/
|
||||
if (accel_set_resolution(id, data, round) == EC_ERROR_INVAL)
|
||||
if (sensor->drv->set_resolution(sensor->drv_data, data, round)
|
||||
== EC_ERROR_INVAL)
|
||||
return EC_ERROR_PARAM2;
|
||||
} else {
|
||||
accel_get_resolution(id, &data);
|
||||
sensor->drv->get_resolution(sensor->drv_data, &data);
|
||||
ccprintf("Resolution for sensor %d: %d\n", id, data);
|
||||
}
|
||||
|
||||
@@ -634,14 +658,16 @@ static int command_acceldatarate(int argc, char **argv)
|
||||
{
|
||||
char *e;
|
||||
int id, data, round = 1;
|
||||
struct motion_sensor_t *sensor;
|
||||
|
||||
if (argc < 2 || argc > 4)
|
||||
return EC_ERROR_PARAM_COUNT;
|
||||
|
||||
/* First argument is sensor id. */
|
||||
id = strtoi(argv[1], &e, 0);
|
||||
if (*e || id < 0 || id > ACCEL_COUNT)
|
||||
if (*e || id < 0 || id > motion_sensor_count)
|
||||
return EC_ERROR_PARAM1;
|
||||
sensor = motion_sensors[id];
|
||||
|
||||
if (argc >= 3) {
|
||||
/* Second argument is data to write. */
|
||||
@@ -660,10 +686,11 @@ static int command_acceldatarate(int argc, char **argv)
|
||||
* Write new data rate, if it returns invalid arg, then
|
||||
* return a parameter error.
|
||||
*/
|
||||
if (accel_set_datarate(id, data, round) == EC_ERROR_INVAL)
|
||||
if (sensor->drv->set_datarate(sensor->drv_data, data, round)
|
||||
== EC_ERROR_INVAL)
|
||||
return EC_ERROR_PARAM2;
|
||||
} else {
|
||||
accel_get_datarate(id, &data);
|
||||
sensor->drv->get_datarate(sensor->drv_data, &data);
|
||||
ccprintf("Data rate for sensor %d: %d\n", id, data);
|
||||
}
|
||||
|
||||
@@ -678,21 +705,23 @@ static int command_accelerometer_interrupt(int argc, char **argv)
|
||||
{
|
||||
char *e;
|
||||
int id, thresh;
|
||||
struct motion_sensor_t *sensor;
|
||||
|
||||
if (argc != 3)
|
||||
return EC_ERROR_PARAM_COUNT;
|
||||
|
||||
/* First argument is id. */
|
||||
id = strtoi(argv[1], &e, 0);
|
||||
if (*e || id < 0 || id >= ACCEL_COUNT)
|
||||
if (*e || id < 0 || id >= motion_sensor_count)
|
||||
return EC_ERROR_PARAM1;
|
||||
sensor = motion_sensors[id];
|
||||
|
||||
/* Second argument is interrupt threshold. */
|
||||
thresh = strtoi(argv[2], &e, 0);
|
||||
if (*e)
|
||||
return EC_ERROR_PARAM2;
|
||||
|
||||
accel_set_interrupt(id, thresh);
|
||||
sensor->drv->set_interrupt(drv_data, thresh);
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
/* KXCJ9 gsensor module for Chrome EC */
|
||||
|
||||
#include "accelerometer.h"
|
||||
#include "accelgyro.h"
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "driver/accel_kxcj9.h"
|
||||
@@ -31,20 +31,20 @@ struct accel_param_pair {
|
||||
};
|
||||
|
||||
/* List of range values in +/-G's and their associated register values. */
|
||||
const struct accel_param_pair ranges[] = {
|
||||
static const struct accel_param_pair ranges[] = {
|
||||
{2, KXCJ9_GSEL_2G},
|
||||
{4, KXCJ9_GSEL_4G},
|
||||
{8, KXCJ9_GSEL_8G_14BIT}
|
||||
};
|
||||
|
||||
/* List of resolution values in bits and their associated register values. */
|
||||
const struct accel_param_pair resolutions[] = {
|
||||
static const struct accel_param_pair resolutions[] = {
|
||||
{8, KXCJ9_RES_8BIT},
|
||||
{12, KXCJ9_RES_12BIT}
|
||||
};
|
||||
|
||||
/* List of ODR values in mHz and their associated register values. */
|
||||
const struct accel_param_pair datarates[] = {
|
||||
static const struct accel_param_pair datarates[] = {
|
||||
{781, KXCJ9_OSA_0_781HZ},
|
||||
{1563, KXCJ9_OSA_1_563HZ},
|
||||
{3125, KXCJ9_OSA_3_125HZ},
|
||||
@@ -59,24 +59,6 @@ const struct accel_param_pair datarates[] = {
|
||||
{1600000, KXCJ9_OSA_1600_HZ}
|
||||
};
|
||||
|
||||
/* Current range of each accelerometer. The value is an index into ranges[]. */
|
||||
static int sensor_range[ACCEL_COUNT] = {0, 0};
|
||||
|
||||
/*
|
||||
* Current resolution of each accelerometer. The value is an index into
|
||||
* resolutions[].
|
||||
*/
|
||||
static int sensor_resolution[ACCEL_COUNT] = {1, 1};
|
||||
|
||||
/*
|
||||
* Current output data rate of each accelerometer. The value is an index into
|
||||
* datarates[].
|
||||
*/
|
||||
static int sensor_datarate[ACCEL_COUNT] = {6, 6};
|
||||
|
||||
|
||||
static struct mutex accel_mutex[ACCEL_COUNT];
|
||||
|
||||
/**
|
||||
* Find index into a accel_param_pair that matches the given engineering value
|
||||
* passed in. The round_up flag is used to specify whether to round up or down.
|
||||
@@ -126,12 +108,12 @@ static int raw_write8(const int addr, const int reg, int data)
|
||||
*
|
||||
* Note: This is intended to be called in a pair with enable_sensor().
|
||||
*
|
||||
* @id Sensor index
|
||||
* @data Pointer to motion sensor data
|
||||
* @ctrl1 Pointer to location to store KXCJ9_CTRL1 register after disabling
|
||||
*
|
||||
* @return EC_SUCCESS if successful, EC_ERROR_* otherwise
|
||||
*/
|
||||
static int disable_sensor(const enum accel_id id, int *ctrl1)
|
||||
static int disable_sensor(struct kxcj9_data *data, int *ctrl1)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -139,7 +121,7 @@ static int disable_sensor(const enum accel_id id, int *ctrl1)
|
||||
* Read the current state of the ctrl1 register so that we can restore
|
||||
* it later.
|
||||
*/
|
||||
ret = raw_read8(accel_addr[id], KXCJ9_CTRL1, ctrl1);
|
||||
ret = raw_read8(data->accel_addr, KXCJ9_CTRL1, ctrl1);
|
||||
if (ret != EC_SUCCESS)
|
||||
return ret;
|
||||
|
||||
@@ -147,13 +129,13 @@ static int disable_sensor(const enum accel_id id, int *ctrl1)
|
||||
* Before disabling the sensor, acquire mutex to prevent another task
|
||||
* from attempting to access accel parameters until we enable sensor.
|
||||
*/
|
||||
mutex_lock(&accel_mutex[id]);
|
||||
mutex_lock(&data->accel_mutex);
|
||||
|
||||
/* Disable sensor. */
|
||||
*ctrl1 &= ~KXCJ9_CTRL1_PC1;
|
||||
ret = raw_write8(accel_addr[id], KXCJ9_CTRL1, *ctrl1);
|
||||
ret = raw_write8(data->accel_addr, KXCJ9_CTRL1, *ctrl1);
|
||||
if (ret != EC_SUCCESS) {
|
||||
mutex_unlock(&accel_mutex[id]);
|
||||
mutex_unlock(&data->accel_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -165,178 +147,166 @@ static int disable_sensor(const enum accel_id id, int *ctrl1)
|
||||
*
|
||||
* Note: This is intended to be called in a pair with disable_sensor().
|
||||
*
|
||||
* @id Sensor index
|
||||
* @data Pointer to motion sensor data
|
||||
* @ctrl1 Value of KXCJ9_CTRL1 register to write to sensor
|
||||
*
|
||||
* @return EC_SUCCESS if successful, EC_ERROR_* otherwise
|
||||
*/
|
||||
static int enable_sensor(const enum accel_id id, const int ctrl1)
|
||||
static int enable_sensor(struct kxcj9_data *data, const int ctrl1)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < SENSOR_ENABLE_ATTEMPTS; i++) {
|
||||
/* Enable accelerometer based on ctrl1 value. */
|
||||
ret = raw_write8(accel_addr[id], KXCJ9_CTRL1,
|
||||
ret = raw_write8(data->accel_addr, KXCJ9_CTRL1,
|
||||
ctrl1 | KXCJ9_CTRL1_PC1);
|
||||
|
||||
/* On first success, we are done. */
|
||||
if (ret == EC_SUCCESS) {
|
||||
mutex_unlock(&accel_mutex[id]);
|
||||
mutex_unlock(&data->accel_mutex);
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Release mutex. */
|
||||
mutex_unlock(&accel_mutex[id]);
|
||||
mutex_unlock(&data->accel_mutex);
|
||||
|
||||
/* Cannot enable accel, print warning and return an error. */
|
||||
CPRINTF("Error trying to enable accelerometer %d\n", id);
|
||||
CPRINTF("Error trying to enable accelerometer\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int accel_set_range(const enum accel_id id, const int range, const int rnd)
|
||||
static int accel_set_range(void *drv_data,
|
||||
const int range,
|
||||
const int rnd)
|
||||
{
|
||||
int ret, ctrl1, ctrl1_new, index;
|
||||
|
||||
/* Check for valid id. */
|
||||
if (id < 0 || id >= ACCEL_COUNT)
|
||||
return EC_ERROR_INVAL;
|
||||
struct kxcj9_data *data = (struct kxcj9_data *)drv_data;
|
||||
|
||||
/* Find index for interface pair matching the specified range. */
|
||||
index = find_param_index(range, rnd, ranges, ARRAY_SIZE(ranges));
|
||||
|
||||
/* Disable the sensor to allow for changing of critical parameters. */
|
||||
ret = disable_sensor(id, &ctrl1);
|
||||
ret = disable_sensor(data, &ctrl1);
|
||||
if (ret != EC_SUCCESS)
|
||||
return ret;
|
||||
|
||||
/* Determine new value of CTRL1 reg and attempt to write it. */
|
||||
ctrl1_new = (ctrl1 & ~KXCJ9_GSEL_ALL) | ranges[index].reg;
|
||||
ret = raw_write8(accel_addr[id], KXCJ9_CTRL1, ctrl1_new);
|
||||
ret = raw_write8(data->accel_addr, KXCJ9_CTRL1, ctrl1_new);
|
||||
|
||||
/* If successfully written, then save the range. */
|
||||
if (ret == EC_SUCCESS) {
|
||||
sensor_range[id] = index;
|
||||
data->sensor_range = index;
|
||||
ctrl1 = ctrl1_new;
|
||||
}
|
||||
|
||||
/* Re-enable the sensor. */
|
||||
if (enable_sensor(id, ctrl1) != EC_SUCCESS)
|
||||
if (enable_sensor(data, ctrl1) != EC_SUCCESS)
|
||||
return EC_ERROR_UNKNOWN;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int accel_get_range(const enum accel_id id, int * const range)
|
||||
static int accel_get_range(void *drv_data, int * const range)
|
||||
{
|
||||
/* Check for valid id. */
|
||||
if (id < 0 || id >= ACCEL_COUNT)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
*range = ranges[sensor_range[id]].val;
|
||||
struct kxcj9_data *data = (struct kxcj9_data *)drv_data;
|
||||
*range = ranges[data->sensor_range].val;
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
int accel_set_resolution(const enum accel_id id, const int res, const int rnd)
|
||||
static int accel_set_resolution(void *drv_data,
|
||||
const int res,
|
||||
const int rnd)
|
||||
{
|
||||
int ret, ctrl1, ctrl1_new, index;
|
||||
|
||||
/* Check for valid id. */
|
||||
if (id < 0 || id >= ACCEL_COUNT)
|
||||
return EC_ERROR_INVAL;
|
||||
struct kxcj9_data *data = (struct kxcj9_data *)drv_data;
|
||||
|
||||
/* Find index for interface pair matching the specified resolution. */
|
||||
index = find_param_index(res, rnd, resolutions,
|
||||
ARRAY_SIZE(resolutions));
|
||||
|
||||
/* Disable the sensor to allow for changing of critical parameters. */
|
||||
ret = disable_sensor(id, &ctrl1);
|
||||
ret = disable_sensor(data, &ctrl1);
|
||||
if (ret != EC_SUCCESS)
|
||||
return ret;
|
||||
|
||||
/* Determine new value of CTRL1 reg and attempt to write it. */
|
||||
ctrl1_new = (ctrl1 & ~KXCJ9_RES_12BIT) | resolutions[index].reg;
|
||||
ret = raw_write8(accel_addr[id], KXCJ9_CTRL1, ctrl1_new);
|
||||
ret = raw_write8(data->accel_addr, KXCJ9_CTRL1, ctrl1_new);
|
||||
|
||||
/* If successfully written, then save the range. */
|
||||
if (ret == EC_SUCCESS) {
|
||||
sensor_resolution[id] = index;
|
||||
data->sensor_resolution = index;
|
||||
ctrl1 = ctrl1_new;
|
||||
}
|
||||
|
||||
/* Re-enable the sensor. */
|
||||
if (enable_sensor(id, ctrl1) != EC_SUCCESS)
|
||||
if (enable_sensor(data, ctrl1) != EC_SUCCESS)
|
||||
return EC_ERROR_UNKNOWN;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int accel_get_resolution(const enum accel_id id, int * const res)
|
||||
static int accel_get_resolution(void *drv_data, int * const res)
|
||||
{
|
||||
/* Check for valid id. */
|
||||
if (id < 0 || id >= ACCEL_COUNT)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
*res = resolutions[sensor_resolution[id]].val;
|
||||
struct kxcj9_data *data = (struct kxcj9_data *)drv_data;
|
||||
*res = resolutions[data->sensor_resolution].val;
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
int accel_set_datarate(const enum accel_id id, const int rate, const int rnd)
|
||||
static int accel_set_datarate(void *drv_data,
|
||||
const int rate,
|
||||
const int rnd)
|
||||
{
|
||||
int ret, ctrl1, index;
|
||||
|
||||
/* Check for valid id. */
|
||||
if (id < 0 || id >= ACCEL_COUNT)
|
||||
return EC_ERROR_INVAL;
|
||||
struct kxcj9_data *data = (struct kxcj9_data *)drv_data;
|
||||
|
||||
/* Find index for interface pair matching the specified rate. */
|
||||
index = find_param_index(rate, rnd, datarates, ARRAY_SIZE(datarates));
|
||||
|
||||
/* Disable the sensor to allow for changing of critical parameters. */
|
||||
ret = disable_sensor(id, &ctrl1);
|
||||
ret = disable_sensor(data, &ctrl1);
|
||||
if (ret != EC_SUCCESS)
|
||||
return ret;
|
||||
|
||||
/* Set output data rate. */
|
||||
ret = raw_write8(accel_addr[id], KXCJ9_DATA_CTRL,
|
||||
ret = raw_write8(data->accel_addr, KXCJ9_DATA_CTRL,
|
||||
datarates[index].reg);
|
||||
|
||||
/* If successfully written, then save the range. */
|
||||
if (ret == EC_SUCCESS)
|
||||
sensor_datarate[id] = index;
|
||||
data->sensor_datarate = index;
|
||||
|
||||
/* Re-enable the sensor. */
|
||||
if (enable_sensor(id, ctrl1) != EC_SUCCESS)
|
||||
if (enable_sensor(data, ctrl1) != EC_SUCCESS)
|
||||
return EC_ERROR_UNKNOWN;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int accel_get_datarate(const enum accel_id id, int * const rate)
|
||||
static int accel_get_datarate(void *drv_data, int * const rate)
|
||||
{
|
||||
/* Check for valid id. */
|
||||
if (id < 0 || id >= ACCEL_COUNT)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
*rate = datarates[sensor_datarate[id]].val;
|
||||
struct kxcj9_data *data = (struct kxcj9_data *)drv_data;
|
||||
*rate = datarates[data->sensor_datarate].val;
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_ACCEL_INTERRUPTS
|
||||
int accel_set_interrupt(const enum accel_id id, unsigned int threshold)
|
||||
static int accel_set_interrupt(void *drv_data, unsigned int threshold)
|
||||
{
|
||||
int ctrl1, tmp, ret;
|
||||
struct kxcj9_data *data = (struct kxcj9_data *)drv_data;
|
||||
|
||||
/* Disable the sensor to allow for changing of critical parameters. */
|
||||
ret = disable_sensor(id, &ctrl1);
|
||||
ret = disable_sensor(data, &ctrl1);
|
||||
if (ret != EC_SUCCESS)
|
||||
return ret;
|
||||
|
||||
/* Set interrupt timer to 1 so it wakes up immediately. */
|
||||
ret = raw_write8(accel_addr[id], KXCJ9_WAKEUP_TIMER, 1);
|
||||
ret = raw_write8(data->accel_addr, KXCJ9_WAKEUP_TIMER, 1);
|
||||
if (ret != EC_SUCCESS)
|
||||
goto error_enable_sensor;
|
||||
|
||||
@@ -345,7 +315,7 @@ int accel_set_interrupt(const enum accel_id id, unsigned int threshold)
|
||||
* first we need to divide by 16 to get the value to send.
|
||||
*/
|
||||
threshold >>= 4;
|
||||
ret = raw_write8(accel_addr[id], KXCJ9_WAKEUP_THRESHOLD, threshold);
|
||||
ret = raw_write8(data->accel_addr, KXCJ9_WAKEUP_THRESHOLD, threshold);
|
||||
if (ret != EC_SUCCESS)
|
||||
goto error_enable_sensor;
|
||||
|
||||
@@ -354,11 +324,11 @@ int accel_set_interrupt(const enum accel_id id, unsigned int threshold)
|
||||
* function is called once, the interrupt stays enabled and it is
|
||||
* only necessary to clear KXCJ9_INT_REL to allow the next interrupt.
|
||||
*/
|
||||
ret = raw_read8(accel_addr[id], KXCJ9_INT_CTRL1, &tmp);
|
||||
ret = raw_read8(data->accel_addr, KXCJ9_INT_CTRL1, &tmp);
|
||||
if (ret != EC_SUCCESS)
|
||||
goto error_enable_sensor;
|
||||
if (!(tmp & KXCJ9_INT_CTRL1_IEN)) {
|
||||
ret = raw_write8(accel_addr[id], KXCJ9_INT_CTRL1,
|
||||
ret = raw_write8(data->accel_addr, KXCJ9_INT_CTRL1,
|
||||
tmp | KXCJ9_INT_CTRL1_IEN);
|
||||
if (ret != EC_SUCCESS)
|
||||
goto error_enable_sensor;
|
||||
@@ -369,41 +339,40 @@ int accel_set_interrupt(const enum accel_id id, unsigned int threshold)
|
||||
* Note: this register latches motion detected above threshold. Once
|
||||
* latched, no interrupt can occur until this register is cleared.
|
||||
*/
|
||||
ret = raw_read8(accel_addr[id], KXCJ9_INT_REL, &tmp);
|
||||
ret = raw_read8(data->accel_addr, KXCJ9_INT_REL, &tmp);
|
||||
|
||||
error_enable_sensor:
|
||||
/* Re-enable the sensor. */
|
||||
if (enable_sensor(id, ctrl1) != EC_SUCCESS)
|
||||
if (enable_sensor(data, ctrl1) != EC_SUCCESS)
|
||||
return EC_ERROR_UNKNOWN;
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
int accel_read(const enum accel_id id, int * const x_acc, int * const y_acc,
|
||||
int * const z_acc)
|
||||
static int accel_read(void *drv_data,
|
||||
int * const x_acc,
|
||||
int * const y_acc,
|
||||
int * const z_acc)
|
||||
{
|
||||
uint8_t acc[6];
|
||||
uint8_t reg = KXCJ9_XOUT_L;
|
||||
int ret, multiplier;
|
||||
|
||||
/* Check for valid id. */
|
||||
if (id < 0 || id >= ACCEL_COUNT)
|
||||
return EC_ERROR_INVAL;
|
||||
struct kxcj9_data *data = (struct kxcj9_data *)drv_data;
|
||||
|
||||
/* Read 6 bytes starting at KXCJ9_XOUT_L. */
|
||||
mutex_lock(&accel_mutex[id]);
|
||||
mutex_lock(&data->accel_mutex);
|
||||
i2c_lock(I2C_PORT_ACCEL, 1);
|
||||
ret = i2c_xfer(I2C_PORT_ACCEL, accel_addr[id], ®, 1, acc, 6,
|
||||
ret = i2c_xfer(I2C_PORT_ACCEL, data->accel_addr, ®, 1, acc, 6,
|
||||
I2C_XFER_SINGLE);
|
||||
i2c_lock(I2C_PORT_ACCEL, 0);
|
||||
mutex_unlock(&accel_mutex[id]);
|
||||
mutex_unlock(&data->accel_mutex);
|
||||
|
||||
if (ret != EC_SUCCESS)
|
||||
return ret;
|
||||
|
||||
/* Determine multiplier based on stored range. */
|
||||
switch (ranges[sensor_range[id]].reg) {
|
||||
switch (ranges[data->sensor_range].reg) {
|
||||
case KXCJ9_GSEL_2G:
|
||||
multiplier = 1;
|
||||
break;
|
||||
@@ -436,17 +405,23 @@ int accel_read(const enum accel_id id, int * const x_acc, int * const y_acc,
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
int accel_init(const enum accel_id id)
|
||||
static int accel_init(void *drv_data, int i2c_addr)
|
||||
{
|
||||
int ret = EC_SUCCESS;
|
||||
int cnt = 0, ctrl1, ctrl2;
|
||||
struct kxcj9_data *data = (struct kxcj9_data *)drv_data;
|
||||
|
||||
/* Check for valid id. */
|
||||
if (id < 0 || id >= ACCEL_COUNT)
|
||||
if (data == NULL)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
memset(&data->accel_mutex, sizeof(struct mutex), 0);
|
||||
data->sensor_range = 0;
|
||||
data->sensor_datarate = 6;
|
||||
data->sensor_resolution = 1;
|
||||
data->accel_addr = i2c_addr;
|
||||
|
||||
/* Disable the sensor to allow for changing of critical parameters. */
|
||||
ret = disable_sensor(id, &ctrl1);
|
||||
ret = disable_sensor(data, &ctrl1);
|
||||
if (ret != EC_SUCCESS)
|
||||
return ret;
|
||||
|
||||
@@ -455,13 +430,13 @@ int accel_init(const enum accel_id id)
|
||||
* the sensor is unknown here. Initiate software reset to restore
|
||||
* sensor to default.
|
||||
*/
|
||||
ret = raw_write8(accel_addr[id], KXCJ9_CTRL2, KXCJ9_CTRL2_SRST);
|
||||
ret = raw_write8(data->accel_addr, KXCJ9_CTRL2, KXCJ9_CTRL2_SRST);
|
||||
if (ret != EC_SUCCESS)
|
||||
return ret;
|
||||
|
||||
/* Wait until software reset is complete or timeout. */
|
||||
while (1) {
|
||||
ret = raw_read8(accel_addr[id], KXCJ9_CTRL2, &ctrl2);
|
||||
ret = raw_read8(data->accel_addr, KXCJ9_CTRL2, &ctrl2);
|
||||
|
||||
/* Reset complete. */
|
||||
if (ret == EC_SUCCESS && !(ctrl2 & KXCJ9_CTRL2_SRST))
|
||||
@@ -476,23 +451,25 @@ int accel_init(const enum accel_id id)
|
||||
}
|
||||
|
||||
/* Set resolution and range. */
|
||||
ctrl1 = resolutions[sensor_resolution[id]].reg |
|
||||
ranges[sensor_range[id]].reg;
|
||||
ctrl1 = resolutions[data->sensor_resolution].reg |
|
||||
ranges[data->sensor_range].reg;
|
||||
#ifdef CONFIG_ACCEL_INTERRUPTS
|
||||
/* Enable wake up (motion detect) functionality. */
|
||||
ctrl1 |= KXCJ9_CTRL1_WUFE;
|
||||
#endif
|
||||
ret = raw_write8(accel_addr[id], KXCJ9_CTRL1, ctrl1);
|
||||
ret = raw_write8(data->accel_addr, KXCJ9_CTRL1, ctrl1);
|
||||
|
||||
#ifdef CONFIG_ACCEL_INTERRUPTS
|
||||
/* Set interrupt polarity to rising edge and keep interrupt disabled. */
|
||||
ret |= raw_write8(accel_addr[id], KXCJ9_INT_CTRL1, KXCJ9_INT_CTRL1_IEA);
|
||||
ret |= raw_write8(data->accel_addr,
|
||||
KXCJ9_INT_CTRL1,
|
||||
KXCJ9_INT_CTRL1_IEA);
|
||||
|
||||
/* Set output data rate for wake-up interrupt function. */
|
||||
ret |= raw_write8(accel_addr[id], KXCJ9_CTRL2, KXCJ9_OWUF_100_0HZ);
|
||||
ret |= raw_write8(data->accel_addr, KXCJ9_CTRL2, KXCJ9_OWUF_100_0HZ);
|
||||
|
||||
/* Set interrupt to trigger on motion on any axis. */
|
||||
ret |= raw_write8(accel_addr[id], KXCJ9_INT_CTRL2,
|
||||
ret |= raw_write8(data->accel_addr, KXCJ9_INT_CTRL2,
|
||||
KXCJ9_INT_SRC2_XNWU | KXCJ9_INT_SRC2_XPWU |
|
||||
KXCJ9_INT_SRC2_YNWU | KXCJ9_INT_SRC2_YPWU |
|
||||
KXCJ9_INT_SRC2_ZNWU | KXCJ9_INT_SRC2_ZPWU);
|
||||
@@ -506,11 +483,27 @@ int accel_init(const enum accel_id id)
|
||||
#endif
|
||||
|
||||
/* Set output data rate. */
|
||||
ret |= raw_write8(accel_addr[id], KXCJ9_DATA_CTRL,
|
||||
datarates[sensor_datarate[id]].reg);
|
||||
ret |= raw_write8(data->accel_addr, KXCJ9_DATA_CTRL,
|
||||
datarates[data->sensor_datarate].reg);
|
||||
|
||||
/* Enable the sensor. */
|
||||
ret |= enable_sensor(id, ctrl1);
|
||||
ret |= enable_sensor(data, ctrl1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const struct accelgyro_info accel_kxcj9 = {
|
||||
.chip_type = CHIP_KXCJ9,
|
||||
.sensor_type = SENSOR_ACCELEROMETER,
|
||||
.init = accel_init,
|
||||
.read = accel_read,
|
||||
.set_range = accel_set_range,
|
||||
.get_range = accel_get_range,
|
||||
.set_resolution = accel_set_resolution,
|
||||
.get_resolution = accel_get_resolution,
|
||||
.set_datarate = accel_set_datarate,
|
||||
.get_datarate = accel_get_datarate,
|
||||
#ifdef CONFIG_ACCEL_INTERRUPTS
|
||||
.set_interrupt = accel_set_interrupt,
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#ifndef __CROS_EC_ACCEL_KXCJ9_H
|
||||
#define __CROS_EC_ACCEL_KXCJ9_H
|
||||
|
||||
#include "task.h"
|
||||
|
||||
/*
|
||||
* 7-bit address is 000111Xb. Where 'X' is determined
|
||||
* by the voltage on the ADDR pin.
|
||||
@@ -99,17 +101,18 @@
|
||||
#define KXCJ9_OSA_800_0HZ 6
|
||||
#define KXCJ9_OSA_1600_HZ 7
|
||||
|
||||
struct kxcj9_data {
|
||||
struct mutex accel_mutex;
|
||||
/* Current range of accelerometer. */
|
||||
int sensor_range;
|
||||
/* Current output data rate of accelerometer. */
|
||||
int sensor_datarate;
|
||||
/* Current resolution of accelerometer. */
|
||||
int sensor_resolution;
|
||||
/* Device address. */
|
||||
int accel_addr;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ACCEL_INTERRUPTS
|
||||
/**
|
||||
* Setup a one-time accel interrupt. If the threshold is low enough, the
|
||||
* interrupt may trigger due simply to noise and not any real motion. If the
|
||||
* threshold is 0, the interrupt will fire immediately.
|
||||
*
|
||||
* @param id Target accelerometer
|
||||
* @param threshold Threshold for interrupt in units of counts.
|
||||
*/
|
||||
int accel_set_interrupt(const enum accel_id id, unsigned int threshold);
|
||||
#endif
|
||||
extern const struct accelgyro_info accel_kxcj9;
|
||||
|
||||
#endif /* __CROS_EC_ACCEL_KXCJ9_H */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
/* LSM6DS0 accelerometer and gyro module for Chrome EC */
|
||||
|
||||
#include "accelerometer.h"
|
||||
#include "accelgyro.h"
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "driver/accelgyro_lsm6ds0.h"
|
||||
@@ -24,14 +24,14 @@ struct accel_param_pair {
|
||||
};
|
||||
|
||||
/* List of range values in +/-G's and their associated register values. */
|
||||
const struct accel_param_pair ranges[] = {
|
||||
static const struct accel_param_pair ranges[] = {
|
||||
{2, LSM6DS0_GSEL_2G},
|
||||
{4, LSM6DS0_GSEL_4G},
|
||||
{8, LSM6DS0_GSEL_8G}
|
||||
};
|
||||
|
||||
/* List of ODR values in mHz and their associated register values. */
|
||||
const struct accel_param_pair datarates[] = {
|
||||
static const struct accel_param_pair datarates[] = {
|
||||
{10000, LSM6DS0_ODR_10HZ},
|
||||
{50000, LSM6DS0_ODR_50HZ},
|
||||
{119000, LSM6DS0_ODR_119HZ},
|
||||
@@ -40,17 +40,6 @@ const struct accel_param_pair datarates[] = {
|
||||
{952000, LSM6DS0_ODR_982HZ}
|
||||
};
|
||||
|
||||
/* Current range of each accelerometer. The value is an index into ranges[]. */
|
||||
static int sensor_range[ACCEL_COUNT] = {0, 0};
|
||||
|
||||
/*
|
||||
* Current output data rate of each accelerometer. The value is an index into
|
||||
* datarates[].
|
||||
*/
|
||||
static int sensor_datarate[ACCEL_COUNT] = {1, 1};
|
||||
|
||||
static struct mutex accel_mutex[ACCEL_COUNT];
|
||||
|
||||
/**
|
||||
* Find index into a accel_param_pair that matches the given engineering value
|
||||
* passed in. The round_up flag is used to specify whether to round up or down.
|
||||
@@ -94,9 +83,12 @@ static int raw_write8(const int addr, const int reg, int data)
|
||||
return i2c_write8(I2C_PORT_ACCEL, addr, reg, data);
|
||||
}
|
||||
|
||||
int accel_set_range(const enum accel_id id, const int range, const int rnd)
|
||||
static int accel_set_range(void *drv_data,
|
||||
const int range,
|
||||
const int rnd)
|
||||
{
|
||||
int ret, index, ctrl_reg6;
|
||||
struct lsm6ds0_data *data = (struct lsm6ds0_data *)drv_data;
|
||||
|
||||
/* Find index for interface pair matching the specified range. */
|
||||
index = find_param_index(range, rnd, ranges, ARRAY_SIZE(ranges));
|
||||
@@ -105,61 +97,52 @@ int accel_set_range(const enum accel_id id, const int range, const int rnd)
|
||||
* Lock accel resource to prevent another task from attempting
|
||||
* to write accel parameters until we are done.
|
||||
*/
|
||||
mutex_lock(&accel_mutex[id]);
|
||||
mutex_lock(&data->accel_mutex);
|
||||
|
||||
ret = raw_read8(accel_addr[id], LSM6DS0_CTRL_REG6_XL, &ctrl_reg6);
|
||||
ret = raw_read8(data->accel_addr, LSM6DS0_CTRL_REG6_XL, &ctrl_reg6);
|
||||
if (ret != EC_SUCCESS)
|
||||
goto accel_cleanup;
|
||||
|
||||
ctrl_reg6 = (ctrl_reg6 & ~LSM6DS0_GSEL_ALL) | ranges[index].reg;
|
||||
ret = raw_write8(accel_addr[id], LSM6DS0_CTRL_REG6_XL, ctrl_reg6);
|
||||
ret = raw_write8(data->accel_addr, LSM6DS0_CTRL_REG6_XL, ctrl_reg6);
|
||||
|
||||
accel_cleanup:
|
||||
/* Unlock accel resource and save new range if written successfully. */
|
||||
mutex_unlock(&accel_mutex[id]);
|
||||
mutex_unlock(&data->accel_mutex);
|
||||
if (ret == EC_SUCCESS)
|
||||
sensor_range[id] = index;
|
||||
data->sensor_range = index;
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
int accel_get_range(const enum accel_id id, int * const range)
|
||||
static int accel_get_range(void *drv_data, int * const range)
|
||||
{
|
||||
/* Check for valid id. */
|
||||
if (id < 0 || id >= ACCEL_COUNT)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
*range = ranges[sensor_range[id]].val;
|
||||
struct lsm6ds0_data *data = (struct lsm6ds0_data *)drv_data;
|
||||
*range = ranges[data->sensor_range].val;
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
int accel_set_resolution(const enum accel_id id, const int res, const int rnd)
|
||||
static int accel_set_resolution(void *drv_data,
|
||||
const int res,
|
||||
const int rnd)
|
||||
{
|
||||
/* Check for valid id. */
|
||||
if (id < 0 || id >= ACCEL_COUNT)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
/* Only one resolution, LSM6DS0_RESOLUTION, so nothing to do. */
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
int accel_get_resolution(const enum accel_id id, int * const res)
|
||||
static int accel_get_resolution(void *drv_data,
|
||||
int * const res)
|
||||
{
|
||||
/* Check for valid id. */
|
||||
if (id < 0 || id >= ACCEL_COUNT)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
*res = LSM6DS0_RESOLUTION;
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
int accel_set_datarate(const enum accel_id id, const int rate, const int rnd)
|
||||
static int accel_set_datarate(void *drv_data,
|
||||
const int rate,
|
||||
const int rnd)
|
||||
{
|
||||
int ret, index, ctrl_reg6;
|
||||
|
||||
/* Check for valid id. */
|
||||
if (id < 0 || id >= ACCEL_COUNT)
|
||||
return EC_ERROR_INVAL;
|
||||
struct lsm6ds0_data *data = (struct lsm6ds0_data *)drv_data;
|
||||
|
||||
/* Find index for interface pair matching the specified range. */
|
||||
index = find_param_index(rate, rnd, datarates, ARRAY_SIZE(datarates));
|
||||
@@ -168,62 +151,64 @@ int accel_set_datarate(const enum accel_id id, const int rate, const int rnd)
|
||||
* Lock accel resource to prevent another task from attempting
|
||||
* to write accel parameters until we are done.
|
||||
*/
|
||||
mutex_lock(&accel_mutex[id]);
|
||||
mutex_lock(&data->accel_mutex);
|
||||
|
||||
ret = raw_read8(accel_addr[id], LSM6DS0_CTRL_REG6_XL, &ctrl_reg6);
|
||||
ret = raw_read8(data->accel_addr, LSM6DS0_CTRL_REG6_XL, &ctrl_reg6);
|
||||
if (ret != EC_SUCCESS)
|
||||
goto accel_cleanup;
|
||||
|
||||
ctrl_reg6 = (ctrl_reg6 & ~LSM6DS0_ODR_ALL) | datarates[index].reg;
|
||||
ret = raw_write8(accel_addr[id], LSM6DS0_CTRL_REG6_XL, ctrl_reg6);
|
||||
ret = raw_write8(data->accel_addr, LSM6DS0_CTRL_REG6_XL, ctrl_reg6);
|
||||
|
||||
accel_cleanup:
|
||||
/* Unlock accel resource and save new ODR if written successfully. */
|
||||
mutex_unlock(&accel_mutex[id]);
|
||||
mutex_unlock(&data->accel_mutex);
|
||||
if (ret == EC_SUCCESS)
|
||||
sensor_datarate[id] = index;
|
||||
data->sensor_datarate = index;
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
int accel_get_datarate(const enum accel_id id, int * const rate)
|
||||
static int accel_get_datarate(void *drv_data,
|
||||
int * const rate)
|
||||
{
|
||||
/* Check for valid id. */
|
||||
if (id < 0 || id >= ACCEL_COUNT)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
*rate = datarates[sensor_datarate[id]].val;
|
||||
struct lsm6ds0_data *data = (struct lsm6ds0_data *)drv_data;
|
||||
*rate = datarates[data->sensor_datarate].val;
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACCEL_INTERRUPTS
|
||||
int accel_set_interrupt(const enum accel_id id, unsigned int threshold)
|
||||
static int accel_set_interrupt(void *drv_data,
|
||||
unsigned int threshold)
|
||||
{
|
||||
/* Currently unsupported. */
|
||||
return EC_ERROR_UNKNOWN;
|
||||
}
|
||||
#endif
|
||||
|
||||
int accel_read(const enum accel_id id, int * const x_acc, int * const y_acc,
|
||||
int * const z_acc)
|
||||
static int accel_read(void *drv_data,
|
||||
int * const x_acc,
|
||||
int * const y_acc,
|
||||
int * const z_acc)
|
||||
{
|
||||
uint8_t acc[6];
|
||||
uint8_t reg = LSM6DS0_OUT_X_L_XL;
|
||||
int ret, multiplier;
|
||||
struct lsm6ds0_data *data = (struct lsm6ds0_data *)drv_data;
|
||||
|
||||
/* Read 6 bytes starting at LSM6DS0_OUT_X_L_XL. */
|
||||
mutex_lock(&accel_mutex[id]);
|
||||
mutex_lock(&data->accel_mutex);
|
||||
i2c_lock(I2C_PORT_ACCEL, 1);
|
||||
ret = i2c_xfer(I2C_PORT_ACCEL, accel_addr[id], ®, 1, acc, 6,
|
||||
ret = i2c_xfer(I2C_PORT_ACCEL, data->accel_addr, ®, 1, acc, 6,
|
||||
I2C_XFER_SINGLE);
|
||||
i2c_lock(I2C_PORT_ACCEL, 0);
|
||||
mutex_unlock(&accel_mutex[id]);
|
||||
mutex_unlock(&data->accel_mutex);
|
||||
|
||||
if (ret != EC_SUCCESS)
|
||||
return ret;
|
||||
|
||||
/* Determine multiplier based on stored range. */
|
||||
switch (ranges[sensor_range[id]].reg) {
|
||||
switch (ranges[data->sensor_range].reg) {
|
||||
case LSM6DS0_GSEL_2G:
|
||||
multiplier = 1;
|
||||
break;
|
||||
@@ -254,32 +239,50 @@ int accel_read(const enum accel_id id, int * const x_acc, int * const y_acc,
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
int accel_init(const enum accel_id id)
|
||||
static int accel_init(void *drv_data, int i2c_addr)
|
||||
{
|
||||
int ret, ctrl_reg6;
|
||||
struct lsm6ds0_data *data = (struct lsm6ds0_data *)drv_data;
|
||||
|
||||
/* Check for valid id. */
|
||||
if (id < 0 || id >= ACCEL_COUNT)
|
||||
if (data == NULL)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
mutex_lock(&accel_mutex[id]);
|
||||
memset(&data->accel_mutex, sizeof(struct mutex), 0);
|
||||
data->sensor_range = 0;
|
||||
data->sensor_datarate = 1;
|
||||
data->accel_addr = i2c_addr;
|
||||
|
||||
/*
|
||||
* This sensor can be powered through an EC reboot, so the state of
|
||||
* the sensor is unknown here. Initiate software reset to restore
|
||||
* sensor to default.
|
||||
*/
|
||||
ret = raw_write8(accel_addr[id], LSM6DS0_CTRL_REG8, 1);
|
||||
ret = raw_write8(data->accel_addr, LSM6DS0_CTRL_REG8, 1);
|
||||
if (ret != EC_SUCCESS)
|
||||
goto accel_cleanup;
|
||||
|
||||
/* Set ODR and range. */
|
||||
ctrl_reg6 = datarates[sensor_datarate[id]].reg |
|
||||
ranges[sensor_range[id]].reg;
|
||||
ctrl_reg6 = datarates[data->sensor_datarate].reg |
|
||||
ranges[data->sensor_range].reg;
|
||||
|
||||
ret = raw_write8(accel_addr[id], LSM6DS0_CTRL_REG6_XL, ctrl_reg6);
|
||||
ret = raw_write8(data->accel_addr, LSM6DS0_CTRL_REG6_XL, ctrl_reg6);
|
||||
|
||||
accel_cleanup:
|
||||
mutex_unlock(&accel_mutex[id]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
const struct accelgyro_info accel_lsm6ds0 = {
|
||||
.chip_type = CHIP_LSM6DS0,
|
||||
.sensor_type = SENSOR_ACCELEROMETER,
|
||||
.init = accel_init,
|
||||
.read = accel_read,
|
||||
.set_range = accel_set_range,
|
||||
.get_range = accel_get_range,
|
||||
.set_resolution = accel_set_resolution,
|
||||
.get_resolution = accel_get_resolution,
|
||||
.set_datarate = accel_set_datarate,
|
||||
.get_datarate = accel_get_datarate,
|
||||
#ifdef CONFIG_ACCEL_INTERRUPTS
|
||||
.set_interrupt = accel_set_interrupt,
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#ifndef __CROS_EC_ACCEL_LSM6DS0_H
|
||||
#define __CROS_EC_ACCEL_LSM6DS0_H
|
||||
|
||||
#include "task.h"
|
||||
|
||||
/*
|
||||
* 7-bit address is 110101Xb. Where 'X' is determined
|
||||
* by the voltage on the ADDR pin.
|
||||
@@ -42,4 +44,16 @@
|
||||
/* Sensor resolution in number of bits. This sensor has fixed resolution. */
|
||||
#define LSM6DS0_RESOLUTION 16
|
||||
|
||||
struct lsm6ds0_data {
|
||||
struct mutex accel_mutex;
|
||||
/* Current range of accelerometer. */
|
||||
int sensor_range;
|
||||
/* Current output data rate of accelerometer. */
|
||||
int sensor_datarate;
|
||||
/* Device address. */
|
||||
int accel_addr;
|
||||
};
|
||||
|
||||
extern const struct accelgyro_info accel_lsm6ds0;
|
||||
|
||||
#endif /* __CROS_EC_ACCEL_LSM6DS0_H */
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
# Accelerometers
|
||||
driver-$(CONFIG_ACCEL_KXCJ9)+=accel_kxcj9.o
|
||||
driver-$(CONFIG_ACCELGYRO_LSM6DS0)+=accelgyro_lsm6ds0.o
|
||||
|
||||
# ALS drivers
|
||||
driver-$(CONFIG_ALS_ISL29035)+=als_isl29035.o
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef __CROS_EC_ACCELEROMETER_H
|
||||
#define __CROS_EC_ACCELEROMETER_H
|
||||
|
||||
/* Header file for accelerometer drivers. */
|
||||
|
||||
/* This array must be defined in board.c. */
|
||||
extern const int accel_addr[];
|
||||
|
||||
/* This enum must be defined in board.h. */
|
||||
enum accel_id;
|
||||
|
||||
/* Number of counts from accelerometer that represents 1G acceleration. */
|
||||
#define ACCEL_G 1024
|
||||
|
||||
/**
|
||||
* Read all three accelerations of an accelerometer. Note that all three
|
||||
* accelerations come back in counts, where ACCEL_G can be used to convert
|
||||
* counts to engineering units.
|
||||
*
|
||||
* @param id Target accelerometer
|
||||
* @param x_acc Pointer to store X-axis acceleration (in counts).
|
||||
* @param y_acc Pointer to store Y-axis acceleration (in counts).
|
||||
* @param z_acc Pointer to store Z-axis acceleration (in counts).
|
||||
*
|
||||
* @return EC_SUCCESS if successful, non-zero if error.
|
||||
*/
|
||||
int accel_read(const enum accel_id id, int * const x_acc, int * const y_acc,
|
||||
int * const z_acc);
|
||||
|
||||
/**
|
||||
* Initialize accelerometers.
|
||||
*
|
||||
* @param id Target accelerometer
|
||||
*
|
||||
* @return EC_SUCCESS if successful, non-zero if error.
|
||||
*/
|
||||
int accel_init(const enum accel_id id);
|
||||
|
||||
/**
|
||||
* Setter and getter methods for the sensor range. The sensor range defines
|
||||
* the maximum value that can be returned from accel_read(). As the range
|
||||
* increases, the resolution gets worse.
|
||||
*
|
||||
* @param id Target accelerometer
|
||||
* @param range Range (Units are +/- G's for accel, +/- deg/s for gyro)
|
||||
* @param rnd Rounding flag. If true, it rounds up to nearest valid value.
|
||||
* Otherwise, it rounds down.
|
||||
*
|
||||
* @return EC_SUCCESS if successful, non-zero if error.
|
||||
*/
|
||||
int accel_set_range(const enum accel_id id, const int range, const int rnd);
|
||||
int accel_get_range(const enum accel_id id, int * const range);
|
||||
|
||||
|
||||
/**
|
||||
* Setter and getter methods for the sensor resolution.
|
||||
*
|
||||
* @param id Target accelerometer
|
||||
* @param range Resolution (Units are number of bits)
|
||||
* param rnd Rounding flag. If true, it rounds up to nearest valid value.
|
||||
* Otherwise, it rounds down.
|
||||
*
|
||||
* @return EC_SUCCESS if successful, non-zero if error.
|
||||
*/
|
||||
int accel_set_resolution(const enum accel_id id, const int res, const int rnd);
|
||||
int accel_get_resolution(const enum accel_id id, int * const res);
|
||||
|
||||
/**
|
||||
* Setter and getter methods for the sensor output data range. As the ODR
|
||||
* increases, the LPF roll-off frequency also increases.
|
||||
*
|
||||
* @param id Target accelerometer
|
||||
* @param rate Output data rate (units are mHz)
|
||||
* @param rnd Rounding flag. If true, it rounds up to nearest valid value.
|
||||
* Otherwise, it rounds down.
|
||||
*
|
||||
* @return EC_SUCCESS if successful, non-zero if error.
|
||||
*/
|
||||
int accel_set_datarate(const enum accel_id id, const int rate, const int rnd);
|
||||
int accel_get_datarate(const enum accel_id id, int * const rate);
|
||||
|
||||
#endif /* __CROS_EC_ACCELEROMETER_H */
|
||||
111
include/accelgyro.h
Normal file
111
include/accelgyro.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef __CROS_EC_ACCELGYRO_H
|
||||
#define __CROS_EC_ACCELGYRO_H
|
||||
|
||||
/* Header file for accelerometer / gyro drivers. */
|
||||
|
||||
/* Number of counts from accelerometer that represents 1G acceleration. */
|
||||
#define ACCEL_G 1024
|
||||
|
||||
enum accelgyro_chip_t {
|
||||
CHIP_TEST,
|
||||
CHIP_KXCJ9,
|
||||
CHIP_LSM6DS0,
|
||||
};
|
||||
|
||||
enum accelgyro_sensor_t {
|
||||
SENSOR_ACCELEROMETER,
|
||||
SENSOR_GYRO,
|
||||
};
|
||||
|
||||
struct accelgyro_info {
|
||||
enum accelgyro_chip_t chip_type;
|
||||
enum accelgyro_sensor_t sensor_type;
|
||||
|
||||
/**
|
||||
* Initialize accelerometers.
|
||||
* @param drv_data Pointer to sensor data.
|
||||
* @i2c_addr i2c slave device address
|
||||
* @return EC_SUCCESS if successful, non-zero if error.
|
||||
*/
|
||||
int (*init)(void *drv_data,
|
||||
int i2c_addr);
|
||||
|
||||
/**
|
||||
* Read all three accelerations of an accelerometer. Note that all
|
||||
* three accelerations come back in counts, where ACCEL_G can be used
|
||||
* to convert counts to engineering units.
|
||||
* @param drv_data Pointer to sensor data.
|
||||
* @param x_acc Pointer to store X-axis acceleration (in counts).
|
||||
* @param y_acc Pointer to store Y-axis acceleration (in counts).
|
||||
* @param z_acc Pointer to store Z-axis acceleration (in counts).
|
||||
* @return EC_SUCCESS if successful, non-zero if error.
|
||||
*/
|
||||
int (*read)(void *drv_data,
|
||||
int * const x_acc,
|
||||
int * const y_acc,
|
||||
int * const z_acc);
|
||||
|
||||
/**
|
||||
* Setter and getter methods for the sensor range. The sensor range
|
||||
* defines the maximum value that can be returned from read(). As the
|
||||
* range increases, the resolution gets worse.
|
||||
* @param drv_data Pointer to sensor data.
|
||||
* @param range Range (Units are +/- G's for accel, +/- deg/s for gyro)
|
||||
* @param rnd Rounding flag. If true, it rounds up to nearest valid
|
||||
* value. Otherwise, it rounds down.
|
||||
* @return EC_SUCCESS if successful, non-zero if error.
|
||||
*/
|
||||
int (*set_range)(void *drv_data,
|
||||
const int range,
|
||||
const int rnd);
|
||||
int (*get_range)(void *drv_data,
|
||||
int * const range);
|
||||
|
||||
/**
|
||||
* Setter and getter methods for the sensor resolution.
|
||||
* @param drv_data Pointer to sensor data.
|
||||
* @param range Resolution (Units are number of bits)
|
||||
* param rnd Rounding flag. If true, it rounds up to nearest valid
|
||||
* value. Otherwise, it rounds down.
|
||||
* @return EC_SUCCESS if successful, non-zero if error.
|
||||
*/
|
||||
int (*set_resolution)(void *drv_data,
|
||||
const int res,
|
||||
const int rnd);
|
||||
int (*get_resolution)(void *drv_data,
|
||||
int * const res);
|
||||
|
||||
/**
|
||||
* Setter and getter methods for the sensor output data range. As the
|
||||
* ODR increases, the LPF roll-off frequency also increases.
|
||||
* @param drv_data Pointer to sensor data.
|
||||
* @param rate Output data rate (units are mHz)
|
||||
* @param rnd Rounding flag. If true, it rounds up to nearest valid
|
||||
* value. Otherwise, it rounds down.
|
||||
* @return EC_SUCCESS if successful, non-zero if error.
|
||||
*/
|
||||
int (*set_datarate)(void *drv_data,
|
||||
const int rate,
|
||||
const int rnd);
|
||||
int (*get_datarate)(void *drv_data,
|
||||
int * const rate);
|
||||
|
||||
#ifdef CONFIG_ACCEL_INTERRUPTS
|
||||
/**
|
||||
* Setup a one-time accel interrupt. If the threshold is low enough, the
|
||||
* interrupt may trigger due simply to noise and not any real motion.
|
||||
* If the threshold is 0, the interrupt will fire immediately.
|
||||
* @param drv_data Pointer to sensor data.
|
||||
* @param threshold Threshold for interrupt in units of counts.
|
||||
*/
|
||||
int (*set_interrupt)(void *drv_data,
|
||||
unsigned int threshold);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* __CROS_EC_ACCELGYRO_H */
|
||||
@@ -1300,6 +1300,7 @@ enum motionsensor_location {
|
||||
/* List of motion sensor chips. */
|
||||
enum motionsensor_chip {
|
||||
MOTIONSENSE_CHIP_KXCJ9 = 0,
|
||||
MOTIONSENSE_CHIP_LSM6DS0 = 1,
|
||||
};
|
||||
|
||||
/* Module flag masks used for the dump sub-command. */
|
||||
|
||||
@@ -92,5 +92,21 @@ void accel_int_lid(enum gpio_signal signal);
|
||||
*/
|
||||
void accel_int_base(enum gpio_signal signal);
|
||||
|
||||
enum sensor_location_t {
|
||||
LOCATION_BASE,
|
||||
LOCATION_LID,
|
||||
};
|
||||
|
||||
struct motion_sensor_t {
|
||||
char *name;
|
||||
enum sensor_location_t location;
|
||||
const struct accelgyro_info *drv;
|
||||
void *drv_data;
|
||||
uint8_t i2c_addr;
|
||||
};
|
||||
|
||||
/* Defined at board level. */
|
||||
extern const struct motion_sensor_t motion_sensors[];
|
||||
extern const unsigned int motion_sensor_count;
|
||||
|
||||
#endif /* __CROS_EC_MOTION_SENSE_H */
|
||||
|
||||
@@ -10,43 +10,12 @@
|
||||
#include "math_util.h"
|
||||
#include "motion_sense.h"
|
||||
#include "test_util.h"
|
||||
#include "util.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Mock functions */
|
||||
|
||||
/* Need to define accelerometer functions just to compile. */
|
||||
int accel_init(enum accel_id id)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
int accel_read(enum accel_id id, int *x_acc, int *y_acc, int *z_acc)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
int accel_set_range(const enum accel_id id, const int range, const int rnd)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
int accel_get_range(const enum accel_id id, int * const range)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
int accel_set_resolution(const enum accel_id id, const int res, const int rnd)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
int accel_get_resolution(const enum accel_id id, int * const res)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
int accel_set_datarate(const enum accel_id id, const int rate, const int rnd)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
int accel_get_datarate(const enum accel_id id, int * const rate)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
/* Need to define motion sensor globals just to compile. */
|
||||
const struct motion_sensor_t motion_sensors[] = {};
|
||||
const unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors);
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Test utilities */
|
||||
|
||||
@@ -7,12 +7,14 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "accelgyro.h"
|
||||
#include "common.h"
|
||||
#include "host_command.h"
|
||||
#include "motion_sense.h"
|
||||
#include "task.h"
|
||||
#include "test_util.h"
|
||||
#include "timer.h"
|
||||
#include "util.h"
|
||||
|
||||
/* Mock acceleration values for motion sense task to read in. */
|
||||
int mock_x_acc[ACCEL_COUNT], mock_y_acc[ACCEL_COUNT], mock_z_acc[ACCEL_COUNT];
|
||||
@@ -20,46 +22,101 @@ int mock_x_acc[ACCEL_COUNT], mock_y_acc[ACCEL_COUNT], mock_z_acc[ACCEL_COUNT];
|
||||
/*****************************************************************************/
|
||||
/* Mock functions */
|
||||
|
||||
int accel_init(enum accel_id id)
|
||||
static int accel_init(void *drv_data, int i2c_addr)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
int accel_read(enum accel_id id, int *x_acc, int *y_acc, int *z_acc)
|
||||
static int accel_read_base(void *drv_data, int *x_acc, int *y_acc, int *z_acc)
|
||||
{
|
||||
/* Return the mock values. */
|
||||
*x_acc = mock_x_acc[id];
|
||||
*y_acc = mock_y_acc[id];
|
||||
*z_acc = mock_z_acc[id];
|
||||
*x_acc = mock_x_acc[ACCEL_BASE];
|
||||
*y_acc = mock_y_acc[ACCEL_BASE];
|
||||
*z_acc = mock_z_acc[ACCEL_BASE];
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
int accel_set_range(const enum accel_id id, const int range, const int rnd)
|
||||
static int accel_read_lid(void *drv_data, int *x_acc, int *y_acc, int *z_acc)
|
||||
{
|
||||
/* Return the mock values. */
|
||||
*x_acc = mock_x_acc[ACCEL_LID];
|
||||
*y_acc = mock_y_acc[ACCEL_LID];
|
||||
*z_acc = mock_z_acc[ACCEL_LID];
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
int accel_get_range(const enum accel_id id, int * const range)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
int accel_set_resolution(const enum accel_id id, const int res, const int rnd)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
int accel_get_resolution(const enum accel_id id, int * const res)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
int accel_set_datarate(const enum accel_id id, const int rate, const int rnd)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
int accel_get_datarate(const enum accel_id id, int * const rate)
|
||||
|
||||
static int accel_set_range(void *drv_data,
|
||||
const int range,
|
||||
const int rnd)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
static int accel_get_range(void *drv_data,
|
||||
int * const range)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
static int accel_set_resolution(void *drv_data,
|
||||
const int res,
|
||||
const int rnd)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
static int accel_get_resolution(void *drv_data,
|
||||
int * const res)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
static int accel_set_datarate(void *drv_data,
|
||||
const int rate,
|
||||
const int rnd)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
static int accel_get_datarate(void *drv_data,
|
||||
int * const rate)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
const struct accelgyro_info test_motion_sense_base = {
|
||||
.chip_type = CHIP_TEST,
|
||||
.sensor_type = SENSOR_ACCELEROMETER,
|
||||
.init = accel_init,
|
||||
.read = accel_read_base,
|
||||
.set_range = accel_set_range,
|
||||
.get_range = accel_get_range,
|
||||
.set_resolution = accel_set_resolution,
|
||||
.get_resolution = accel_get_resolution,
|
||||
.set_datarate = accel_set_datarate,
|
||||
.get_datarate = accel_get_datarate,
|
||||
};
|
||||
|
||||
const struct accelgyro_info test_motion_sense_lid = {
|
||||
.chip_type = CHIP_TEST,
|
||||
.sensor_type = SENSOR_ACCELEROMETER,
|
||||
.init = accel_init,
|
||||
.read = accel_read_lid,
|
||||
.set_range = accel_set_range,
|
||||
.get_range = accel_get_range,
|
||||
.set_resolution = accel_set_resolution,
|
||||
.get_resolution = accel_get_resolution,
|
||||
.set_datarate = accel_set_datarate,
|
||||
.get_datarate = accel_get_datarate,
|
||||
};
|
||||
|
||||
const struct motion_sensor_t motion_sensors[] = {
|
||||
{"test base sensor", LOCATION_BASE, &test_motion_sense_base, NULL, 0},
|
||||
{"test lid sensor", LOCATION_LID, &test_motion_sense_lid, NULL, 0},
|
||||
};
|
||||
const unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors);
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Test utilities */
|
||||
|
||||
Reference in New Issue
Block a user