summaryrefslogtreecommitdiff
path: root/include/driver/mag_bmm150.h
blob: a9136da1e5651bb43d4e31edb5358a4afc893626 (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
/* Copyright 2015 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.
 */

/* BMM150 magnetometer definition */

#ifndef __CROS_EC_MAG_BMM150_H
#define __CROS_EC_MAG_BMM150_H

#include "accelgyro.h"
#include "mag_cal.h"

#define BMM150_ADDR0_FLAGS 0x10
#define BMM150_ADDR1_FLAGS 0x11
#define BMM150_ADDR2_FLAGS 0x12
#define BMM150_ADDR3_FLAGS 0x13

#define BMM150_CHIP_ID 0x40
#define BMM150_CHIP_ID_MAJOR 0x32

#define BMM150_BASE_DATA 0x42

#define BMM150_INT_STATUS 0x4a
#define BMM150_PWR_CTRL 0x4b
#define BMM150_SRST (BIT(7) | BIT(1))
#define BMM150_PWR_ON BIT(0)

#define BMM150_OP_CTRL 0x4c
#define BMM150_OP_MODE_OFFSET 1
#define BMM150_OP_MODE_MASK 3
#define BMM150_OP_MODE_NORMAL 0x00
#define BMM150_OP_MODE_FORCED 0x01
#define BMM150_OP_MODE_SLEEP 0x03

#define BMM150_INT_CTRL 0x4d

#define BMM150_REPXY 0x51
#define BMM150_LOW_POWER_nXY 3
#define BMM150_REGULAR_nXY 9
#define BMM150_ENHANCED_nXY 15
#define BMM150_HIGH_ACCURACY_nXY 47
#define BMM150_SPECIAL_nXY 75
#define BMM150_REPZ 0x52
#define BMM150_LOW_POWER_nZ 3
#define BMM150_REGULAR_nZ 15
#define BMM150_ENHANCED_nZ 27
#define BMM150_HIGH_ACCURACY_nZ 83
#define BMM150_SPECIAL_nZ 27

#define BMM150_REP(_preset, _axis) CONCAT4(BMM150_, _preset, _n, _axis)

/* Hidden registers for RHALL calculation */
#define BMM150_REGA_DIG_X1 0x5d
#define BMM150_REGA_DIG_Y1 0x5e
#define BMM150_REGA_DIG_Z4_LSB 0x62
#define BMM150_REGA_DIG_Z4_MSB 0x63
#define BMM150_REGA_DIG_X2 0x64
#define BMM150_REGA_DIG_Y2 0x65
#define BMM150_REGA_DIG_Z2_LSB 0x68
#define BMM150_REGA_DIG_Z2_MSB 0x69
#define BMM150_REGA_DIG_Z1_LSB 0x6a
#define BMM150_REGA_DIG_Z1_MSB 0x6b
#define BMM150_REGA_DIG_XYZ1_LSB 0x6c
#define BMM150_REGA_DIG_XYZ1_MSB 0x6d
#define BMM150_REGA_DIG_Z3_LSB 0x6e
#define BMM150_REGA_DIG_Z3_MSB 0x6f
#define BMM150_REGA_DIG_XY2 0x70
#define BMM150_REGA_DIG_XY1 0x71

/* Overflow */

#define BMM150_FLIP_OVERFLOW_ADCVAL (-4096)
#define BMM150_HALL_OVERFLOW_ADCVAL (-16384)
#define BMM150_OVERFLOW_OUTPUT (0x8000)

/* Min and Max sampling frequency in mHz */
#define BMM150_MAG_MIN_FREQ 781

/*
 * From Section 4.2.4, max frequency depends on the preset.
 *
 *  Fmax ~= 1 / (145us * nXY + 500us * nZ + 980us)
 *
 *  To be safe, declare only 75% of the value.
 */
#define __BMM150_MAG_MAX_FREQ(_preset) \
	(750000000 /                   \
	 (145 * BMM150_REP(_preset, XY) + 500 * BMM150_REP(_preset, Z) + 980))

#if (__BMM150_MAG_MAX_FREQ(SPECIAL) > CONFIG_EC_MAX_SENSOR_FREQ_MILLIHZ)
#error "EC too slow for magnetometer"
#endif

struct bmm150_comp_registers {
	/* Local copy of the compensation registers. */
	int8_t dig1[2];
	int8_t dig2[2];

	uint16_t dig_z1;
	int16_t dig_z2;
	int16_t dig_z3;
	int16_t dig_z4;

	uint8_t dig_xy1;
	int8_t dig_xy2;

	uint16_t dig_xyz1;
};

struct bmm150_private_data {
	/* lsm6dsm_data union requires cal be first element */
	struct mag_cal_t cal;
	struct bmm150_comp_registers comp;
};

#ifdef CONFIG_MAG_BMI_BMM150
#include "accelgyro_bmi_common.h"

#define BMM150_COMP_REG(_s) (&BMI_GET_DATA(_s)->compass.comp)

#define BMM150_CAL(_s) (&BMI_GET_DATA(_s)->compass.cal)
/*
 * Behind a BMI, the BMM150 is in forced mode. Be sure to choose a frequency
 * compatible with BMI.
 */
#define BMM150_MAG_MAX_FREQ(_preset) \
	BMI_REG_TO_ODR(BMI_ODR_TO_REG(__BMM150_MAG_MAX_FREQ(_preset)))
#else
#define BMM150_COMP_REG(_s) NULL
#define BMM150_CAL(_s) NULL
#define BMM150_MAG_MAX_FREQ(_preset) __BMM150_MAG_MAX_FREQ(_preset)
#endif

/* Specific initialization of BMM150 when behing BMI160 */
int bmm150_init(struct motion_sensor_t *s);

/* Command to normalize and apply temperature compensation */
void bmm150_normalize(const struct motion_sensor_t *s, intv3_t v,
		      uint8_t *data);

int bmm150_set_offset(const struct motion_sensor_t *s, const intv3_t offset);

int bmm150_get_offset(const struct motion_sensor_t *s, intv3_t offset);

#endif /* __CROS_EC_MAG_BMM150_H */