Skip to content
Permalink
Browse files

sensor: fxos8700: add support for hardware reset pin

Add support for pulsing the hardware reset pin of the FXOS8700 high
during initialization.

According to the datasheet, this is required for the I2C/SPI bus
auto-detection logic to work properly if the VDD/VDDIO power
sequencing order cannot be guaranteed.

Signed-off-by: Henrik Brix Andersen <henrik@brixandersen.dk>
  • Loading branch information...
henrikbrixandersen authored and nashif committed Apr 8, 2019
1 parent 08d41ec commit 917cb432eeaf1219fb81c9b4df685158691542a8
Showing with 51 additions and 13 deletions.
  1. +44 −13 drivers/sensor/fxos8700/fxos8700.c
  2. +2 −0 drivers/sensor/fxos8700/fxos8700.h
  3. +5 −0 dts/bindings/sensor/nxp,fxos8700.yaml
@@ -372,6 +372,7 @@ static int fxos8700_init(struct device *dev)
const struct fxos8700_config *config = dev->config->config_info;
struct fxos8700_data *data = dev->driver_data;
struct sensor_value odr = {.val1 = 6, .val2 = 250000};
struct device *rst;

/* Get the I2C device */
data->i2c = device_get_binding(config->i2c_name);
@@ -380,6 +381,42 @@ static int fxos8700_init(struct device *dev)
return -EINVAL;
}

if (config->reset_name) {
/* Pulse RST pin high to perform a hardware reset of
* the sensor.
*/
rst = device_get_binding(config->reset_name);
if (!rst) {
LOG_ERR("Could not find reset GPIO device");
return -EINVAL;
}

gpio_pin_configure(rst, config->reset_pin, GPIO_DIR_OUT);
gpio_pin_write(rst, config->reset_pin, 1);
/* The datasheet does not mention how long to pulse
* the RST pin high in order to reset. Stay on the
* safe side and pulse for 1 millisecond.
*/
k_busy_wait(USEC_PER_MSEC);
gpio_pin_write(rst, config->reset_pin, 0);
} else {
/* Software reset the sensor. Upon issuing a software
* reset command over the I2C interface, the sensor
* immediately resets and does not send any
* acknowledgment (ACK) of the written byte to the
* master. Therefore, do not check the return code of
* the I2C transaction.
*/
i2c_reg_write_byte(data->i2c, config->i2c_address,
FXOS8700_REG_CTRLREG2,
FXOS8700_CTRLREG2_RST_MASK);
}

/* The sensor requires us to wait 1 ms after a reset before
* attempting further communications.
*/
k_busy_wait(USEC_PER_MSEC);

/*
* Read the WHOAMI register to make sure we are talking to FXOS8700 or
* compatible device and not some other type of device that happens to
@@ -410,19 +447,6 @@ static int fxos8700_init(struct device *dev)
return -EIO;
}

/* Reset the sensor. Upon issuing a software reset command over the I2C
* interface, the sensor immediately resets and does not send any
* acknowledgment (ACK) of the written byte to the master. Therefore,
* do not check the return code of the I2C transaction.
*/
i2c_reg_write_byte(data->i2c, config->i2c_address,
FXOS8700_REG_CTRLREG2, FXOS8700_CTRLREG2_RST_MASK);

/* The sensor requires us to wait 1 ms after a software reset before
* attempting further communications.
*/
k_busy_wait(USEC_PER_MSEC);

if (fxos8700_set_odr(dev, &odr)) {
LOG_ERR("Could not set default data rate");
return -EIO;
@@ -498,6 +522,13 @@ static const struct sensor_driver_api fxos8700_driver_api = {
static const struct fxos8700_config fxos8700_config = {
.i2c_name = DT_NXP_FXOS8700_0_BUS_NAME,
.i2c_address = DT_NXP_FXOS8700_0_BASE_ADDRESS,
#ifdef DT_NXP_FXOS8700_0_RESET_GPIOS_CONTROLLER
.reset_name = DT_NXP_FXOS8700_0_RESET_GPIOS_CONTROLLER,
.reset_pin = DT_NXP_FXOS8700_0_RESET_GPIOS_PIN,
#else
.reset_name = NULL,
.reset_pin = 0,
#endif
#ifdef CONFIG_FXOS8700_MODE_ACCEL
.mode = FXOS8700_MODE_ACCEL,
.start_addr = FXOS8700_REG_OUTXMSB,
@@ -126,6 +126,8 @@ struct fxos8700_config {
u8_t gpio_pin;
#endif
u8_t i2c_address;
char *reset_name;
u8_t reset_pin;
enum fxos8700_mode mode;
enum fxos8700_power_mode power_mode;
enum fxos8700_range range;
@@ -18,6 +18,11 @@ properties:
compatible:
constraint: "nxp,fxos8700"

reset-gpios:
type: compound
category: optional
generation: define, use-prop-name

int1-gpios:
type: compound
category: optional

0 comments on commit 917cb43

Please sign in to comment.
You can’t perform that action at this time.