summaryrefslogtreecommitdiff
path: root/driver/accelgyro_lsm6dso.h
blob: 9a58fe7d3654d7a55b369393b1fcdc8988ae58f8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/* Copyright 2019 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.
 */

/* LSM6DSO Accel and Gyro driver for Chrome EC */

#ifndef __CROS_EC_ACCELGYRO_LSM6DSO_H
#define __CROS_EC_ACCELGYRO_LSM6DSO_H

#include "stm_mems_common.h"

/*
 * 7-bit address is 110101xb. Where 'x' is determined
 * by the voltage on the ADDR pin
 */
#define LSM6DSO_ADDR0_FLAGS		0x6a
#define LSM6DSO_ADDR1_FLAGS		0x6b

/* Access to embedded sensor hub register bank */
#define LSM6DSO_FUNC_CFG_ACC_ADDR	0x01
#define LSM6DSO_FUNC_CFG_EN			0x80

/* Who Am I */
#define LSM6DSO_WHO_AM_I_REG		0x0f
#define LSM6DSO_WHO_AM_I		0x6c

/* Common defines for Acc and Gyro sensors */
#define LSM6DSO_EN_BIT				0x01
#define LSM6DSO_DIS_BIT				0x00

#define LSM6DSO_GYRO_OUT_X_L_ADDR	0x22
#define LSM6DSO_ACCEL_OUT_X_L_ADDR	0x28

#define LSM6DSO_CTRL1_ADDR		0x10
#define LSM6DSO_CTRL2_ADDR		0x11
#define LSM6DSO_CTRL3_ADDR		0x12
#define LSM6DSO_SW_RESET			0x01
#define LSM6DSO_IF_INC				0x04
#define LSM6DSO_PP_OD				0x10
#define LSM6DSO_H_L_ACTIVE			0x20
#define LSM6DSO_BDU				0x40

#define LSM6DSO_CTRL4_ADDR		0x13
#define LSM6DSO_INT2_ON_INT1_MASK		0x20

#define LSM6DSO_CTRL5_ADDR		0x14
#define LSM6DSO_CTRL6_ADDR		0x15
#define LSM6DSO_CTRL7_ADDR		0x16
#define LSM6DSO_CTRL8_ADDR		0x17
#define LSM6DSO_CTRL9_ADDR		0x18

#define LSM6DSO_CTRL10_ADDR		0x19
#define LSM6DSO_TIMESTAMP_EN    		0x20

#define LSM6DSO_STATUS_REG		0x1e

/* Output data rate registers and masks */
#define LSM6DSO_ODR_REG(_sensor) \
	(LSM6DSO_CTRL1_ADDR + (_sensor))
#define LSM6DSO_ODR_MASK			0xf0

/* FIFO decimator registers and bitmask */
#define LSM6DSO_FIFO_CTRL1_ADDR		0x07
#define LSM6DSO_FIFO_CTRL2_ADDR		0x08

#define LSM6DSO_FIFO_CTRL3_ADDR		0x09
#define LSM6DSO_FIFO_ODR_XL_MASK		0x0f
#define LSM6DSO_FIFO_ODR_G_MASK			0xf0

#define LSM6DSO_FIFO_CTRL4_ADDR		0x0a
#define LSM6DSO_FIFO_MODE_MASK			0x07

#define LSM6DSO_INT1_CTRL		0x0d
#define LSM6DSO_INT2_CTRL		0x0e
#define LSM6DSO_INT_FIFO_TH			0x08
#define LSM6DSO_INT_FIFO_OVR			0x10
#define LSM6DSO_INT_FIFO_FULL			0x20

#define LSM6DSO_FIFO_STS1_ADDR		0x3a
#define LSM6DSO_FIFO_STS2_ADDR		0x3b
#define LSM6DSO_FIFO_DIFF_MASK			0x07ff
#define LSM6DSO_FIFO_FULL			0x2000
#define LSM6DSO_FIFO_DATA_OVR			0x4000
#define LSM6DSO_FIFO_WATERMARK			0x8000

/* Out FIFO data register */
#define LSM6DSO_FIFO_DATA_ADDR_TAG	0x78

/* Registers value for supported FIFO mode */
#define LSM6DSO_FIFO_MODE_BYPASS_VAL	0x00
#define LSM6DSO_FIFO_MODE_CONTINUOUS_VAL	0x06

/* Define device available in FIFO pattern */
enum lsm6dso_dev_fifo {
	LSM6DSO_FIFO_DEV_INVALID = -1,
	LSM6DSO_FIFO_DEV_GYRO = 0,
	LSM6DSO_FIFO_DEV_ACCEL,
	LSM6DSO_FIFO_DEV_NUM,
};

/* Define FIFO data pattern, tag and len */
#define LSM6DSO_TAG_SIZE		1
#define LSM6DSO_FIFO_SAMPLE_SIZE	(OUT_XYZ_SIZE + LSM6DSO_TAG_SIZE)

enum lsm6dso_tag_fifo {
	LSM6DSO_GYRO_TAG = 0x01,
	LSM6DSO_ACC_TAG = 0x02,
};

struct lsm6dso_fstatus {
	uint16_t len;
	uint16_t pattern;
};

/* Absolute maximum rate for Acc and Gyro sensors */
#define LSM6DSO_ODR_MIN_VAL		13000
#define LSM6DSO_ODR_MAX_VAL \
	MOTION_MAX_SENSOR_FREQUENCY(416000, 13000)

/* ODR reg value from selected data rate in mHz */
#define LSM6DSO_ODR_TO_REG(_odr) (__fls(_odr / LSM6DSO_ODR_MIN_VAL) + 1)

#define LSM6DSO_FIFO_ODR_MASK(_s) \
	(_s->type == MOTIONSENSE_TYPE_ACCEL ? LSM6DSO_FIFO_ODR_XL_MASK : \
	 LSM6DSO_FIFO_ODR_G_MASK)

/* Normalized ODR values from selected data rate in mHz */
#define LSM6DSO_REG_TO_ODR(_reg) (LSM6DSO_ODR_MIN_VAL << (_reg - 1))

/* Full Scale ranges value and gain for Acc */
#define LSM6DSO_FS_LIST_NUM		4

#define LSM6DSO_ACCEL_FS_ADDR		0x10
#define LSM6DSO_ACCEL_FS_MASK			0x0c

#define LSM6DSO_ACCEL_FS_2G_VAL		0x00
#define LSM6DSO_ACCEL_FS_4G_VAL		0x02
#define LSM6DSO_ACCEL_FS_8G_VAL		0x03
#define LSM6DSO_ACCEL_FS_16G_VAL	0x01

#define LSM6DSO_ACCEL_FS_MAX_VAL	16

/* Accel reg value from Full Scale range */
static inline uint8_t lsm6dso_accel_fs_reg(int fs)
{
	uint8_t ret;

	switch(fs) {
	case 2:
		ret = LSM6DSO_ACCEL_FS_2G_VAL;
		break;
	case 16:
		ret = LSM6DSO_ACCEL_FS_16G_VAL;
		break;
	default:
		ret = __fls(fs);
		break;
	}

	return ret;
}

/* Accel normalized FS value from Full Scale */
#define LSM6DSO_ACCEL_NORMALIZE_FS(_fs) (1 << __fls(_fs))

/* Full Scale range value and gain for Gyro */
#define LSM6DSO_GYRO_FS_ADDR		0x11
#define LSM6DSO_GYRO_FS_MASK			0x0c

/* Minimal Gyro range in mDPS */
#define LSM6DSO_GYRO_FS_MIN_VAL_MDPS ((8750 << 15) / 1000)
#define LSM6DSO_GYRO_FS_MAX_REG_VAL 3

/* Gyro reg value for Full Scale selection in DPS */
#define LSM6DSO_GYRO_FS_REG(_fs) \
	__fls(MAX(1, (_fs * 1000) / LSM6DSO_GYRO_FS_MIN_VAL_MDPS))

/* Gyro normalized FS value (in DPS) from Full Scale register */
#define LSM6DSO_GYRO_NORMALIZE_FS(_reg) \
	((LSM6DSO_GYRO_FS_MIN_VAL_MDPS << (_reg)) / 1000)

/* FS register address/mask for Acc/Gyro sensors */
#define LSM6DSO_RANGE_REG(_sensor)  	(LSM6DSO_ACCEL_FS_ADDR + (_sensor))
#define LSM6DSO_RANGE_MASK  			0x0c

/* Status register bit for Acc/Gyro data ready */
enum lsm6dso_status {
	LSM6DSO_STS_DOWN = 0x00,
	LSM6DSO_STS_XLDA_UP = 0x01,
	LSM6DSO_STS_GDA_UP = 0x02
};

/* Status register bitmask for Acc/Gyro data ready */
#define LSM6DSO_STS_XLDA_MASK			0x01
#define LSM6DSO_STS_GDA_MASK			0x02

/* Sensor resolution in number of bits: fixed 16 bit */
#define LSM6DSO_RESOLUTION      	16

/* Aggregate private data for all supported sensor (Acc, Gyro) */
struct lsm6dso_data {
	struct stprivate_data st_data[LSM6DSO_FIFO_DEV_NUM];
};

/*
 * Note: The specific number of samples to discard depends on the filters
 * configured for the chip, as well as the ODR being set. For most of our
 * allowed ODRs, 3 should suffice.
 * See: ST's LSM6DSO application notes (AN5192) Tables 12 and 18 for details
 */
#define LSM6DSO_DISCARD_SAMPLES 3

#define LSM6DSO_GET_DATA(_s) ((struct stprivate_data *)((_s)->drv_data))

/* Macro to initialize motion_sensors structure */
#define LSM6DSO_ST_DATA(g, type) (&((g).st_data[type]))

extern const struct accelgyro_drv lsm6dso_drv;

void lsm6dso_interrupt(enum gpio_signal signal);

#endif /* __CROS_EC_ACCELGYRO_LSM6DSO_H */