From patchwork Thu Jun 21 06:34:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Himanshu Jha X-Patchwork-Id: 10479193 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5AF1060230 for ; Thu, 21 Jun 2018 06:35:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 37C8628D08 for ; Thu, 21 Jun 2018 06:35:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2AFE828D28; Thu, 21 Jun 2018 06:35:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_WEB,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5E56F28D08 for ; Thu, 21 Jun 2018 06:35:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751159AbeFUGfC (ORCPT ); Thu, 21 Jun 2018 02:35:02 -0400 Received: from mail-pg0-f67.google.com ([74.125.83.67]:40533 "EHLO mail-pg0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754292AbeFUGfA (ORCPT ); Thu, 21 Jun 2018 02:35:00 -0400 Received: by mail-pg0-f67.google.com with SMTP id w8-v6so939778pgp.7 for ; Wed, 20 Jun 2018 23:35:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Iu0/hy+2q/zxwjx0EtVGtQyrOzouzjCOnaXGps06FV4=; b=cDoFL2BL03wQgB6vP6+vHRZYGFFYsXqCuCzxzzuQtn7gT+gwg51PeWpNGFNB/rNTEN J3CXk/G+uB2Vi4DlG/5swjbcFbAd054jtUe3QJBdhU4xgg1mtBD1Cp3dIRP/L4RHdkSK N2rM/+zLoaFQxfrk86Nhe8cE+0n+cup2KlNl+aFwJqnF3HYmaFUE29QDIIPg2tEBANkF BWQDZVb3SsSgSzoNOEsTVVOvI6j2blOQYHn16ddhS6hYuw7UHxMCxacPI8FUQ9vENs1f m4+FFBT668/KoHieyEYvCGDmSud3VH1Nw7VPUEVwRXAyWBg3BHOi8Sd1kaHsD6uW607U xrPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Iu0/hy+2q/zxwjx0EtVGtQyrOzouzjCOnaXGps06FV4=; b=YH8fpC1Q4sTqwp/tWhNnvYRik39s/wXOEaeF5AS1ZPVv9nqSzTXOh/NfTDkS/u4f49 yJlUA5ffGphUlS6fA6RY9yZw/mG7p2Km8MWRZnqLqfgvMDAcdRrofhxkuhPjNrKwtYPf ZReHN70asSUy7jKdWlVswW9pCafC/QTN4TCGqa7OUcWu2iHW+q3KL2wN2h4lMLO2Uxrj 61L7uwUbkaAjaHV2gNcY/KxFWoSjZWPVCR4lttUQXAK+ynciOMmL2A/uD4AD4ExoMDd3 272sEQ0beX5xQhTXMRFDbP3asGnz02KM6aiFpbuv59iDWp5PvEYp7xWLUfXKT0vYCH7I Jeiw== X-Gm-Message-State: APt69E3RUKlsjKYVUZhwBLFIed9Tu1VWalUggEGL+GLZ4wr88BrYApDD uaV36XFo4Zzp5UY49cLI6UQ= X-Google-Smtp-Source: ADUXVKJidqyybUXxQ5zrh6O5cuCm4HSmwQupL09zBA18j5VyZr6ngBPhNSax4W6MnDDI7tSK7A+oVA== X-Received: by 2002:a63:ad08:: with SMTP id g8-v6mr20847962pgf.74.1529562899936; Wed, 20 Jun 2018 23:34:59 -0700 (PDT) Received: from localhost.localdomain ([103.46.193.14]) by smtp.gmail.com with ESMTPSA id n83-v6sm9406527pfi.147.2018.06.20.23.34.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 20 Jun 2018 23:34:59 -0700 (PDT) From: Himanshu Jha To: jic23@kernel.org, linux-iio@vger.kernel.org Cc: lars@metafoo.de, pmeerw@pmeerw.net, daniel.baluta@gmail.com, Himanshu Jha Subject: [RFC 1/3] iio: imu: bme680: Add initial support for Bosch BME680 Date: Thu, 21 Jun 2018 12:04:35 +0530 Message-Id: <1529562877-9357-2-git-send-email-himanshujha199640@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1529562877-9357-1-git-send-email-himanshujha199640@gmail.com> References: <1529562877-9357-1-git-send-email-himanshujha199640@gmail.com> Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Implement a minimal probe function to register the device to the kernel. The probe does a simple power on reset and then checks for chip id. Datasheet: https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME680-DS001-00.pdf Cc: Daniel Baluta Signed-off-by: Himanshu Jha --- drivers/iio/imu/Kconfig | 1 + drivers/iio/imu/Makefile | 1 + drivers/iio/imu/bme680/Kconfig | 32 +++++++++++ drivers/iio/imu/bme680/Makefile | 6 +++ drivers/iio/imu/bme680/bme680.h | 11 ++++ drivers/iio/imu/bme680/bme680_core.c | 101 +++++++++++++++++++++++++++++++++++ drivers/iio/imu/bme680/bme680_i2c.c | 56 +++++++++++++++++++ drivers/iio/imu/bme680/bme680_spi.c | 49 +++++++++++++++++ 8 files changed, 257 insertions(+) create mode 100644 drivers/iio/imu/bme680/Kconfig create mode 100644 drivers/iio/imu/bme680/Makefile create mode 100644 drivers/iio/imu/bme680/bme680.h create mode 100644 drivers/iio/imu/bme680/bme680_core.c create mode 100644 drivers/iio/imu/bme680/bme680_i2c.c create mode 100644 drivers/iio/imu/bme680/bme680_spi.c diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig index 156630a..cb7d2c0 100644 --- a/drivers/iio/imu/Kconfig +++ b/drivers/iio/imu/Kconfig @@ -26,6 +26,7 @@ config ADIS16480 ADIS16485, ADIS16488 inertial sensors. source "drivers/iio/imu/bmi160/Kconfig" +source "drivers/iio/imu/bme680/Kconfig" config KMX61 tristate "Kionix KMX61 6-axis accelerometer and magnetometer" diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile index 68629c68..6c8c937 100644 --- a/drivers/iio/imu/Makefile +++ b/drivers/iio/imu/Makefile @@ -15,6 +15,7 @@ adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_buffer.o obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o obj-y += bmi160/ +obj-y += bme680/ obj-y += inv_mpu6050/ obj-$(CONFIG_KMX61) += kmx61.o diff --git a/drivers/iio/imu/bme680/Kconfig b/drivers/iio/imu/bme680/Kconfig new file mode 100644 index 0000000..71c392b --- /dev/null +++ b/drivers/iio/imu/bme680/Kconfig @@ -0,0 +1,32 @@ +# +# Bosch BME680 Driver +# + +config BME680 + tristate + select IIO_BUFFER + +config BME680_I2C + tristate "Bosch BME680 I2C Driver" + depends on I2C + select BME680 + select REGMAP_I2C + help + If you say yes here you get support for BME680 on I2C with + temperature, pressure, humidity & gas sensing. + + This driver can also be built as a module. If so, the module will be + called bme68_i2c. + +config BME680_SPI + tristate "Bosch BME680 SPI Driver" + depends on SPI + select BME680 + select REGMAP_SPI + help + If you say yes here you get support for BME680 on SPI with + temperature, pressure, humidity & gas sensing. + + This driver can also be built as a module. If so, the module will be + called bme68_spi. + diff --git a/drivers/iio/imu/bme680/Makefile b/drivers/iio/imu/bme680/Makefile new file mode 100644 index 0000000..562a708 --- /dev/null +++ b/drivers/iio/imu/bme680/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for Bosch BME680 +# +obj-$(CONFIG_BME680) += bme680_core.o +obj-$(CONFIG_BME680_I2C) += bme680_i2c.o +obj-$(CONFIG_BME680_SPI) += bme680_spi.o diff --git a/drivers/iio/imu/bme680/bme680.h b/drivers/iio/imu/bme680/bme680.h new file mode 100644 index 0000000..9ee0cf5 --- /dev/null +++ b/drivers/iio/imu/bme680/bme680.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef BME680_H_ +#define BME680_H_ + +extern const struct regmap_config bme680_regmap_config; + +int bme680_core_probe(struct device *dev, struct regmap *regmap, + const char *name, bool use_spi); +void bme680_core_remove(struct device *dev); + +#endif /* BME680_H_ */ diff --git a/drivers/iio/imu/bme680/bme680_core.c b/drivers/iio/imu/bme680/bme680_core.c new file mode 100644 index 0000000..a6d013d --- /dev/null +++ b/drivers/iio/imu/bme680/bme680_core.c @@ -0,0 +1,101 @@ +/* + * Bosch BME680 - Temperature, Pressure, Humidity & Gas Sensor + * + * IIO core driver - I2C & SPI bus support + */ +#include +#include +#include + +#define BME680_REG_CHIP_I2C_ID 0xD0 +#define BME680_REG_CHIP_SPI_ID 0x50 +#define BME680_CHIP_ID_VAL 0x61 +#define BME680_SOFT_RESET 0xE0 +#define BME680_CMD_SOFTRESET 0xB6 + +struct bme680_data { + struct regmap *regmap; +}; + +const struct regmap_config bme680_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +}; +EXPORT_SYMBOL(bme680_regmap_config); + +static const struct iio_info bme680_info = { +}; + +static int bme680_chip_init(struct bme680_data *data, bool use_spi) +{ + struct device *dev = regmap_get_device(data->regmap); + unsigned int val; + int ret; + + /* Power on Soft Reset */ + ret = regmap_write(data->regmap, BME680_SOFT_RESET, BME680_CMD_SOFTRESET); + if (ret < 0) + return ret; + + if (!use_spi) { + ret = regmap_read(data->regmap, BME680_REG_CHIP_I2C_ID, &val); + } else { + ret = regmap_read(data->regmap, BME680_REG_CHIP_SPI_ID, &val); + } + + if (ret < 0) { + dev_err(dev, "Error reading chip ID\n"); + return ret; + } + + if (val != BME680_CHIP_ID_VAL) { + dev_err(dev, "Wrong chip ID, got %x expected %x\n", + val, BME680_CHIP_ID_VAL); + return -ENODEV; + } + + return 0; +} + +int bme680_core_probe(struct device *dev, struct regmap *regmap, + const char *name, bool use_spi) +{ + struct iio_dev *indio_dev; + struct bme680_data *data; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + dev_set_drvdata(dev, indio_dev); + data->regmap = regmap; + + ret = bme680_chip_init(data, use_spi); + if (ret < 0) + return ret; + + indio_dev->dev.parent = dev; + indio_dev->name = name; + indio_dev->info = &bme680_info; + + ret = iio_device_register(indio_dev); + if (ret < 0) + return ret; + return 0; +} +EXPORT_SYMBOL_GPL(bme680_core_probe); + +void bme680_core_remove(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct bme680_data *data = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); +} +EXPORT_SYMBOL_GPL(bme680_core_remove); + +MODULE_AUTHOR("Himanshu Jha "); +MODULE_DESCRIPTION("Bosch BME680 Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/imu/bme680/bme680_i2c.c b/drivers/iio/imu/bme680/bme680_i2c.c new file mode 100644 index 0000000..1c8223e --- /dev/null +++ b/drivers/iio/imu/bme680/bme680_i2c.c @@ -0,0 +1,56 @@ +/* + * 7-Bit I2C slave address is: + * - 0x76 if SDO is pulled to GND + * - 0x77 if SDO is pulled to VDDIO + */ +#include +#include +#include + +#include "bme680.h" + +static int bme680_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct regmap *regmap; + const char *name = NULL; + + regmap = devm_regmap_init_i2c(client, &bme680_regmap_config); + if (IS_ERR(regmap)) { + dev_err(&client->dev, "Failed to register i2c regmap %d\n", + (int)PTR_ERR(regmap)); + return PTR_ERR(regmap); + } + + if (id) + name = id->name; + + return bme680_core_probe(&client->dev, regmap, name, false); +} + +static int bme680_i2c_remove(struct i2c_client *client) +{ + bme680_core_remove(&client->dev); + + return 0; +} + +static const struct i2c_device_id bme680_i2c_id[] = { + {"bme680", 0}, + {}, +}; +MODULE_DEVICE_TABLE(i2c, bme680_i2c_id); + +static struct i2c_driver bme680_i2c_driver = { + .driver = { + .name = "bme680_i2c", + }, + .probe = bme680_i2c_probe, + .remove = bme680_i2c_remove, + .id_table = bme680_i2c_id, +}; +module_i2c_driver(bme680_i2c_driver); + +MODULE_AUTHOR("Himanshu Jha "); +MODULE_DESCRIPTION("BME680 I2C driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/imu/bme680/bme680_spi.c b/drivers/iio/imu/bme680/bme680_spi.c new file mode 100644 index 0000000..c135924 --- /dev/null +++ b/drivers/iio/imu/bme680/bme680_spi.c @@ -0,0 +1,49 @@ +/* + * BME680 - SPI Driver + */ +#include +#include +#include + +#include "bme680.h" + +static int bme680_spi_probe(struct spi_device *spi) +{ + struct regmap *regmap; + const struct spi_device_id *id = spi_get_device_id(spi); + + regmap = devm_regmap_init_spi(spi, &bme680_regmap_config); + if (IS_ERR(regmap)) { + dev_err(&spi->dev, "Failed to register spi regmap %d\n", + (int)PTR_ERR(regmap)); + return PTR_ERR(regmap); + } + return bme680_core_probe(&spi->dev, regmap, id->name, true); +} + +static int bme680_spi_remove(struct spi_device *spi) +{ + bme680_core_remove(&spi->dev); + + return 0; +} + +static const struct spi_device_id bme680_spi_id[] = { + {"bme680", 0}, + {} +}; +MODULE_DEVICE_TABLE(spi, bme680_spi_id); + +static struct spi_driver bme680_spi_driver = { + .driver = { + .name = "bme680_spi", + }, + .probe = bme680_spi_probe, + .remove = bme680_spi_remove, + .id_table = bme680_spi_id, +}; +module_spi_driver(bme680_spi_driver); + +MODULE_AUTHOR("Himanshu Jha "); +MODULE_DESCRIPTION("Bosch BME680 SPI driver"); +MODULE_LICENSE("GPL v2");