static void bma280_fiber_cb(void *arg) { struct device *dev = arg; struct bma280_data *drv_data = dev->driver_data; uint8_t status = 0; /* check for data ready */ i2c_reg_read_byte(drv_data->i2c, BMA280_I2C_ADDRESS, BMA280_REG_INT_STATUS_1, &status); if (status & BMA280_BIT_DATA_INT_STATUS && drv_data->data_ready_handler != NULL) { drv_data->data_ready_handler(dev, &drv_data->data_ready_trigger); } /* check for any motion */ i2c_reg_read_byte(drv_data->i2c, BMA280_I2C_ADDRESS, BMA280_REG_INT_STATUS_0, &status); if (status & BMA280_BIT_SLOPE_INT_STATUS && drv_data->any_motion_handler != NULL) { drv_data->any_motion_handler(dev, &drv_data->data_ready_trigger); /* clear latched interrupt */ i2c_reg_update_byte(drv_data->i2c, BMA280_I2C_ADDRESS, BMA280_REG_INT_RST_LATCH, BMA280_BIT_INT_LATCH_RESET, BMA280_BIT_INT_LATCH_RESET); } gpio_pin_enable_callback(drv_data->gpio, CONFIG_BMA280_GPIO_PIN_NUM); }
static void sx9500_thread_main(int arg1, int unused) { struct device *dev = INT_TO_POINTER(arg1); struct sx9500_data *data = dev->driver_data; uint8_t reg_val; ARG_UNUSED(unused); while (1) { k_sem_take(&data->sem, K_FOREVER); if (i2c_reg_read_byte(data->i2c_master, data->i2c_slave_addr, SX9500_REG_IRQ_SRC, ®_val) < 0) { SYS_LOG_DBG("sx9500: error %d reading IRQ source register", ret); continue; } if ((reg_val & SX9500_CONV_DONE_IRQ) && data->handler_drdy) { data->handler_drdy(dev, &data->trigger_drdy); } if ((reg_val & SX9500_NEAR_FAR_IRQ) && data->handler_near_far) { data->handler_near_far(dev, &data->trigger_near_far); } } }
static int sx9500_init_chip(struct device *dev) { struct sx9500_data *data = (struct sx9500_data *) dev->driver_data; u8_t val; if (i2c_write(data->i2c_master, sx9500_reg_defaults, sizeof(sx9500_reg_defaults), data->i2c_slave_addr) < 0) { return -EIO; } /* No interrupts active. We only activate them when an * application registers a trigger. */ if (i2c_reg_write_byte(data->i2c_master, data->i2c_slave_addr, SX9500_REG_IRQ_MSK, 0) < 0) { return -EIO; } /* Read irq source reg to clear reset status. */ if (i2c_reg_read_byte(data->i2c_master, data->i2c_slave_addr, SX9500_REG_IRQ_SRC, &val) < 0) { return -EIO; } return i2c_reg_write_byte(data->i2c_master, data->i2c_slave_addr, SX9500_REG_PROX_CTRL0, 1 << CONFIG_SX9500_PROX_CHANNEL); }
static int fxos8700_sample_fetch(struct device *dev, enum sensor_channel chan) { const struct fxos8700_config *config = dev->config->config_info; struct fxos8700_data *data = dev->driver_data; u8_t buffer[FXOS8700_MAX_NUM_BYTES]; u8_t num_bytes; s16_t *raw; int ret = 0; int i; if (chan != SENSOR_CHAN_ALL) { LOG_ERR("Unsupported sensor channel"); return -ENOTSUP; } k_sem_take(&data->sem, K_FOREVER); /* Read all the channels in one I2C transaction. The number of bytes to * read and the starting register address depend on the mode * configuration (accel-only, mag-only, or hybrid). */ num_bytes = config->num_channels * FXOS8700_BYTES_PER_CHANNEL_NORMAL; __ASSERT(num_bytes <= sizeof(buffer), "Too many bytes to read"); if (i2c_burst_read(data->i2c, config->i2c_address, config->start_addr, buffer, num_bytes)) { LOG_ERR("Could not fetch sample"); ret = -EIO; goto exit; } /* Parse the buffer into raw channel data (16-bit integers). To save * RAM, store the data in raw format and wait to convert to the * normalized sensor_value type until later. */ __ASSERT(config->start_channel + config->num_channels <= ARRAY_SIZE(data->raw), "Too many channels"); raw = &data->raw[config->start_channel]; for (i = 0; i < num_bytes; i += 2) { *raw++ = (buffer[i] << 8) | (buffer[i+1]); } #ifdef CONFIG_FXOS8700_TEMP if (i2c_reg_read_byte(data->i2c, config->i2c_address, FXOS8700_REG_TEMP, &data->temp)) { LOG_ERR("Could not fetch temperature"); ret = -EIO; goto exit; } #endif exit: k_sem_give(&data->sem); return ret; }
static int lps25hb_sample_fetch(struct device *dev, enum sensor_channel chan) { struct lps25hb_data *data = dev->driver_data; const struct lps25hb_config *config = dev->config->config_info; u8_t out[5]; int offset; __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL); for (offset = 0; offset < sizeof(out); ++offset) { if (i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr, LPS25HB_REG_PRESS_OUT_XL + offset, out + offset) < 0) { SYS_LOG_DBG("failed to read sample"); return -EIO; } } data->sample_press = (s32_t)((u32_t)(out[0]) | ((u32_t)(out[1]) << 8) | ((u32_t)(out[2]) << 16)); data->sample_temp = (s16_t)((u16_t)(out[3]) | ((u16_t)(out[4]) << 8)); return 0; }
static int sx9500_sample_fetch(struct device *dev, enum sensor_channel chan) { struct sx9500_data *data = (struct sx9500_data *) dev->driver_data; __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_PROX); return i2c_reg_read_byte(data->i2c_master, data->i2c_slave_addr, SX9500_REG_STAT, &data->prox_stat); }
static inline int lsm9ds0_mfd_sample_fetch_temp(struct device *dev) { struct lsm9ds0_mfd_data *data = dev->driver_data; const struct lsm9ds0_mfd_config *config = dev->config->config_info; u8_t out_l, out_h; if (i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_MFD_REG_OUT_TEMP_L_XM, &out_l) < 0 || i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_MFD_REG_OUT_TEMP_H_XM, &out_h) < 0) { SYS_LOG_DBG("failed to read temperature sample\n"); return -EIO; } data->sample_temp = (s16_t)((u16_t)(out_l) | ((u16_t)(out_h) << 8)); return 0; }
static int lsm9ds0_gyro_init_chip(struct device *dev) { struct lsm9ds0_gyro_data *data = dev->driver_data; const struct lsm9ds0_gyro_config *config = dev->config->config_info; uint8_t chip_id; if (lsm9ds0_gyro_power_ctrl(dev, 0, 0, 0, 0) < 0) { SYS_LOG_DBG("failed to power off device"); return -EIO; } if (lsm9ds0_gyro_power_ctrl(dev, 1, 1, 1, 1) < 0) { SYS_LOG_DBG("failed to power on device"); return -EIO; } if (i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_GYRO_REG_WHO_AM_I_G, &chip_id) < 0) { SYS_LOG_DBG("failed reading chip id"); goto err_poweroff; } if (chip_id != LSM9DS0_GYRO_VAL_WHO_AM_I_G) { SYS_LOG_DBG("invalid chip id 0x%x", chip_id); goto err_poweroff; } SYS_LOG_DBG("chip id 0x%x", chip_id); if (lsm9ds0_gyro_set_fs_raw(dev, LSM9DS0_GYRO_DEFAULT_FULLSCALE) < 0) { SYS_LOG_DBG("failed to set full-scale"); goto err_poweroff; } if (lsm9ds0_gyro_set_odr_raw(dev, LSM9DS0_GYRO_DEFAULT_SAMPLING_RATE) < 0) { SYS_LOG_DBG("failed to set sampling rate"); goto err_poweroff; } if (i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_GYRO_REG_CTRL_REG4_G, LSM9DS0_GYRO_MASK_CTRL_REG4_G_BDU | LSM9DS0_GYRO_MASK_CTRL_REG4_G_BLE, (1 << LSM9DS0_GYRO_SHIFT_CTRL_REG4_G_BDU) | (0 << LSM9DS0_GYRO_SHIFT_CTRL_REG4_G_BLE)) < 0) { SYS_LOG_DBG("failed to set BDU and BLE"); goto err_poweroff; } return 0; err_poweroff: lsm9ds0_gyro_power_ctrl(dev, 0, 0, 0, 0); return -EIO; }
static int lsm9ds0_gyro_sample_fetch(struct device *dev, enum sensor_channel chan) { struct lsm9ds0_gyro_data *data = dev->driver_data; const struct lsm9ds0_gyro_config *config = dev->config->config_info; uint8_t x_l, x_h, y_l, y_h, z_l, z_h; __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_GYRO_ANY); if (i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_GYRO_REG_OUT_X_L_G, &x_l) < 0 || i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_GYRO_REG_OUT_X_H_G, &x_h) < 0 || i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_GYRO_REG_OUT_Y_L_G, &y_l) < 0 || i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_GYRO_REG_OUT_Y_H_G, &y_h) < 0 || i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_GYRO_REG_OUT_Z_L_G, &z_l) < 0 || i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_GYRO_REG_OUT_Z_H_G, &z_h) < 0) { SYS_LOG_DBG("failed to read sample"); return -EIO; } data->sample_x = (int16_t)((uint16_t)(x_l) | ((uint16_t)(x_h) << 8)); data->sample_y = (int16_t)((uint16_t)(y_l) | ((uint16_t)(y_h) << 8)); data->sample_z = (int16_t)((uint16_t)(z_l) | ((uint16_t)(z_h) << 8)); #if defined(CONFIG_LSM9DS0_GYRO_FULLSCALE_RUNTIME) data->sample_fs = data->fs; #endif return 0; }
int ak8975_init(struct device *dev) { struct ak8975_data *drv_data = dev->driver_data; u8_t id; drv_data->i2c = device_get_binding(CONFIG_AK8975_I2C_MASTER_DEV_NAME); if (drv_data->i2c == NULL) { SYS_LOG_ERR("Failed to get pointer to %s device!", CONFIG_AK8975_I2C_MASTER_DEV_NAME); return -EINVAL; } #ifdef CONFIG_MPU9150 /* wake up MPU9150 chip */ if (i2c_reg_update_byte(drv_data->i2c, MPU9150_I2C_ADDR, MPU9150_REG_PWR_MGMT1, MPU9150_SLEEP_EN, 0) < 0) { SYS_LOG_ERR("Failed to wake up MPU9150 chip."); return -EIO; } /* enable MPU9150 pass-though to have access to AK8975 */ if (i2c_reg_update_byte(drv_data->i2c, MPU9150_I2C_ADDR, MPU9150_REG_BYPASS_CFG, MPU9150_I2C_BYPASS_EN, MPU9150_I2C_BYPASS_EN) < 0) { SYS_LOG_ERR("Failed to enable pass-through mode for MPU9150."); return -EIO; } #endif /* check chip ID */ if (i2c_reg_read_byte(drv_data->i2c, CONFIG_AK8975_I2C_ADDR, AK8975_REG_CHIP_ID, &id) < 0) { SYS_LOG_ERR("Failed to read chip ID."); return -EIO; } if (id != AK8975_CHIP_ID) { SYS_LOG_ERR("Invalid chip ID."); return -EINVAL; } if (ak8975_read_adjustment_data(drv_data) < 0) { return -EIO; } dev->driver_api = &ak8975_driver_api; return 0; }
static int lps25hb_init_chip(struct device *dev) { struct lps25hb_data *data = dev->driver_data; const struct lps25hb_config *config = dev->config->config_info; u8_t chip_id; lps25hb_power_ctrl(dev, 0); k_busy_wait(50 * USEC_PER_MSEC); if (lps25hb_power_ctrl(dev, 1) < 0) { SYS_LOG_DBG("failed to power on device"); return -EIO; } k_busy_wait(20 * USEC_PER_MSEC); if (i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr, LPS25HB_REG_WHO_AM_I, &chip_id) < 0) { SYS_LOG_DBG("failed reading chip id"); goto err_poweroff; } if (chip_id != LPS25HB_VAL_WHO_AM_I) { SYS_LOG_DBG("invalid chip id 0x%x", chip_id); goto err_poweroff; } SYS_LOG_DBG("chip id 0x%x", chip_id); if (lps25hb_set_odr_raw(dev, LPS25HB_DEFAULT_SAMPLING_RATE) < 0) { SYS_LOG_DBG("failed to set sampling rate"); goto err_poweroff; } if (i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr, LPS25HB_REG_CTRL_REG1, LPS25HB_MASK_CTRL_REG1_BDU, (1 << LPS25HB_SHIFT_CTRL_REG1_BDU)) < 0) { SYS_LOG_DBG("failed to set BDU"); goto err_poweroff; } return 0; err_poweroff: lps25hb_power_ctrl(dev, 0); return -EIO; }
int fxos8700_get_power(struct device *dev, enum fxos8700_power *power) { const struct fxos8700_config *config = dev->config->config_info; struct fxos8700_data *data = dev->driver_data; u8_t val = *power; if (i2c_reg_read_byte(data->i2c, config->i2c_address, FXOS8700_REG_CTRLREG1, &val)) { LOG_ERR("Could not get power setting"); return -EIO; } val &= FXOS8700_M_CTRLREG1_MODE_MASK; *power = val; return 0; }
int fxas21002_get_power(struct device *dev, enum fxas21002_power *power) { const struct fxas21002_config *config = dev->config->config_info; struct fxas21002_data *data = dev->driver_data; u8_t val = *power; if (i2c_reg_read_byte(data->i2c, config->i2c_address, FXAS21002_REG_CTRLREG1, &val)) { SYS_LOG_ERR("Could not get power setting"); return -EIO; } val &= FXAS21002_CTRLREG1_POWER_MASK; *power = val; return 0; }
static inline int lsm9ds0_mfd_sample_fetch_accel(struct device *dev) { struct lsm9ds0_mfd_data *data = dev->driver_data; const struct lsm9ds0_mfd_config *config = dev->config->config_info; u8_t out_l, out_h; #if defined(CONFIG_LSM9DS0_MFD_ACCEL_ENABLE_X) if (i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_MFD_REG_OUT_X_L_A, &out_l) < 0 || i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_MFD_REG_OUT_X_H_A, &out_h) < 0) { SYS_LOG_DBG("failed to read accel sample (X axis)"); return -EIO; } data->sample_accel_x = (s16_t)((u16_t)(out_l) | ((u16_t)(out_h) << 8)); #endif #if defined(CONFIG_LSM9DS0_MFD_ACCEL_ENABLE_Y) if (i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_MFD_REG_OUT_Y_L_A, &out_l) < 0 || i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_MFD_REG_OUT_Y_H_A, &out_h) < 0) { SYS_LOG_DBG("failed to read accel sample (Y axis)"); return -EIO; } data->sample_accel_y = (s16_t)((u16_t)(out_l) | ((u16_t)(out_h) << 8)); #endif #if defined(CONFIG_LSM9DS0_MFD_ACCEL_ENABLE_Z) if (i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_MFD_REG_OUT_Z_L_A, &out_l) < 0 || i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_MFD_REG_OUT_Z_H_A, &out_h) < 0) { SYS_LOG_DBG("failed to read accel sample (Z axis)"); return -EIO; } data->sample_accel_z = (s16_t)((u16_t)(out_l) | ((u16_t)(out_h) << 8)); #endif #if defined(CONFIG_LSM9DS0_MFD_ACCEL_FULL_SCALE_RUNTIME) data->sample_accel_fs = data->accel_fs; #endif return 0; }
static void sx9500_gpio_thread_cb(void *arg) { struct device *dev = arg; struct sx9500_data *data = dev->driver_data; uint8_t reg_val; if (i2c_reg_read_byte(data->i2c_master, data->i2c_slave_addr, SX9500_REG_IRQ_SRC, ®_val) < 0) { SYS_LOG_DBG("sx9500: error %d reading IRQ source register", ret); return; } if ((reg_val & SX9500_CONV_DONE_IRQ) && data->handler_drdy) { data->handler_drdy(dev, &data->trigger_drdy); } if ((reg_val & SX9500_NEAR_FAR_IRQ) && data->handler_near_far) { data->handler_near_far(dev, &data->trigger_near_far); } }
static int fxas21002_init(struct device *dev) { const struct fxas21002_config *config = dev->config->config_info; struct fxas21002_data *data = dev->driver_data; u32_t transition_time; u8_t whoami; u8_t ctrlreg1; /* Get the I2C device */ data->i2c = device_get_binding(config->i2c_name); if (data->i2c == NULL) { SYS_LOG_ERR("Could not find I2C device"); return -EINVAL; } /* Read the WHOAMI register to make sure we are talking to FXAS21002 * and not some other type of device that happens to have the same I2C * address. */ if (i2c_reg_read_byte(data->i2c, config->i2c_address, FXAS21002_REG_WHOAMI, &whoami)) { SYS_LOG_ERR("Could not get WHOAMI value"); return -EIO; } if (whoami != config->whoami) { SYS_LOG_ERR("WHOAMI value received 0x%x, expected 0x%x", whoami, config->whoami); 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, FXAS21002_REG_CTRLREG1, FXAS21002_CTRLREG1_RST_MASK); /* Wait for the reset sequence to complete */ do { if (i2c_reg_read_byte(data->i2c, config->i2c_address, FXAS21002_REG_CTRLREG1, &ctrlreg1)) { SYS_LOG_ERR("Could not get ctrlreg1 value"); return -EIO; } } while (ctrlreg1 & FXAS21002_CTRLREG1_RST_MASK); /* Set the full-scale range */ if (i2c_reg_update_byte(data->i2c, config->i2c_address, FXAS21002_REG_CTRLREG0, FXAS21002_CTRLREG0_FS_MASK, config->range)) { SYS_LOG_ERR("Could not set range"); return -EIO; } /* Set the output data rate */ if (i2c_reg_update_byte(data->i2c, config->i2c_address, FXAS21002_REG_CTRLREG1, FXAS21002_CTRLREG1_DR_MASK, config->dr << FXAS21002_CTRLREG1_DR_SHIFT)) { SYS_LOG_ERR("Could not set output data rate"); return -EIO; } k_sem_init(&data->sem, 0, UINT_MAX); #if CONFIG_FXAS21002_TRIGGER if (fxas21002_trigger_init(dev)) { SYS_LOG_ERR("Could not initialize interrupts"); return -EIO; } #endif /* Set active */ if (fxas21002_set_power(dev, FXAS21002_POWER_ACTIVE)) { SYS_LOG_ERR("Could not set active"); return -EIO; } /* Wait the transition time from standby to active mode */ transition_time = fxas21002_get_transition_time(FXAS21002_POWER_STANDBY, FXAS21002_POWER_ACTIVE, config->dr); k_busy_wait(transition_time); k_sem_give(&data->sem); SYS_LOG_DBG("Init complete"); return 0; }
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}; /* Get the I2C device */ data->i2c = device_get_binding(config->i2c_name); if (data->i2c == NULL) { LOG_ERR("Could not find I2C device"); return -EINVAL; } /* * 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 * have the same I2C address. */ if (i2c_reg_read_byte(data->i2c, config->i2c_address, FXOS8700_REG_WHOAMI, &data->whoami)) { LOG_ERR("Could not get WHOAMI value"); return -EIO; } switch (data->whoami) { case WHOAMI_ID_MMA8451: case WHOAMI_ID_MMA8652: case WHOAMI_ID_MMA8653: if (config->mode != FXOS8700_MODE_ACCEL) { LOG_ERR("Device 0x%x supports only " "accelerometer mode", data->whoami); return -EIO; } case WHOAMI_ID_FXOS8700: LOG_DBG("Device ID 0x%x", data->whoami); break; default: LOG_ERR("Unknown Device ID 0x%x", data->whoami); 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; } if (i2c_reg_update_byte(data->i2c, config->i2c_address, FXOS8700_REG_CTRLREG2, FXOS8700_CTRLREG2_MODS_MASK, config->power_mode)) { LOG_ERR("Could not set power scheme"); return -EIO; } /* Set the mode (accel-only, mag-only, or hybrid) */ if (i2c_reg_update_byte(data->i2c, config->i2c_address, FXOS8700_REG_M_CTRLREG1, FXOS8700_M_CTRLREG1_MODE_MASK, config->mode)) { LOG_ERR("Could not set mode"); return -EIO; } /* Set hybrid autoincrement so we can read accel and mag channels in * one I2C transaction. */ if (i2c_reg_update_byte(data->i2c, config->i2c_address, FXOS8700_REG_M_CTRLREG2, FXOS8700_M_CTRLREG2_AUTOINC_MASK, FXOS8700_M_CTRLREG2_AUTOINC_MASK)) { LOG_ERR("Could not set hybrid autoincrement"); return -EIO; } /* Set the full-scale range */ if (i2c_reg_update_byte(data->i2c, config->i2c_address, FXOS8700_REG_XYZ_DATA_CFG, FXOS8700_XYZ_DATA_CFG_FS_MASK, config->range)) { LOG_ERR("Could not set range"); return -EIO; } k_sem_init(&data->sem, 0, UINT_MAX); #if CONFIG_FXOS8700_TRIGGER if (fxos8700_trigger_init(dev)) { LOG_ERR("Could not initialize interrupts"); return -EIO; } #endif /* Set active */ if (fxos8700_set_power(dev, FXOS8700_POWER_ACTIVE)) { LOG_ERR("Could not set active"); return -EIO; } k_sem_give(&data->sem); LOG_DBG("Init complete"); return 0; } static const struct sensor_driver_api fxos8700_driver_api = { .sample_fetch = fxos8700_sample_fetch, .channel_get = fxos8700_channel_get, .attr_set = fxos8700_attr_set, #if CONFIG_FXOS8700_TRIGGER .trigger_set = fxos8700_trigger_set, #endif }; static const struct fxos8700_config fxos8700_config = { .i2c_name = CONFIG_FXOS8700_I2C_NAME, .i2c_address = CONFIG_FXOS8700_I2C_ADDRESS, #ifdef CONFIG_FXOS8700_MODE_ACCEL .mode = FXOS8700_MODE_ACCEL, .start_addr = FXOS8700_REG_OUTXMSB, .start_channel = FXOS8700_CHANNEL_ACCEL_X, .num_channels = FXOS8700_NUM_ACCEL_CHANNELS, #elif CONFIG_FXOS8700_MODE_MAGN .mode = FXOS8700_MODE_MAGN, .start_addr = FXOS8700_REG_M_OUTXMSB, .start_channel = FXOS8700_CHANNEL_MAGN_X, .num_channels = FXOS8700_NUM_MAG_CHANNELS, #else .mode = FXOS8700_MODE_HYBRID, .start_addr = FXOS8700_REG_OUTXMSB, .start_channel = FXOS8700_CHANNEL_ACCEL_X, .num_channels = FXOS8700_NUM_HYBRID_CHANNELS, #endif #if CONFIG_FXOS8700_PM_NORMAL .power_mode = FXOS8700_PM_NORMAL, #elif CONFIG_FXOS8700_PM_LOW_NOISE_LOW_POWER .power_mode = FXOS8700_PM_LOW_NOISE_LOW_POWER, #elif CONFIG_FXOS8700_PM_HIGH_RESOLUTION .power_mode = FXOS8700_PM_HIGH_RESOLUTION, #else .power_mode = FXOS8700_PM_LOW_POWER, #endif #if CONFIG_FXOS8700_RANGE_8G .range = FXOS8700_RANGE_8G, #elif CONFIG_FXOS8700_RANGE_4G .range = FXOS8700_RANGE_4G, #else .range = FXOS8700_RANGE_2G, #endif #ifdef CONFIG_FXOS8700_TRIGGER .gpio_name = CONFIG_FXOS8700_GPIO_NAME, .gpio_pin = CONFIG_FXOS8700_GPIO_PIN, #endif #ifdef CONFIG_FXOS8700_PULSE .pulse_cfg = CONFIG_FXOS8700_PULSE_CFG, .pulse_ths[0] = CONFIG_FXOS8700_PULSE_THSX, .pulse_ths[1] = CONFIG_FXOS8700_PULSE_THSY, .pulse_ths[2] = CONFIG_FXOS8700_PULSE_THSZ, .pulse_tmlt = CONFIG_FXOS8700_PULSE_TMLT, .pulse_ltcy = CONFIG_FXOS8700_PULSE_LTCY, .pulse_wind = CONFIG_FXOS8700_PULSE_WIND, #endif }; static struct fxos8700_data fxos8700_data; DEVICE_AND_API_INIT(fxos8700, CONFIG_FXOS8700_NAME, fxos8700_init, &fxos8700_data, &fxos8700_config, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &fxos8700_driver_api);
static int adt7420_temp_reg_write(struct device *dev, u8_t reg, s16_t val) { struct adt7420_data *drv_data = dev->driver_data; const struct adt7420_dev_config *cfg = dev->config->config_info; u8_t buf[3] = {reg, val >> 8, val & 0xFF}; return i2c_write(drv_data->i2c, buf, sizeof(buf), cfg->i2c_addr); } static int adt7420_attr_set(struct device *dev, enum sensor_channel chan, enum sensor_attribute attr, const struct sensor_value *val) { struct adt7420_data *drv_data = dev->driver_data; const struct adt7420_dev_config *cfg = dev->config->config_info; u8_t val8, reg = 0; u16_t rate; s64_t value; if (chan != SENSOR_CHAN_AMBIENT_TEMP) { return -ENOTSUP; } switch (attr) { case SENSOR_ATTR_SAMPLING_FREQUENCY: rate = val->val1 * 1000 + val->val2 / 1000; /* rate in mHz */ switch (rate) { case 240: val8 = ADT7420_OP_MODE_CONT_CONV; break; case 1000: val8 = ADT7420_OP_MODE_1_SPS; break; default: return -EINVAL; } if (i2c_reg_update_byte(drv_data->i2c, cfg->i2c_addr, ADT7420_REG_CONFIG, ADT7420_CONFIG_OP_MODE(~0), ADT7420_CONFIG_OP_MODE(val8)) < 0) { LOG_DBG("Failed to set attribute!"); return -EIO; } return 0; case SENSOR_ATTR_UPPER_THRESH: reg = ADT7420_REG_T_HIGH_MSB; /* Fallthrough */ case SENSOR_ATTR_LOWER_THRESH: if (!reg) { reg = ADT7420_REG_T_LOW_MSB; } if ((val->val1 > 150) || (val->val1 < -40)) { return -EINVAL; } value = (s64_t)val->val1 * 1000000 + val->val2; value = (value / ADT7420_TEMP_SCALE) << 1; if (adt7420_temp_reg_write(dev, reg, value) < 0) { LOG_DBG("Failed to set attribute!"); return -EIO; } return 0; default: return -ENOTSUP; } return 0; } static int adt7420_sample_fetch(struct device *dev, enum sensor_channel chan) { struct adt7420_data *drv_data = dev->driver_data; s16_t value; __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_AMBIENT_TEMP); if (adt7420_temp_reg_read(dev, ADT7420_REG_TEMP_MSB, &value) < 0) { return -EIO; } drv_data->sample = value >> 1; /* use 15-bit only */ return 0; } static int adt7420_channel_get(struct device *dev, enum sensor_channel chan, struct sensor_value *val) { struct adt7420_data *drv_data = dev->driver_data; s32_t value; if (chan != SENSOR_CHAN_AMBIENT_TEMP) { return -ENOTSUP; } value = (s32_t)drv_data->sample * ADT7420_TEMP_SCALE; val->val1 = value / 1000000; val->val2 = value % 1000000; return 0; } static const struct sensor_driver_api adt7420_driver_api = { .attr_set = adt7420_attr_set, .sample_fetch = adt7420_sample_fetch, .channel_get = adt7420_channel_get, #ifdef CONFIG_ADT7420_TRIGGER .trigger_set = adt7420_trigger_set, #endif }; static int adt7420_probe(struct device *dev) { struct adt7420_data *drv_data = dev->driver_data; const struct adt7420_dev_config *cfg = dev->config->config_info; u8_t value; int ret; ret = i2c_reg_read_byte(drv_data->i2c, cfg->i2c_addr, ADT7420_REG_ID, &value); if (ret) { return ret; } if (value != ADT7420_DEFAULT_ID) return -ENODEV; ret = i2c_reg_write_byte(drv_data->i2c, cfg->i2c_addr, ADT7420_REG_CONFIG, ADT7420_CONFIG_RESOLUTION | ADT7420_CONFIG_OP_MODE(ADT7420_OP_MODE_CONT_CONV)); if (ret) { return ret; } ret = i2c_reg_write_byte(drv_data->i2c, cfg->i2c_addr, ADT7420_REG_HIST, CONFIG_ADT7420_TEMP_HYST); if (ret) { return ret; } ret = adt7420_temp_reg_write(dev, ADT7420_REG_T_CRIT_MSB, (CONFIG_ADT7420_TEMP_CRIT * 1000000 / ADT7420_TEMP_SCALE) << 1); if (ret) { return ret; } #ifdef CONFIG_ADT7420_TRIGGER if (adt7420_init_interrupt(dev) < 0) { LOG_ERR("Failed to initialize interrupt!"); return -EIO; } #endif return 0; } static int adt7420_init(struct device *dev) { struct adt7420_data *drv_data = dev->driver_data; const struct adt7420_dev_config *cfg = dev->config->config_info; drv_data->i2c = device_get_binding(cfg->i2c_port); if (drv_data->i2c == NULL) { LOG_DBG("Failed to get pointer to %s device!", cfg->i2c_port); return -EINVAL; } return adt7420_probe(dev); } static struct adt7420_data adt7420_driver; static const struct adt7420_dev_config adt7420_config = { .i2c_port = CONFIG_ADT7420_I2C_MASTER_DEV_NAME, .i2c_addr = CONFIG_ADT7420_I2C_ADDR, #ifdef CONFIG_ADT7420_TRIGGER .gpio_port = CONFIG_ADT7420_GPIO_DEV_NAME, .int_gpio = CONFIG_ADT7420_GPIO_PIN_NUM, #endif }; DEVICE_AND_API_INIT(adt7420, CONFIG_ADT7420_NAME, adt7420_init, &adt7420_driver, &adt7420_config, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &adt7420_driver_api);
static int lsm9ds0_mfd_init_chip(struct device *dev) { struct lsm9ds0_mfd_data *data = dev->driver_data; const struct lsm9ds0_mfd_config *config = dev->config->config_info; u8_t chip_id; if (lsm9ds0_mfd_reboot_memory(dev) < 0) { SYS_LOG_DBG("failed to reset device"); return -EIO; } if (i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_MFD_REG_WHO_AM_I_XM, &chip_id) < 0) { SYS_LOG_DBG("failed reading chip id"); return -EIO; } if (chip_id != LSM9DS0_MFD_VAL_WHO_AM_I_XM) { SYS_LOG_DBG("invalid chip id 0x%x", chip_id); return -EIO; } SYS_LOG_DBG("chip id 0x%x", chip_id); #if !defined(LSM9DS0_MFD_ACCEL_DISABLED) if (i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_MFD_REG_CTRL_REG1_XM, LSM9DS0_MFD_MASK_CTRL_REG1_XM_BDU | LSM9DS0_MFD_MASK_CTRL_REG1_XM_AODR, (1 << LSM9DS0_MFD_SHIFT_CTRL_REG1_XM_BDU) | (LSM9DS0_MFD_ACCEL_DEFAULT_AODR << LSM9DS0_MFD_SHIFT_CTRL_REG1_XM_AODR))) { SYS_LOG_DBG("failed to set AODR and BDU"); return -EIO; } if (lsm9ds0_mfd_accel_set_fs_raw(dev, LSM9DS0_MFD_ACCEL_DEFAULT_FS)) { SYS_LOG_DBG("failed to set accelerometer full-scale"); return -EIO; } if (i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_MFD_REG_CTRL_REG1_XM, LSM9DS0_MFD_MASK_CTRL_REG1_XM_AXEN | LSM9DS0_MFD_MASK_CTRL_REG1_XM_AYEN | LSM9DS0_MFD_MASK_CTRL_REG1_XM_AZEN, (LSM9DS0_MFD_ACCEL_ENABLE_X << LSM9DS0_MFD_SHIFT_CTRL_REG1_XM_AXEN) | (LSM9DS0_MFD_ACCEL_ENABLE_Y << LSM9DS0_MFD_SHIFT_CTRL_REG1_XM_AYEN) | (LSM9DS0_MFD_ACCEL_ENABLE_Z << LSM9DS0_MFD_SHIFT_CTRL_REG1_XM_AZEN)) < 0) { SYS_LOG_DBG("failed to set accelerometer axis enable bits\n"); return -EIO; } #elif !defined(LSM9DS0_MFD_MAGN_DISABLED) if (i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_MFD_REG_CTRL_REG1_XM, LSM9DS0_MFD_MASK_CTRL_REG1_XM_BDU, 1 << LSM9DS0_MFD_SHIFT_CTRL_REG1_XM_BDU) < 0) { SYS_LOG_DBG("failed to set BDU\n"); return -EIO; } #endif #if !defined(LSM9DS0_MFD_MAGN_DISABLED) if (i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_MFD_REG_CTRL_REG7_XM, LSM9DS0_MFD_MASK_CTRL_REG7_XM_MD, (0 << LSM9DS0_MFD_SHIFT_CTRL_REG7_XM_MD)) < 0) { SYS_LOG_DBG("failed to power on magnetometer"); return -EIO; } if (lsm9ds0_mfd_magn_set_odr_raw(dev, LSM9DS0_MFD_MAGN_DEFAULT_M_ODR)) { SYS_LOG_DBG("failed to set magnetometer sampling rate"); return -EIO; } if (lsm9ds0_mfd_magn_set_fs_raw(dev, LSM9DS0_MFD_MAGN_DEFAULT_FS)) { SYS_LOG_DBG("failed to set magnetometer full-scale"); return -EIO; } #endif #if !defined(LSM9DS0_MFD_TEMP_DISABLED) if (i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr, LSM9DS0_MFD_REG_CTRL_REG5_XM, LSM9DS0_MFD_MASK_CTRL_REG5_XM_TEMP_EN, 1 << LSM9DS0_MFD_SHIFT_CTRL_REG5_XM_TEMP_EN) < 0) { SYS_LOG_DBG("failed to power on temperature sensor"); return -EIO; } #endif return 0; }
static int apds9960_sensor_setup(struct device *dev) { struct apds9960_data *data = dev->driver_data; u8_t chip_id; if (i2c_reg_read_byte(data->i2c, APDS9960_I2C_ADDRESS, APDS9960_ID_REG, &chip_id)) { LOG_ERR("Failed reading chip id"); return -EIO; } if (!((chip_id == APDS9960_ID_1) || (chip_id == APDS9960_ID_2))) { LOG_ERR("Invalid chip id 0x%x", chip_id); return -EIO; } /* Disable all functions and interrupts */ if (i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS, APDS9960_ENABLE_REG, 0)) { LOG_ERR("ENABLE register is not cleared"); return -EIO; } if (i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS, APDS9960_AICLEAR_REG, 0)) { return -EIO; } /* Disable gesture interrupt */ if (i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS, APDS9960_GCONFIG4_REG, 0)) { LOG_ERR("GCONFIG4 register is not cleared"); return -EIO; } if (i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS, APDS9960_WTIME_REG, APDS9960_DEFAULT_WTIME)) { LOG_ERR("Default wait time not set"); return -EIO; } if (i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS, APDS9960_CONFIG1_REG, APDS9960_DEFAULT_CONFIG1)) { LOG_ERR("Default WLONG not set"); return -EIO; } if (i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS, APDS9960_CONFIG2_REG, APDS9960_DEFAULT_CONFIG2)) { LOG_ERR("Configuration Register Two not set"); return -EIO; } if (i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS, APDS9960_CONFIG3_REG, APDS9960_DEFAULT_CONFIG3)) { LOG_ERR("Configuration Register Three not set"); return -EIO; } if (i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS, APDS9960_PERS_REG, APDS9960_DEFAULT_PERS)) { LOG_ERR("Interrupt persistence not set"); return -EIO; } if (apds9960_proxy_setup(dev, APDS9960_DEFAULT_PGAIN)) { LOG_ERR("Failed to setup proximity functionality"); return -EIO; } if (apds9960_ambient_setup(dev, APDS9960_DEFAULT_AGAIN)) { LOG_ERR("Failed to setup ambient light functionality"); return -EIO; } return 0; }
static int apds9960_sample_fetch(struct device *dev, enum sensor_channel chan) { struct apds9960_data *data = dev->driver_data; u8_t status; if (chan != SENSOR_CHAN_ALL) { LOG_ERR("Unsupported sensor channel"); return -ENOTSUP; } #ifndef CONFIG_APDS9960_TRIGGER gpio_pin_enable_callback(data->gpio, DT_AVAGO_APDS9960_0_INT_GPIOS_PIN); if (i2c_reg_update_byte(data->i2c, APDS9960_I2C_ADDRESS, APDS9960_ENABLE_REG, APDS9960_ENABLE_PON | APDS9960_ENABLE_AIEN, APDS9960_ENABLE_PON | APDS9960_ENABLE_AIEN)) { LOG_ERR("Power on bit not set."); return -EIO; } k_sem_take(&data->data_sem, K_FOREVER); #endif if (i2c_reg_read_byte(data->i2c, APDS9960_I2C_ADDRESS, APDS9960_STATUS_REG, &status)) { return -EIO; } LOG_DBG("status: 0x%x", status); if (status & APDS9960_STATUS_PINT) { if (i2c_reg_read_byte(data->i2c, APDS9960_I2C_ADDRESS, APDS9960_PDATA_REG, &data->pdata)) { return -EIO; } } if (status & APDS9960_STATUS_AINT) { if (i2c_burst_read(data->i2c, APDS9960_I2C_ADDRESS, APDS9960_CDATAL_REG, (u8_t *)&data->sample_crgb, sizeof(data->sample_crgb))) { return -EIO; } } #ifndef CONFIG_APDS9960_TRIGGER if (i2c_reg_update_byte(data->i2c, APDS9960_I2C_ADDRESS, APDS9960_ENABLE_REG, APDS9960_ENABLE_PON, 0)) { return -EIO; } #endif if (i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS, APDS9960_AICLEAR_REG, 0)) { return -EIO; } return 0; }
int mpu6050_init(struct device *dev) { struct mpu6050_data *drv_data = dev->driver_data; u8_t id, i; drv_data->i2c = device_get_binding(CONFIG_MPU6050_I2C_MASTER_DEV_NAME); if (drv_data->i2c == NULL) { SYS_LOG_ERR("Failed to get pointer to %s device", CONFIG_MPU6050_I2C_MASTER_DEV_NAME); return -EINVAL; } /* check chip ID */ if (i2c_reg_read_byte(drv_data->i2c, CONFIG_MPU6050_I2C_ADDR, MPU6050_REG_CHIP_ID, &id) < 0) { SYS_LOG_ERR("Failed to read chip ID."); return -EIO; } if (id != MPU6050_CHIP_ID) { SYS_LOG_ERR("Invalid chip ID."); return -EINVAL; } /* wake up chip */ if (i2c_reg_update_byte(drv_data->i2c, CONFIG_MPU6050_I2C_ADDR, MPU6050_REG_PWR_MGMT1, MPU6050_SLEEP_EN, 0) < 0) { SYS_LOG_ERR("Failed to wake up chip."); return -EIO; } /* set accelerometer full-scale range */ for (i = 0; i < 4; i++) { if (BIT(i+1) == CONFIG_MPU6050_ACCEL_FS) { break; } } if (i == 4) { SYS_LOG_ERR("Invalid value for accel full-scale range."); return -EINVAL; } if (i2c_reg_write_byte(drv_data->i2c, CONFIG_MPU6050_I2C_ADDR, MPU6050_REG_ACCEL_CFG, i << MPU6050_ACCEL_FS_SHIFT) < 0) { SYS_LOG_ERR("Failed to write accel full-scale range."); return -EIO; } drv_data->accel_sensitivity_shift = 14 - i; /* set gyroscope full-scale range */ for (i = 0; i < 4; i++) { if (BIT(i) * 250 == CONFIG_MPU6050_GYRO_FS) { break; } } if (i == 4) { SYS_LOG_ERR("Invalid value for gyro full-scale range."); return -EINVAL; } if (i2c_reg_write_byte(drv_data->i2c, CONFIG_MPU6050_I2C_ADDR, MPU6050_REG_GYRO_CFG, i << MPU6050_GYRO_FS_SHIFT) < 0) { SYS_LOG_ERR("Failed to write gyro full-scale range."); return -EIO; } drv_data->gyro_sensitivity_x10 = mpu6050_gyro_sensitivity_x10[i]; #ifdef CONFIG_MPU6050_TRIGGER if (mpu6050_init_interrupt(dev) < 0) { SYS_LOG_DBG("Failed to initialize interrupts."); return -EIO; } #endif return 0; }
static int lsm6ds0_init_chip(struct device *dev) { struct lsm6ds0_data *data = dev->driver_data; const struct lsm6ds0_config *config = dev->config->config_info; u8_t chip_id; if (lsm6ds0_reboot(dev) < 0) { LOG_DBG("failed to reboot device"); return -EIO; } if (i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr, LSM6DS0_REG_WHO_AM_I, &chip_id) < 0) { LOG_DBG("failed reading chip id"); return -EIO; } if (chip_id != LSM6DS0_VAL_WHO_AM_I) { LOG_DBG("invalid chip id 0x%x", chip_id); return -EIO; } LOG_DBG("chip id 0x%x", chip_id); if (lsm6ds0_accel_axis_ctrl(dev, LSM6DS0_ACCEL_ENABLE_X_AXIS, LSM6DS0_ACCEL_ENABLE_Y_AXIS, LSM6DS0_ACCEL_ENABLE_Z_AXIS) < 0) { LOG_DBG("failed to set accelerometer axis"); return -EIO; } if (lsm6ds0_accel_set_fs_raw(dev, LSM6DS0_DEFAULT_ACCEL_FULLSCALE) < 0) { LOG_DBG("failed to set accelerometer full-scale"); return -EIO; } if (lsm6ds0_accel_set_odr_raw(dev, LSM6DS0_DEFAULT_ACCEL_SAMPLING_RATE) < 0) { LOG_DBG("failed to set accelerometer sampling rate"); return -EIO; } if (lsm6ds0_gyro_axis_ctrl(dev, LSM6DS0_GYRO_ENABLE_X_AXIS, LSM6DS0_GYRO_ENABLE_Y_AXIS, LSM6DS0_GYRO_ENABLE_Z_AXIS) < 0) { LOG_DBG("failed to set gyroscope axis"); return -EIO; } if (lsm6ds0_gyro_set_fs_raw(dev, LSM6DS0_DEFAULT_GYRO_FULLSCALE) < 0) { LOG_DBG("failed to set gyroscope full-scale"); return -EIO; } if (lsm6ds0_gyro_set_odr_raw(dev, LSM6DS0_DEFAULT_GYRO_SAMPLING_RATE) < 0) { LOG_DBG("failed to set gyroscope sampling rate"); return -EIO; } if (i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr, LSM6DS0_REG_CTRL_REG8, LSM6DS0_MASK_CTRL_REG8_BDU | LSM6DS0_MASK_CTRL_REG8_BLE | LSM6DS0_MASK_CTRL_REG8_IF_ADD_INC, (1 << LSM6DS0_SHIFT_CTRL_REG8_BDU) | (0 << LSM6DS0_SHIFT_CTRL_REG8_BLE) | (1 << LSM6DS0_SHIFT_CTRL_REG8_IF_ADD_INC)) < 0) { LOG_DBG("failed to set BDU, BLE and burst"); return -EIO; } return 0; }
static int fxos8700_init(struct device *dev) { const struct fxos8700_config *config = dev->config->config_info; struct fxos8700_data *data = dev->driver_data; u8_t whoami; /* Get the I2C device */ data->i2c = device_get_binding(config->i2c_name); if (data->i2c == NULL) { SYS_LOG_ERR("Could not find I2C device"); return -EINVAL; } /* Read the WHOAMI register to make sure we are talking to FXOS8700 and * not some other type of device that happens to have the same I2C * address. */ if (i2c_reg_read_byte(data->i2c, config->i2c_address, FXOS8700_REG_WHOAMI, &whoami)) { SYS_LOG_ERR("Could not get WHOAMI value"); return -EIO; } if (whoami != config->whoami) { SYS_LOG_ERR("WHOAMI value received 0x%x, expected 0x%x", whoami, FXOS8700_REG_WHOAMI); 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); /* Set the mode (accel-only, mag-only, or hybrid) */ if (i2c_reg_update_byte(data->i2c, config->i2c_address, FXOS8700_REG_M_CTRLREG1, FXOS8700_M_CTRLREG1_MODE_MASK, config->mode)) { SYS_LOG_ERR("Could not set mode"); return -EIO; } /* Set hybrid autoincrement so we can read accel and mag channels in * one I2C transaction. */ if (i2c_reg_update_byte(data->i2c, config->i2c_address, FXOS8700_REG_M_CTRLREG2, FXOS8700_M_CTRLREG2_AUTOINC_MASK, FXOS8700_M_CTRLREG2_AUTOINC_MASK)) { SYS_LOG_ERR("Could not set hybrid autoincrement"); return -EIO; } /* Set the full-scale range */ if (i2c_reg_update_byte(data->i2c, config->i2c_address, FXOS8700_REG_XYZ_DATA_CFG, FXOS8700_XYZ_DATA_CFG_FS_MASK, config->range)) { SYS_LOG_ERR("Could not set range"); return -EIO; } #if CONFIG_FXOS8700_TRIGGER if (fxos8700_trigger_init(dev)) { SYS_LOG_ERR("Could not initialize interrupts"); return -EIO; } #endif /* Set active */ if (fxos8700_set_power(dev, FXOS8700_POWER_ACTIVE)) { SYS_LOG_ERR("Could not set active"); return -EIO; } k_sem_init(&data->sem, 1, UINT_MAX); SYS_LOG_DBG("Init complete"); return 0; }