From 14e8015f8569d9634479a4a461e7c138d60d99ca Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 30 Jun 2016 03:48:49 +0200 Subject: iio: pressure: bmp280: split driver in logical parts This splits the BMP280 driver in three logical parts: the core driver bmp280-core that only operated on a struct device * and a struct regmap *, the regmap driver bmp280-regmap that can be shared between I2C and other transports and the I2C module driver bmp280-i2c. Cleverly bake all functionality into a single object bmp280.o so that we still get the same module binary built for the device in the end, without any fuzz exporting symbols to the left and right. Signed-off-by: Linus Walleij Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/iio/pressure/Makefile') diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile index 17d6e7afa1ff..2d98a7ff77a8 100644 --- a/drivers/iio/pressure/Makefile +++ b/drivers/iio/pressure/Makefile @@ -4,6 +4,7 @@ # When adding new entries keep the list in alphabetical order obj-$(CONFIG_BMP280) += bmp280.o +bmp280-objs := bmp280-core.o bmp280-regmap.o bmp280-i2c.o obj-$(CONFIG_HID_SENSOR_PRESS) += hid-sensor-press.o obj-$(CONFIG_HP03) += hp03.o obj-$(CONFIG_MPL115) += mpl115.o -- cgit v1.2.3 From 17118843a563c681aaafb29621befba02f28c592 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 30 Jun 2016 03:48:50 +0200 Subject: iio: pressure: bmp280: split off an I2C Kconfig entry This creates a separate BMP280_I2C Kconfig entry that gets selected by BMP280 for I2C transport. As we currently only support I2C transport there is not much practical change other than getting a separate object file (or module) for the I2C driver part. The old Kconfig symbol BMP280 will still select the stuff we need so that oldconfig and old defconfigs works fine. Tested-by: Akinobu Mita Signed-off-by: Linus Walleij Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/Kconfig | 17 ++++++++++++----- drivers/iio/pressure/Makefile | 3 ++- drivers/iio/pressure/bmp280-core.c | 7 +++++++ drivers/iio/pressure/bmp280-regmap.c | 3 +++ 4 files changed, 24 insertions(+), 6 deletions(-) (limited to 'drivers/iio/pressure/Makefile') diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig index 8d654f671b6b..3d0d311acb1d 100644 --- a/drivers/iio/pressure/Kconfig +++ b/drivers/iio/pressure/Kconfig @@ -6,17 +6,24 @@ menu "Pressure sensors" config BMP280 - tristate "Bosch Sensortec BMP180 and BMP280 pressure sensor driver" + tristate "Bosch Sensortec BMP180/BMP280 pressure sensor I2C driver" depends on I2C depends on !(BMP085_I2C=y || BMP085_I2C=m) - select REGMAP_I2C + select REGMAP + select BMP280_I2C if (I2C) help Say yes here to build support for Bosch Sensortec BMP180 and BMP280 pressure and temperature sensors. Also supports the BE280 with - an additional humidty sensor channel. + an additional humidity sensor channel. - To compile this driver as a module, choose M here: the module - will be called bmp280. + To compile this driver as a module, choose M here: the modules + will be called bmp280-i2c and bmp280. + +config BMP280_I2C + tristate + depends on BMP280 + depends on I2C + select REGMAP_I2C config HID_SENSOR_PRESS depends on HID_SENSOR_HUB diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile index 2d98a7ff77a8..736f4305fe46 100644 --- a/drivers/iio/pressure/Makefile +++ b/drivers/iio/pressure/Makefile @@ -4,7 +4,8 @@ # When adding new entries keep the list in alphabetical order obj-$(CONFIG_BMP280) += bmp280.o -bmp280-objs := bmp280-core.o bmp280-regmap.o bmp280-i2c.o +bmp280-objs := bmp280-core.o bmp280-regmap.o +obj-$(CONFIG_BMP280_I2C) += bmp280-i2c.o obj-$(CONFIG_HID_SENSOR_PRESS) += hid-sensor-press.o obj-$(CONFIG_HP03) += hp03.o obj-$(CONFIG_MPL115) += mpl115.o diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c index 83b96fe71f3b..f1b5f8c0ac8c 100644 --- a/drivers/iio/pressure/bmp280-core.c +++ b/drivers/iio/pressure/bmp280-core.c @@ -16,6 +16,7 @@ #define pr_fmt(fmt) "bmp280: " fmt #include +#include #include #include #include @@ -955,6 +956,7 @@ out_disable_vddd: regulator_disable(data->vddd); return ret; } +EXPORT_SYMBOL(bmp280_common_probe); int bmp280_common_remove(struct device *dev) { @@ -966,3 +968,8 @@ int bmp280_common_remove(struct device *dev) regulator_disable(data->vddd); return 0; } +EXPORT_SYMBOL(bmp280_common_remove); + +MODULE_AUTHOR("Vlad Dogaru "); +MODULE_DESCRIPTION("Driver for Bosch Sensortec BMP180/BMP280 pressure and temperature sensor"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/pressure/bmp280-regmap.c b/drivers/iio/pressure/bmp280-regmap.c index 3341189d0975..6807113ec09f 100644 --- a/drivers/iio/pressure/bmp280-regmap.c +++ b/drivers/iio/pressure/bmp280-regmap.c @@ -1,4 +1,5 @@ #include +#include #include #include "bmp280.h" @@ -37,6 +38,7 @@ const struct regmap_config bmp180_regmap_config = { .writeable_reg = bmp180_is_writeable_reg, .volatile_reg = bmp180_is_volatile_reg, }; +EXPORT_SYMBOL(bmp180_regmap_config); static bool bmp280_is_writeable_reg(struct device *dev, unsigned int reg) { @@ -79,3 +81,4 @@ const struct regmap_config bmp280_regmap_config = { .writeable_reg = bmp280_is_writeable_reg, .volatile_reg = bmp280_is_volatile_reg, }; +EXPORT_SYMBOL(bmp280_regmap_config); -- cgit v1.2.3 From b26b4e91700ff45d033eeaac91597d6d479378a4 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 30 Jun 2016 03:48:51 +0200 Subject: iio: pressure: bmp280: add SPI interface driver This patch mimics the SPI functionality found in the misc driver in drivers/misc/bh085-spi.c to make it possible to reuse the existing BMP280/BMP180/BMP085 driver with all clients of the other driver. The adoption is straight-forward since like the other driver, it is a simple matter of using regmap. This driver is also so obviously inspired/copied from the old misc driver in drivers/misc/bmp085.c that I just took the liberty to add in the authors of the other drivers + self in the core driver file. The MISC driver also supports a variant named "BMP181" so include that here to be complete in comparison to the old driver. The bus mapping code for SPI was written by Akinobu Mita. Signed-off-by: Akinobu Mita Tested-by: Akinobu Mita Signed-off-by: Linus Walleij Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/Kconfig | 15 ++++- drivers/iio/pressure/Makefile | 1 + drivers/iio/pressure/bmp280-core.c | 4 ++ drivers/iio/pressure/bmp280-spi.c | 123 +++++++++++++++++++++++++++++++++++++ 4 files changed, 140 insertions(+), 3 deletions(-) create mode 100644 drivers/iio/pressure/bmp280-spi.c (limited to 'drivers/iio/pressure/Makefile') diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig index 3d0d311acb1d..d130cdc78f43 100644 --- a/drivers/iio/pressure/Kconfig +++ b/drivers/iio/pressure/Kconfig @@ -7,17 +7,20 @@ menu "Pressure sensors" config BMP280 tristate "Bosch Sensortec BMP180/BMP280 pressure sensor I2C driver" - depends on I2C + depends on (I2C || SPI_MASTER) depends on !(BMP085_I2C=y || BMP085_I2C=m) + depends on !(BMP085_SPI=y || BMP085_SPI=m) select REGMAP select BMP280_I2C if (I2C) + select BMP280_SPI if (SPI_MASTER) help Say yes here to build support for Bosch Sensortec BMP180 and BMP280 pressure and temperature sensors. Also supports the BE280 with an additional humidity sensor channel. - To compile this driver as a module, choose M here: the modules - will be called bmp280-i2c and bmp280. + To compile this driver as a module, choose M here: the core module + will be called bmp280 and you will also get bmp280-i2c for I2C + and/or bmp280-spi for SPI support. config BMP280_I2C tristate @@ -25,6 +28,12 @@ config BMP280_I2C depends on I2C select REGMAP_I2C +config BMP280_SPI + tristate + depends on BMP280 + depends on SPI_MASTER + select REGMAP + config HID_SENSOR_PRESS depends on HID_SENSOR_HUB select IIO_BUFFER diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile index 736f4305fe46..7f395bed5e88 100644 --- a/drivers/iio/pressure/Makefile +++ b/drivers/iio/pressure/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_BMP280) += bmp280.o bmp280-objs := bmp280-core.o bmp280-regmap.o obj-$(CONFIG_BMP280_I2C) += bmp280-i2c.o +obj-$(CONFIG_BMP280_SPI) += bmp280-spi.o obj-$(CONFIG_HID_SENSOR_PRESS) += hid-sensor-press.o obj-$(CONFIG_HP03) += hp03.o obj-$(CONFIG_MPL115) += mpl115.o diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c index f1b5f8c0ac8c..43bd0b07619c 100644 --- a/drivers/iio/pressure/bmp280-core.c +++ b/drivers/iio/pressure/bmp280-core.c @@ -1,5 +1,9 @@ /* + * Copyright (c) 2010 Christoph Mair + * Copyright (c) 2012 Bosch Sensortec GmbH + * Copyright (c) 2012 Unixphere AB * Copyright (c) 2014 Intel Corporation + * Copyright (c) 2016 Linus Walleij * * Driver for Bosch Sensortec BMP180 and BMP280 digital pressure sensor. * diff --git a/drivers/iio/pressure/bmp280-spi.c b/drivers/iio/pressure/bmp280-spi.c new file mode 100644 index 000000000000..216e64b682bf --- /dev/null +++ b/drivers/iio/pressure/bmp280-spi.c @@ -0,0 +1,123 @@ +/* + * SPI interface for the BMP280 driver + * + * Inspired by the older BMP085 driver drivers/misc/bmp085-spi.c + */ +#include +#include +#include +#include + +#include "bmp280.h" + +static int bmp280_regmap_spi_write(void *context, const void *data, + size_t count) +{ + struct device *dev = context; + struct spi_device *spi = to_spi_device(dev); + u8 buf[2]; + + memcpy(buf, data, 2); + /* + * The SPI register address (= full register address without bit 7) and + * the write command (bit7 = RW = '0') + */ + buf[0] &= ~0x80; + + return spi_write_then_read(spi, buf, 2, NULL, 0); +} + +static int bmp280_regmap_spi_read(void *context, const void *reg, + size_t reg_size, void *val, size_t val_size) +{ + struct device *dev = context; + struct spi_device *spi = to_spi_device(dev); + + return spi_write_then_read(spi, reg, reg_size, val, val_size); +} + +static struct regmap_bus bmp280_regmap_bus = { + .write = bmp280_regmap_spi_write, + .read = bmp280_regmap_spi_read, + .reg_format_endian_default = REGMAP_ENDIAN_BIG, + .val_format_endian_default = REGMAP_ENDIAN_BIG, +}; + +static int bmp280_spi_probe(struct spi_device *spi) +{ + const struct spi_device_id *id = spi_get_device_id(spi); + struct regmap *regmap; + const struct regmap_config *regmap_config; + int ret; + + spi->bits_per_word = 8; + ret = spi_setup(spi); + if (ret < 0) { + dev_err(&spi->dev, "spi_setup failed!\n"); + return ret; + } + + switch (id->driver_data) { + case BMP180_CHIP_ID: + regmap_config = &bmp180_regmap_config; + break; + case BMP280_CHIP_ID: + case BME280_CHIP_ID: + regmap_config = &bmp280_regmap_config; + break; + default: + return -EINVAL; + } + + regmap = devm_regmap_init(&spi->dev, + &bmp280_regmap_bus, + &spi->dev, + regmap_config); + if (IS_ERR(regmap)) { + dev_err(&spi->dev, "failed to allocate register map\n"); + return PTR_ERR(regmap); + } + + return bmp280_common_probe(&spi->dev, + regmap, + id->driver_data, + id->name); +} + +static int bmp280_spi_remove(struct spi_device *spi) +{ + return bmp280_common_remove(&spi->dev); +} + +static const struct of_device_id bmp280_of_spi_match[] = { + { .compatible = "bosch,bmp085", }, + { .compatible = "bosch,bmp180", }, + { .compatible = "bosch,bmp181", }, + { .compatible = "bosch,bmp280", }, + { .compatible = "bosch,bme280", }, + { }, +}; +MODULE_DEVICE_TABLE(of, bmp280_of_spi_match); + +static const struct spi_device_id bmp280_spi_id[] = { + { "bmp180", BMP180_CHIP_ID }, + { "bmp181", BMP180_CHIP_ID }, + { "bmp280", BMP280_CHIP_ID }, + { "bme280", BME280_CHIP_ID }, + { } +}; +MODULE_DEVICE_TABLE(spi, bmp280_spi_id); + +static struct spi_driver bmp280_spi_driver = { + .driver = { + .name = "bmp280", + .of_match_table = bmp280_of_spi_match, + }, + .id_table = bmp280_spi_id, + .probe = bmp280_spi_probe, + .remove = bmp280_spi_remove, +}; +module_spi_driver(bmp280_spi_driver); + +MODULE_DESCRIPTION("BMP280 SPI bus driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3