summaryrefslogtreecommitdiff
path: root/driver/stm_mems_common.c
diff options
context:
space:
mode:
authorMario Tesi <mario.tesi@st.com>2016-11-18 09:48:42 +0100
committerchrome-bot <chrome-bot@chromium.org>2017-02-09 03:10:22 -0800
commit8db50ce410cd71a6b4429fb91a3be9e103312f8f (patch)
treedef49c0684d3d0b1e10491ed475afb9ebbc1eb22 /driver/stm_mems_common.c
parentb6c5e8e7a2edee6f167fe1282db6e1263fa6988e (diff)
downloadchrome-ec-8db50ce410cd71a6b4429fb91a3be9e103312f8f.tar.gz
driver: accel: Add acc driver basics and FIFO for LIS2DH/LIS2DH12
Add driver for acc sensor ST lis2dh/lis2dh12 Support interrupt management for FIFO watermark Starting to share common code with other devices like lsm6dsm/lsm6dsl (acc/gyro) or new lis2mdl (mag) TODO: Add all embedded functions support (click, tap and so on) BUG=none BRANCH=master TEST=Tested on discovery BOARD with sensor connected on EC i2c master bus. Added motion sense task on discovery board task list, added gpio info in board configuration file and tested with motion sense console commands. Data for acc seems ok: can successfully change ODR and full scale range. Also FIFO and interrupt tested Device tested is lis2dh (lis2dh12 simply differs for low pin count but share the same registers) Change-Id: I16abeac3f139a604094b38d8d8b857a62c93a242 Signed-off-by: Mario Tesi <mario.tesi@st.com> Reviewed-on: https://chromium-review.googlesource.com/412700 Commit-Ready: mario tesi <mario.tesi@st.com> Tested-by: mario tesi <mario.tesi@st.com> Reviewed-by: Gwendal Grignou <gwendal@chromium.org>
Diffstat (limited to 'driver/stm_mems_common.c')
-rw-r--r--driver/stm_mems_common.c182
1 files changed, 182 insertions, 0 deletions
diff --git a/driver/stm_mems_common.c b/driver/stm_mems_common.c
new file mode 100644
index 0000000000..9e482583b3
--- /dev/null
+++ b/driver/stm_mems_common.c
@@ -0,0 +1,182 @@
+/* Copyright (c) 2016 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.
+ */
+
+/**
+ * Commons acc/gyro function for ST sensors in Chrome EC
+ */
+#include "stm_mems_common.h"
+
+/**
+ * Read single register
+ */
+inline int raw_read8(const int port, const int addr, const int reg,
+ int *data_ptr)
+{
+ /* TODO: Implement SPI interface support */
+ return i2c_read8(port, addr, reg, data_ptr);
+}
+
+/**
+ * Write single register
+ */
+inline int raw_write8(const int port, const int addr, const int reg,
+ int data)
+{
+ /* TODO: Implement SPI interface support */
+ return i2c_write8(port, addr, reg, data);
+}
+
+/**
+ * Read n bytes for read
+ * NOTE: Some chip use MSB for auto-increments in SUB address
+ * MSB must be set for autoincrement in multi read when auto_inc
+ * is set
+ */
+int raw_read_n(const int port, const int addr, const uint8_t reg,
+ uint8_t *data_ptr, const int len, int auto_inc)
+{
+ int rv = -EC_ERROR_PARAM1;
+ uint8_t reg_a = reg;
+
+ if (auto_inc)
+ reg_a |= AUTO_INC;
+
+ /* TODO: Implement SPI interface support */
+ i2c_lock(port, 1);
+ rv = i2c_xfer(port, addr, &reg_a, 1, data_ptr, len, I2C_XFER_SINGLE);
+ i2c_lock(port, 0);
+
+ return rv;
+}
+
+ /**
+ * write_data_with_mask - Write register with mask
+ * @s: Motion sensor pointer
+ * @reg: Device register
+ * @mask: The mask to search
+ * @data: Data pointer
+ */
+int write_data_with_mask(const struct motion_sensor_t *s, int reg,
+ uint8_t mask, uint8_t data)
+{
+ int err;
+ int new_data = 0x00, old_data = 0x00;
+
+ err = raw_read8(s->port, s->addr, reg, &old_data);
+ if (err != EC_SUCCESS)
+ return err;
+
+ new_data = ((old_data & (~mask)) | ((data << __builtin_ctz(mask)) & mask));
+
+ if (new_data == old_data)
+ return EC_SUCCESS;
+
+ return raw_write8(s->port, s->addr, reg, new_data);
+}
+
+ /**
+ * set_resolution - Set bit resolution
+ * @s: Motion sensor pointer
+ * @res: Bit resolution
+ * @rnd: Round bit
+ *
+ * TODO: must support multiple resolution
+ */
+int set_resolution(const struct motion_sensor_t *s, int res, int rnd)
+{
+ return EC_SUCCESS;
+}
+
+ /**
+ * get_resolution - Get bit resolution
+ * @s: Motion sensor pointer
+ *
+ * TODO: must support multiple resolution
+ */
+int get_resolution(const struct motion_sensor_t *s)
+{
+ struct stprivate_data *data = s->drv_data;
+
+ return data->resol;
+}
+
+/**
+ * set_offset - Set data offset
+ * @s: Motion sensor pointer
+ * @offset: offset vector
+ * @temp: Temp
+ */
+int set_offset(const struct motion_sensor_t *s,
+ const int16_t *offset, int16_t temp)
+{
+ struct stprivate_data *data = s->drv_data;
+
+ data->offset[X] = offset[X];
+ data->offset[Y] = offset[Y];
+ data->offset[Z] = offset[Z];
+ return EC_SUCCESS;
+}
+
+/**
+ * get_offset - Get data offset
+ * @s: Motion sensor pointer
+ * @offset: offset vector
+ * @temp: Temp
+ */
+int get_offset(const struct motion_sensor_t *s,
+ int16_t *offset, int16_t *temp)
+{
+ struct stprivate_data *data = s->drv_data;
+
+ offset[X] = data->offset[X];
+ offset[Y] = data->offset[Y];
+ offset[Z] = data->offset[Z];
+ *temp = EC_MOTION_SENSE_INVALID_CALIB_TEMP;
+ return EC_SUCCESS;
+}
+
+/**
+ * get_data_rate - Get data rate (ODR)
+ * @s: Motion sensor pointer
+ */
+int get_data_rate(const struct motion_sensor_t *s)
+{
+ struct stprivate_data *data = s->drv_data;
+
+ return data->base.odr;
+}
+
+/**
+ * normalize - Apply LSB data sens. and rotation based on sensor resolution
+ * @s: Motion sensor pointer
+ * @v: output vector
+ * @data: LSB raw data
+ */
+void normalize(const struct motion_sensor_t *s, vector_3_t v, uint8_t *data)
+{
+ int i;
+ struct stprivate_data *drvdata = s->drv_data;
+
+ /* Adjust data to sensor Sensitivity and Precision:
+ * - devices with 16 bits resolution has gain in ug/LSB
+ * - devices with 8/10 bits resolution has gain in mg/LSB
+ */
+ for (i = 0; i < 3; i++) {
+ switch (drvdata->resol) {
+ case 10:
+ v[i] = ((int16_t)((data[i * 2 + 1] << 8) |
+ data[i * 2]) >> 6);
+ v[i] = v[i] * drvdata->base.range;
+ break;
+ case 16:
+ v[i] = ((int16_t)(data[i * 2 + 1] << 8) |
+ data[i * 2]);
+ v[i] = (v[i] * drvdata->base.range) / 1000;
+ break;
+ }
+ }
+
+ rotate(v, *s->rot_standard_ref, v);
+}