|
11 | 11 | * SPDX-License-Identifier: Apache-2.0 |
12 | 12 | */ |
13 | 13 |
|
14 | | -#define DT_DRV_COMPAT bosch_bme680 |
15 | | - |
16 | | -#include "bme680.h" |
17 | 14 | #include <drivers/gpio.h> |
18 | | -#include <drivers/i2c.h> |
19 | 15 | #include <init.h> |
20 | 16 | #include <kernel.h> |
21 | 17 | #include <sys/byteorder.h> |
22 | 18 | #include <sys/__assert.h> |
23 | 19 | #include <drivers/sensor.h> |
24 | | - |
25 | 20 | #include <logging/log.h> |
| 21 | + |
| 22 | +#include "bme680.h" |
| 23 | + |
26 | 24 | LOG_MODULE_REGISTER(bme680, CONFIG_SENSOR_LOG_LEVEL); |
27 | 25 |
|
28 | | -static int bme680_reg_read(const struct device *dev, uint8_t start, |
29 | | - uint8_t *buf, int size) |
| 26 | + |
| 27 | +#if BME680_BUS_SPI |
| 28 | +static inline bool bme680_is_on_spi(const struct device *dev) |
30 | 29 | { |
31 | 30 | const struct bme680_config *config = dev->config; |
32 | 31 |
|
33 | | - return i2c_burst_read_dt(&config->bus, start, buf, size); |
| 32 | + return config->bus_io == &bme680_bus_io_spi; |
34 | 33 | } |
| 34 | +#endif |
35 | 35 |
|
36 | | -static int bme680_reg_write(const struct device *dev, uint8_t reg, uint8_t val) |
| 36 | +static inline int bme680_bus_check(const struct device *dev) |
37 | 37 | { |
38 | 38 | const struct bme680_config *config = dev->config; |
39 | 39 |
|
40 | | - return i2c_reg_write_byte_dt(&config->bus, reg, val); |
| 40 | + return config->bus_io->check(&config->bus); |
| 41 | +} |
| 42 | + |
| 43 | +static inline int bme680_reg_read(const struct device *dev, |
| 44 | + uint8_t start, uint8_t *buf, int size) |
| 45 | +{ |
| 46 | + const struct bme680_config *config = dev->config; |
| 47 | + |
| 48 | + return config->bus_io->read(dev, start, buf, size); |
| 49 | +} |
| 50 | + |
| 51 | +static inline int bme680_reg_write(const struct device *dev, uint8_t reg, |
| 52 | + uint8_t val) |
| 53 | +{ |
| 54 | + const struct bme680_config *config = dev->config; |
| 55 | + |
| 56 | + return config->bus_io->write(dev, reg, val); |
41 | 57 | } |
42 | 58 |
|
43 | 59 | static void bme680_calc_temp(struct bme680_data *data, uint32_t adc_temp) |
@@ -346,13 +362,22 @@ static int bme680_read_compensation(const struct device *dev) |
346 | 362 | static int bme680_init(const struct device *dev) |
347 | 363 | { |
348 | 364 | struct bme680_data *data = dev->data; |
349 | | - const struct bme680_config *config = dev->config; |
350 | 365 | int err; |
351 | 366 |
|
352 | | - if (!device_is_ready(config->bus.bus)) { |
353 | | - LOG_ERR("I2C master %s not ready", config->bus.bus->name); |
354 | | - return -EINVAL; |
| 367 | + err = bme680_bus_check(dev); |
| 368 | + if (err < 0) { |
| 369 | + LOG_ERR("Bus not ready for '%s'", dev->name); |
| 370 | + return err; |
| 371 | + } |
| 372 | + |
| 373 | +#if BME680_BUS_SPI |
| 374 | + if (bme680_is_on_spi(dev)) { |
| 375 | + err = bme680_reg_read(dev, BME680_REG_MEM_PAGE, &data->mem_page, 1); |
| 376 | + if (err < 0) { |
| 377 | + return err; |
| 378 | + } |
355 | 379 | } |
| 380 | +#endif |
356 | 381 |
|
357 | 382 | err = bme680_reg_read(dev, BME680_REG_CHIP_ID, &data->chip_id, 1); |
358 | 383 | if (err < 0) { |
@@ -410,12 +435,39 @@ static const struct sensor_driver_api bme680_api_funcs = { |
410 | 435 | .channel_get = bme680_channel_get, |
411 | 436 | }; |
412 | 437 |
|
413 | | -static struct bme680_data bme680_data; |
| 438 | +/* Initializes a struct bme680_config for an instance on a SPI bus. */ |
| 439 | +#define BME680_CONFIG_SPI(inst) \ |
| 440 | + { \ |
| 441 | + .bus.spi = SPI_DT_SPEC_INST_GET( \ |
| 442 | + inst, BME680_SPI_OPERATION, 0), \ |
| 443 | + .bus_io = &bme680_bus_io_spi, \ |
| 444 | + } |
414 | 445 |
|
415 | | -static const struct bme680_config bme680_config = { |
416 | | - .bus = I2C_DT_SPEC_INST_GET(0) |
417 | | -}; |
| 446 | +/* Initializes a struct bme680_config for an instance on an I2C bus. */ |
| 447 | +#define BME680_CONFIG_I2C(inst) \ |
| 448 | + { \ |
| 449 | + .bus.i2c = I2C_DT_SPEC_INST_GET(inst), \ |
| 450 | + .bus_io = &bme680_bus_io_i2c, \ |
| 451 | + } |
418 | 452 |
|
419 | | -DEVICE_DT_INST_DEFINE(0, bme680_init, NULL, &bme680_data, |
420 | | - &bme680_config, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, |
421 | | - &bme680_api_funcs); |
| 453 | +/* |
| 454 | + * Main instantiation macro, which selects the correct bus-specific |
| 455 | + * instantiation macros for the instance. |
| 456 | + */ |
| 457 | +#define BME680_DEFINE(inst) \ |
| 458 | + static struct bme680_data bme680_data_##inst; \ |
| 459 | + static const struct bme680_config bme680_config_##inst = \ |
| 460 | + COND_CODE_1(DT_INST_ON_BUS(inst, spi), \ |
| 461 | + (BME680_CONFIG_SPI(inst)), \ |
| 462 | + (BME680_CONFIG_I2C(inst))); \ |
| 463 | + DEVICE_DT_INST_DEFINE(inst, \ |
| 464 | + bme680_init, \ |
| 465 | + NULL, \ |
| 466 | + &bme680_data_##inst, \ |
| 467 | + &bme680_config_##inst, \ |
| 468 | + POST_KERNEL, \ |
| 469 | + CONFIG_SENSOR_INIT_PRIORITY, \ |
| 470 | + &bme680_api_funcs); |
| 471 | + |
| 472 | +/* Create the struct device for every status "okay" node in the devicetree. */ |
| 473 | +DT_INST_FOREACH_STATUS_OKAY(BME680_DEFINE) |
0 commit comments