148 lines
4.2 KiB
C
148 lines
4.2 KiB
C
/* 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;
|
|
};
|
|
#define BMM150_COMP_REG(_s) \
|
|
(&BMI160_GET_DATA(_s)->compass.comp)
|
|
|
|
#define BMM150_CAL(_s) \
|
|
(&BMI160_GET_DATA(_s)->compass.cal)
|
|
|
|
#ifdef CONFIG_MAG_BMI160_BMM150
|
|
#include "accelgyro_bmi160.h"
|
|
/*
|
|
* Behind a BMI160, the BMM150 is in forced mode. Be sure to choose a frequency
|
|
* comptible with BMI160.
|
|
*/
|
|
#define BMM150_MAG_MAX_FREQ(_preset) \
|
|
BMI160_REG_TO_ODR(BMI160_ODR_TO_REG(__BMM150_MAG_MAX_FREQ(_preset)))
|
|
#else
|
|
#define BMM150_MAG_MAX_FREQ(_preset) __BMM150_MAG_MAX_FREQ(_preset)
|
|
#endif
|
|
|
|
/* Specific initialization of BMM150 when behing BMI160 */
|
|
int bmm150_init(const 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 */
|