drivers: sensor: mpu6050: convert to devicetree

Add a binding for the sensor and replace all Kconfig selection of
hardware parameters with devicetree property values.

Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit is contained in:
Peter Bigot 2019-12-22 08:47:38 -06:00 committed by Carles Cufí
commit fe018f51a2
6 changed files with 77 additions and 60 deletions

View file

@ -11,28 +11,6 @@ menuconfig MPU6050
if MPU6050
config MPU6050_NAME
string "Driver name"
default "MPU6050"
help
Device name with which the MPU6050 sensor is identified.
config MPU6050_I2C_ADDR
hex "I2C address"
default 0x68
range 0x68 0x69
help
I2C address of the MPU6050 sensor.
Choose 0x68 if the AD0 pin is pulled to GND or 0x69 if the AD0 pin
is pulled to VDD.
config MPU6050_I2C_MASTER_DEV_NAME
string "I2C master where MPU6050 is connected"
default "I2C_0"
help
Specify the device name of the I2C master device to which MPU6050 is
connected.
choice
prompt "Trigger mode"
default MPU6050_TRIGGER_GLOBAL_THREAD
@ -57,22 +35,6 @@ endchoice
config MPU6050_TRIGGER
bool
config MPU6050_GPIO_DEV_NAME
string "GPIO device"
default "GPIO_0"
depends on MPU6050_TRIGGER
help
The device name of the GPIO device to which the MPU6050 interrupt pin
is connected.
config MPU6050_GPIO_PIN_NUM
int "Interrupt GPIO pin number"
default 0
depends on MPU6050_TRIGGER
help
The number of the GPIO on which the interrupt signal from the MPU6050
chip will be received.
config MPU6050_THREAD_PRIORITY
int "Thread priority"
depends on MPU6050_TRIGGER_OWN_THREAD

View file

@ -110,9 +110,10 @@ static int mpu6050_channel_get(struct device *dev,
static int mpu6050_sample_fetch(struct device *dev, enum sensor_channel chan)
{
struct mpu6050_data *drv_data = dev->driver_data;
const struct mpu6050_config *cfg = dev->config->config_info;
s16_t buf[7];
if (i2c_burst_read(drv_data->i2c, CONFIG_MPU6050_I2C_ADDR,
if (i2c_burst_read(drv_data->i2c, cfg->i2c_addr,
MPU6050_REG_DATA_START, (u8_t *)buf, 14) < 0) {
LOG_ERR("Failed to read data sample.");
return -EIO;
@ -140,17 +141,18 @@ static const struct sensor_driver_api mpu6050_driver_api = {
int mpu6050_init(struct device *dev)
{
struct mpu6050_data *drv_data = dev->driver_data;
const struct mpu6050_config *cfg = dev->config->config_info;
u8_t id, i;
drv_data->i2c = device_get_binding(CONFIG_MPU6050_I2C_MASTER_DEV_NAME);
drv_data->i2c = device_get_binding(cfg->i2c_label);
if (drv_data->i2c == NULL) {
LOG_ERR("Failed to get pointer to %s device",
CONFIG_MPU6050_I2C_MASTER_DEV_NAME);
cfg->i2c_label);
return -EINVAL;
}
/* check chip ID */
if (i2c_reg_read_byte(drv_data->i2c, CONFIG_MPU6050_I2C_ADDR,
if (i2c_reg_read_byte(drv_data->i2c, cfg->i2c_addr,
MPU6050_REG_CHIP_ID, &id) < 0) {
LOG_ERR("Failed to read chip ID.");
return -EIO;
@ -162,7 +164,7 @@ int mpu6050_init(struct device *dev)
}
/* wake up chip */
if (i2c_reg_update_byte(drv_data->i2c, CONFIG_MPU6050_I2C_ADDR,
if (i2c_reg_update_byte(drv_data->i2c, cfg->i2c_addr,
MPU6050_REG_PWR_MGMT1, MPU6050_SLEEP_EN,
0) < 0) {
LOG_ERR("Failed to wake up chip.");
@ -181,7 +183,7 @@ int mpu6050_init(struct device *dev)
return -EINVAL;
}
if (i2c_reg_write_byte(drv_data->i2c, CONFIG_MPU6050_I2C_ADDR,
if (i2c_reg_write_byte(drv_data->i2c, cfg->i2c_addr,
MPU6050_REG_ACCEL_CFG,
i << MPU6050_ACCEL_FS_SHIFT) < 0) {
LOG_ERR("Failed to write accel full-scale range.");
@ -202,7 +204,7 @@ int mpu6050_init(struct device *dev)
return -EINVAL;
}
if (i2c_reg_write_byte(drv_data->i2c, CONFIG_MPU6050_I2C_ADDR,
if (i2c_reg_write_byte(drv_data->i2c, cfg->i2c_addr,
MPU6050_REG_GYRO_CFG,
i << MPU6050_GYRO_FS_SHIFT) < 0) {
LOG_ERR("Failed to write gyro full-scale range.");
@ -221,8 +223,18 @@ int mpu6050_init(struct device *dev)
return 0;
}
struct mpu6050_data mpu6050_driver;
static struct mpu6050_data mpu6050_driver;
static const struct mpu6050_config mpu6050_cfg = {
.i2c_label = DT_INST_0_INVENSENSE_MPU6050_BUS_NAME,
.i2c_addr = DT_INST_0_INVENSENSE_MPU6050_BASE_ADDRESS,
#ifdef CONFIG_MPU6050_TRIGGER
.int_pin = DT_INST_0_INVENSENSE_MPU6050_INT_GPIOS_PIN,
.int_flags = DT_INST_0_INVENSENSE_MPU6050_INT_GPIOS_FLAGS,
.int_label = DT_INST_0_INVENSENSE_MPU6050_INT_GPIOS_CONTROLLER,
#endif /* CONFIG_MPU6050_TRIGGER */
};
DEVICE_AND_API_INIT(mpu6050, CONFIG_MPU6050_NAME, mpu6050_init, &mpu6050_driver,
NULL, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY,
DEVICE_AND_API_INIT(mpu6050, DT_INST_0_INVENSENSE_MPU6050_LABEL,
mpu6050_init, &mpu6050_driver, &mpu6050_cfg,
POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY,
&mpu6050_driver_api);

View file

@ -50,6 +50,7 @@ struct mpu6050_data {
u16_t gyro_sensitivity_x10;
#ifdef CONFIG_MPU6050_TRIGGER
struct device *dev;
struct device *gpio;
struct gpio_callback gpio_cb;
@ -62,12 +63,21 @@ struct mpu6050_data {
struct k_sem gpio_sem;
#elif defined(CONFIG_MPU6050_TRIGGER_GLOBAL_THREAD)
struct k_work work;
struct device *dev;
#endif
#endif /* CONFIG_MPU6050_TRIGGER */
};
struct mpu6050_config {
const char *i2c_label;
u16_t i2c_addr;
#ifdef CONFIG_MPU6050_TRIGGER
u8_t int_pin;
u8_t int_flags;
const char *int_label;
#endif /* CONFIG_MPU6050_TRIGGER */
};
#ifdef CONFIG_MPU6050_TRIGGER
int mpu6050_trigger_set(struct device *dev,
const struct sensor_trigger *trig,

View file

@ -19,12 +19,13 @@ int mpu6050_trigger_set(struct device *dev,
sensor_trigger_handler_t handler)
{
struct mpu6050_data *drv_data = dev->driver_data;
const struct mpu6050_config *cfg = dev->config->config_info;
if (trig->type != SENSOR_TRIG_DATA_READY) {
return -ENOTSUP;
}
gpio_pin_disable_callback(drv_data->gpio, CONFIG_MPU6050_GPIO_PIN_NUM);
gpio_pin_disable_callback(drv_data->gpio, cfg->int_pin);
drv_data->data_ready_handler = handler;
if (handler == NULL) {
@ -33,7 +34,7 @@ int mpu6050_trigger_set(struct device *dev,
drv_data->data_ready_trigger = *trig;
gpio_pin_enable_callback(drv_data->gpio, CONFIG_MPU6050_GPIO_PIN_NUM);
gpio_pin_enable_callback(drv_data->gpio, cfg->int_pin);
return 0;
}
@ -43,10 +44,11 @@ static void mpu6050_gpio_callback(struct device *dev,
{
struct mpu6050_data *drv_data =
CONTAINER_OF(cb, struct mpu6050_data, gpio_cb);
const struct mpu6050_config *cfg = drv_data->dev->config->config_info;
ARG_UNUSED(pins);
gpio_pin_disable_callback(dev, CONFIG_MPU6050_GPIO_PIN_NUM);
gpio_pin_disable_callback(dev, cfg->int_pin);
#if defined(CONFIG_MPU6050_TRIGGER_OWN_THREAD)
k_sem_give(&drv_data->gpio_sem);
@ -59,13 +61,14 @@ static void mpu6050_thread_cb(void *arg)
{
struct device *dev = arg;
struct mpu6050_data *drv_data = dev->driver_data;
const struct mpu6050_config *cfg = dev->config->config_info;
if (drv_data->data_ready_handler != NULL) {
drv_data->data_ready_handler(dev,
&drv_data->data_ready_trigger);
}
gpio_pin_enable_callback(drv_data->gpio, CONFIG_MPU6050_GPIO_PIN_NUM);
gpio_pin_enable_callback(drv_data->gpio, cfg->int_pin);
}
#ifdef CONFIG_MPU6050_TRIGGER_OWN_THREAD
@ -96,22 +99,25 @@ static void mpu6050_work_cb(struct k_work *work)
int mpu6050_init_interrupt(struct device *dev)
{
struct mpu6050_data *drv_data = dev->driver_data;
const struct mpu6050_config *cfg = dev->config->config_info;
/* setup data ready gpio interrupt */
drv_data->gpio = device_get_binding(CONFIG_MPU6050_GPIO_DEV_NAME);
drv_data->gpio = device_get_binding(cfg->int_label);
if (drv_data->gpio == NULL) {
LOG_ERR("Failed to get pointer to %s device",
CONFIG_MPU6050_GPIO_DEV_NAME);
cfg->int_label);
return -EINVAL;
}
gpio_pin_configure(drv_data->gpio, CONFIG_MPU6050_GPIO_PIN_NUM,
drv_data->dev = dev;
gpio_pin_configure(drv_data->gpio, cfg->int_pin,
GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE |
GPIO_INT_ACTIVE_HIGH | GPIO_INT_DEBOUNCE);
gpio_init_callback(&drv_data->gpio_cb,
mpu6050_gpio_callback,
BIT(CONFIG_MPU6050_GPIO_PIN_NUM));
BIT(cfg->int_pin));
if (gpio_add_callback(drv_data->gpio, &drv_data->gpio_cb) < 0) {
LOG_ERR("Failed to set gpio callback");
@ -119,7 +125,7 @@ int mpu6050_init_interrupt(struct device *dev)
}
/* enable data ready interrupt */
if (i2c_reg_write_byte(drv_data->i2c, CONFIG_MPU6050_I2C_ADDR,
if (i2c_reg_write_byte(drv_data->i2c, cfg->i2c_addr,
MPU6050_REG_INT_EN, MPU6050_DRDY_EN) < 0) {
LOG_ERR("Failed to enable data ready interrupt.");
return -EIO;
@ -135,10 +141,9 @@ int mpu6050_init_interrupt(struct device *dev)
0, K_NO_WAIT);
#elif defined(CONFIG_MPU6050_TRIGGER_GLOBAL_THREAD)
drv_data->work.handler = mpu6050_work_cb;
drv_data->dev = dev;
#endif
gpio_pin_enable_callback(drv_data->gpio, CONFIG_MPU6050_GPIO_PIN_NUM);
gpio_pin_enable_callback(drv_data->gpio, cfg->int_pin);
return 0;
}

View file

@ -0,0 +1,19 @@
# Copyright (c) 2019 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
description: MPU-6000 motion tracking device
# MPU-6000 is SPI or I2C. MPU-6050 is I2C-only. Driver does not
# support SPI so stick with I2C variant.
compatible: "invensense,mpu6050"
include: i2c-device.yaml
properties:
int-gpios:
type: phandle-array
required: false
description: |
The INT signal default configuration is active-high. The
property value should ensure the flags properly describe the
signal that is presented to the driver.

View file

@ -376,6 +376,15 @@
#define DT_INST_0_ISIL_ISL29035_INT_GPIOS_PIN 0
#endif
#ifndef DT_INST_0_INVENSENSE_MPU6050_LABEL
#define DT_INST_0_INVENSENSE_MPU6050_LABEL ""
#define DT_INST_0_INVENSENSE_MPU6050_BASE_ADDRESS 0
#define DT_INST_0_INVENSENSE_MPU6050_BUS_NAME ""
#define DT_INST_0_INVENSENSE_MPU6050_INT_GPIOS_CONTROLLER ""
#define DT_INST_0_INVENSENSE_MPU6050_INT_GPIOS_FLAGS 0
#define DT_INST_0_INVENSENSE_MPU6050_INT_GPIOS_PIN 0
#endif
#ifndef DT_INST_0_HOPERF_HP206C_LABEL
#define DT_INST_0_HOPERF_HP206C_LABEL ""
#define DT_INST_0_HOPERF_HP206C_BASE_ADDRESS 0