From patchwork Sun Jan 29 01:33:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angel Iglesias X-Patchwork-Id: 13119973 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D6E21C61D97 for ; Sun, 29 Jan 2023 01:34:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230245AbjA2Bei (ORCPT ); Sat, 28 Jan 2023 20:34:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46052 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230452AbjA2Bed (ORCPT ); Sat, 28 Jan 2023 20:34:33 -0500 Received: from mail-wm1-x335.google.com (mail-wm1-x335.google.com [IPv6:2a00:1450:4864:20::335]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B029A1C33E; Sat, 28 Jan 2023 17:34:21 -0800 (PST) Received: by mail-wm1-x335.google.com with SMTP id q8so5852646wmo.5; Sat, 28 Jan 2023 17:34:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=C997OhrnhNoiM7iywusJdgGkUWnaX2vRvWZPHFED/VQ=; b=JdSMzdYt2ajzvF0+AUl0KDbviuu+Sv/YNk1l4+OstVtNuD/QzNFRT5OZTHN/4lGEsR mqZVgAZG8bfjw7UBezuYGhW4IRKwu3OO97ISqJbQBnav5svjrFNWN+tPPvKndUGY1PhN oBcRQ3JB5cDtRyi57VrLeiUvQU+knYGALeewW1mjjTepNoLuRh3dkXnodJJuy+wBuGiK Wq9TxoTXlg9SRd5j30bQNsdhY40jw4iyPlPc9p8Jmcgv0UaQKWcgv5xc4ouWBsUVLMtD 4K0grrvM75WRr6m91uX8Q1i5MNSoVQFzRzExTw6Vg1I13cr8Z9nKeNX3k7xXxLC7GDpa fk0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=C997OhrnhNoiM7iywusJdgGkUWnaX2vRvWZPHFED/VQ=; b=3zU6PTpQ4O96o2sNHmvLLZMO5zUDzyuw48yCB0GwHz3oS2k0o2iXD6s2LVJ6Wv5mQW tPHjvID35Ut3cKdZThqVLZVdJbiPWASbr7UHUgEfue06DDIwNLjSw5CtGcV944LZ4wOy 9L8rQ4T7I+v4PMyL4t7bnjqGV8OaeOSzzEfgcVzUT7C5362NUPci2W0hlqD9aiUqGZ46 vxNcL6nU40ZW+JcqzKTg0dNAvWd29jUvm82EehAmD9NOFBf67lwP6JU3pI7usO5N/aFX xNKc6BweTYKac6hPBlDX0yGYTlXLJmWXG4ALbuTb31pz3G7sLipQEntkE5Yo5rXz2SL0 Wn+Q== X-Gm-Message-State: AFqh2kpJn/4s+b4DUj5YQ8cJBZAy1pM+dOGHkT/sPtonopju8NUZ6iDv VJwei9On2g1YYwzHrANgrK7p7mD0TAk= X-Google-Smtp-Source: AMrXdXvD+aJC0ZcCaTAu1q9Kr4VS/4xsJ+B1CIrqBCBVXPK2dTTuBW/pCqovB4Ttfd2xMc4xSLiMtA== X-Received: by 2002:a1c:7504:0:b0:3d3:52bb:3984 with SMTP id o4-20020a1c7504000000b003d352bb3984mr41561526wmc.17.1674956060015; Sat, 28 Jan 2023 17:34:20 -0800 (PST) Received: from localhost.localdomain (143.red-83-35-57.dynamicip.rima-tde.net. [83.35.57.143]) by smtp.gmail.com with ESMTPSA id r7-20020a05600c434700b003dc3f195abesm5197132wme.39.2023.01.28.17.34.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 28 Jan 2023 17:34:19 -0800 (PST) From: Angel Iglesias To: linux-iio@vger.kernel.org Cc: Angel Iglesias , Andy Shevchenko , Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Andreas Klinger , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 1/7] iio: pressure: bmp280: Use chip_info pointers for each chip as driver data Date: Sun, 29 Jan 2023 02:33:03 +0100 Message-Id: <7392796d1bc63d58f7a19d209a86c8e0de84a763.1674954271.git.ang.iglesiasg@gmail.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Refactor driver I2C and SPI implementations using pointers for each variant's chip_info as the driver data. Adds the regmap configuration to the chip_info struct. Suggested-by: Andy Shevchenko Suggested-by: Jonathan Cameron Signed-off-by: Angel Iglesias diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c index c0aff78489b4..2c8773db4b73 100644 --- a/drivers/iio/pressure/bmp280-core.c +++ b/drivers/iio/pressure/bmp280-core.c @@ -49,65 +49,6 @@ */ enum { AC1, AC2, AC3, AC4, AC5, AC6, B1, B2, MB, MC, MD }; -struct bmp180_calib { - s16 AC1; - s16 AC2; - s16 AC3; - u16 AC4; - u16 AC5; - u16 AC6; - s16 B1; - s16 B2; - s16 MB; - s16 MC; - s16 MD; -}; - -/* See datasheet Section 4.2.2. */ -struct bmp280_calib { - u16 T1; - s16 T2; - s16 T3; - u16 P1; - s16 P2; - s16 P3; - s16 P4; - s16 P5; - s16 P6; - s16 P7; - s16 P8; - s16 P9; - u8 H1; - s16 H2; - u8 H3; - s16 H4; - s16 H5; - s8 H6; -}; - -/* See datasheet Section 3.11.1. */ -struct bmp380_calib { - u16 T1; - u16 T2; - s8 T3; - s16 P1; - s16 P2; - s8 P3; - s8 P4; - u16 P5; - u16 P6; - s8 P7; - s8 P8; - s16 P9; - s8 P10; - s8 P11; -}; - -static const char *const bmp280_supply_names[] = { - "vddd", "vdda" -}; - -#define BMP280_NUM_SUPPLIES ARRAY_SIZE(bmp280_supply_names) enum bmp380_odr { BMP380_ODR_200HZ, @@ -130,94 +71,6 @@ enum bmp380_odr { BMP380_ODR_0_0015HZ, }; -struct bmp280_data { - struct device *dev; - struct mutex lock; - struct regmap *regmap; - struct completion done; - bool use_eoc; - const struct bmp280_chip_info *chip_info; - union { - struct bmp180_calib bmp180; - struct bmp280_calib bmp280; - struct bmp380_calib bmp380; - } calib; - struct regulator_bulk_data supplies[BMP280_NUM_SUPPLIES]; - unsigned int start_up_time; /* in microseconds */ - - /* log of base 2 of oversampling rate */ - u8 oversampling_press; - u8 oversampling_temp; - u8 oversampling_humid; - u8 iir_filter_coeff; - - /* - * BMP380 devices introduce sampling frequency configuration. See - * datasheet sections 3.3.3. and 4.3.19 for more details. - * - * BMx280 devices allowed indirect configuration of sampling frequency - * changing the t_standby duration between measurements, as detailed on - * section 3.6.3 of the datasheet. - */ - int sampling_freq; - - /* - * Carryover value from temperature conversion, used in pressure - * calculation. - */ - s32 t_fine; - - /* - * DMA (thus cache coherency maintenance) may require the - * transfer buffers to live in their own cache lines. - */ - union { - /* Sensor data buffer */ - u8 buf[3]; - /* Calibration data buffers */ - __le16 bmp280_cal_buf[BMP280_CONTIGUOUS_CALIB_REGS / 2]; - __be16 bmp180_cal_buf[BMP180_REG_CALIB_COUNT / 2]; - u8 bmp380_cal_buf[BMP380_CALIB_REG_COUNT]; - /* Miscellaneous, endianess-aware data buffers */ - __le16 le16; - __be16 be16; - } __aligned(IIO_DMA_MINALIGN); -}; - -struct bmp280_chip_info { - unsigned int id_reg; - - const struct iio_chan_spec *channels; - int num_channels; - unsigned int start_up_time; - - const int *oversampling_temp_avail; - int num_oversampling_temp_avail; - int oversampling_temp_default; - - const int *oversampling_press_avail; - int num_oversampling_press_avail; - int oversampling_press_default; - - const int *oversampling_humid_avail; - int num_oversampling_humid_avail; - int oversampling_humid_default; - - const int *iir_filter_coeffs_avail; - int num_iir_filter_coeffs_avail; - int iir_filter_coeff_default; - - const int (*sampling_freq_avail)[2]; - int num_sampling_freq_avail; - int sampling_freq_default; - - int (*chip_config)(struct bmp280_data *); - int (*read_temp)(struct bmp280_data *, int *); - int (*read_press)(struct bmp280_data *, int *, int *); - int (*read_humid)(struct bmp280_data *, int *, int *); - int (*read_calib)(struct bmp280_data *); -}; - /* * These enums are used for indexing into the array of compensation * parameters for BMP280. @@ -905,8 +758,10 @@ static int bmp280_chip_config(struct bmp280_data *data) static const int bmp280_oversampling_avail[] = { 1, 2, 4, 8, 16 }; -static const struct bmp280_chip_info bmp280_chip_info = { +const struct bmp280_chip_info bmp280_chip_info = { .id_reg = BMP280_REG_ID, + .chip_id = BMP280_CHIP_ID, + .regmap_config = &bmp280_regmap_config, .start_up_time = 2000, .channels = bmp280_channels, .num_channels = 2, @@ -934,6 +789,7 @@ static const struct bmp280_chip_info bmp280_chip_info = { .read_press = bmp280_read_press, .read_calib = bmp280_read_calib, }; +EXPORT_SYMBOL_NS(bmp280_chip_info, IIO_BMP280); static int bme280_chip_config(struct bmp280_data *data) { @@ -953,8 +809,10 @@ static int bme280_chip_config(struct bmp280_data *data) return bmp280_chip_config(data); } -static const struct bmp280_chip_info bme280_chip_info = { +const struct bmp280_chip_info bme280_chip_info = { .id_reg = BMP280_REG_ID, + .chip_id = BME280_CHIP_ID, + .regmap_config = &bmp280_regmap_config, .start_up_time = 2000, .channels = bmp280_channels, .num_channels = 3, @@ -977,6 +835,7 @@ static const struct bmp280_chip_info bme280_chip_info = { .read_humid = bmp280_read_humid, .read_calib = bme280_read_calib, }; +EXPORT_SYMBOL_NS(bme280_chip_info, IIO_BMP280); /* * Helper function to send a command to BMP3XX sensors. @@ -1319,8 +1178,10 @@ static int bmp380_chip_config(struct bmp280_data *data) static const int bmp380_oversampling_avail[] = { 1, 2, 4, 8, 16, 32 }; static const int bmp380_iir_filter_coeffs_avail[] = { 1, 2, 4, 8, 16, 32, 64, 128}; -static const struct bmp280_chip_info bmp380_chip_info = { +const struct bmp280_chip_info bmp380_chip_info = { .id_reg = BMP380_REG_ID, + .chip_id = BMP380_CHIP_ID, + .regmap_config = &bmp380_regmap_config, .start_up_time = 2000, .channels = bmp380_channels, .num_channels = 2, @@ -1346,6 +1207,7 @@ static const struct bmp280_chip_info bmp380_chip_info = { .read_press = bmp380_read_press, .read_calib = bmp380_read_calib, }; +EXPORT_SYMBOL_NS(bmp380_chip_info, IIO_BMP280); static int bmp180_measure(struct bmp280_data *data, u8 ctrl_meas) { @@ -1579,8 +1441,10 @@ static int bmp180_chip_config(struct bmp280_data *data) static const int bmp180_oversampling_temp_avail[] = { 1 }; static const int bmp180_oversampling_press_avail[] = { 1, 2, 4, 8 }; -static const struct bmp280_chip_info bmp180_chip_info = { +const struct bmp280_chip_info bmp180_chip_info = { .id_reg = BMP280_REG_ID, + .chip_id = BMP180_CHIP_ID, + .regmap_config = &bmp180_regmap_config, .start_up_time = 2000, .channels = bmp280_channels, .num_channels = 2, @@ -1600,6 +1464,7 @@ static const struct bmp280_chip_info bmp180_chip_info = { .read_press = bmp180_read_press, .read_calib = bmp180_read_calib, }; +EXPORT_SYMBOL_NS(bmp180_chip_info, IIO_BMP280); static irqreturn_t bmp085_eoc_irq(int irq, void *d) { @@ -1661,11 +1526,10 @@ static void bmp280_regulators_disable(void *data) int bmp280_common_probe(struct device *dev, struct regmap *regmap, - unsigned int chip, + const struct bmp280_chip_info *chip_info, const char *name, int irq) { - const struct bmp280_chip_info *chip_info; struct iio_dev *indio_dev; struct bmp280_data *data; struct gpio_desc *gpiod; @@ -1684,22 +1548,6 @@ int bmp280_common_probe(struct device *dev, indio_dev->info = &bmp280_info; indio_dev->modes = INDIO_DIRECT_MODE; - switch (chip) { - case BMP180_CHIP_ID: - chip_info = &bmp180_chip_info; - break; - case BMP280_CHIP_ID: - chip_info = &bmp280_chip_info; - break; - case BME280_CHIP_ID: - chip_info = &bme280_chip_info; - break; - case BMP380_CHIP_ID: - chip_info = &bmp380_chip_info; - break; - default: - return -EINVAL; - } data->chip_info = chip_info; /* Apply initial values from chip info structure */ @@ -1751,9 +1599,9 @@ int bmp280_common_probe(struct device *dev, ret = regmap_read(regmap, data->chip_info->id_reg, &chip_id); if (ret < 0) return ret; - if (chip_id != chip) { + if (chip_id != data->chip_info->chip_id) { dev_err(dev, "bad chip id: expected %x got %x\n", - chip, chip_id); + data->chip_info->chip_id, chip_id); return -EINVAL; } diff --git a/drivers/iio/pressure/bmp280-i2c.c b/drivers/iio/pressure/bmp280-i2c.c index 14eab086d24a..5f908e2c9826 100644 --- a/drivers/iio/pressure/bmp280-i2c.c +++ b/drivers/iio/pressure/bmp280-i2c.c @@ -8,25 +8,14 @@ static int bmp280_i2c_probe(struct i2c_client *client) { struct regmap *regmap; - const struct regmap_config *regmap_config; + const struct bmp280_chip_info *chip_info; const struct i2c_device_id *id = i2c_client_get_device_id(client); - 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; - case BMP380_CHIP_ID: - regmap_config = &bmp380_regmap_config; - break; - default: - return -EINVAL; - } + chip_info = device_get_match_data(&client->dev); + if (!chip_info) + chip_info = (const struct bmp280_chip_info *) id->driver_data; - regmap = devm_regmap_init_i2c(client, regmap_config); + regmap = devm_regmap_init_i2c(client, chip_info->regmap_config); if (IS_ERR(regmap)) { dev_err(&client->dev, "failed to allocate register map\n"); return PTR_ERR(regmap); @@ -34,27 +23,27 @@ static int bmp280_i2c_probe(struct i2c_client *client) return bmp280_common_probe(&client->dev, regmap, - id->driver_data, + chip_info, id->name, client->irq); } static const struct of_device_id bmp280_of_i2c_match[] = { - { .compatible = "bosch,bmp085", .data = (void *)BMP180_CHIP_ID }, - { .compatible = "bosch,bmp180", .data = (void *)BMP180_CHIP_ID }, - { .compatible = "bosch,bmp280", .data = (void *)BMP280_CHIP_ID }, - { .compatible = "bosch,bme280", .data = (void *)BME280_CHIP_ID }, - { .compatible = "bosch,bmp380", .data = (void *)BMP380_CHIP_ID }, + { .compatible = "bosch,bmp085", .data = &bmp180_chip_info }, + { .compatible = "bosch,bmp180", .data = &bmp180_chip_info }, + { .compatible = "bosch,bmp280", .data = &bmp280_chip_info }, + { .compatible = "bosch,bme280", .data = &bme280_chip_info }, + { .compatible = "bosch,bmp380", .data = &bmp380_chip_info }, { }, }; MODULE_DEVICE_TABLE(of, bmp280_of_i2c_match); static const struct i2c_device_id bmp280_i2c_id[] = { - {"bmp085", BMP180_CHIP_ID }, - {"bmp180", BMP180_CHIP_ID }, - {"bmp280", BMP280_CHIP_ID }, - {"bme280", BME280_CHIP_ID }, - {"bmp380", BMP380_CHIP_ID }, + {"bmp085", (kernel_ulong_t)&bmp180_chip_info }, + {"bmp180", (kernel_ulong_t)&bmp180_chip_info }, + {"bmp280", (kernel_ulong_t)&bmp280_chip_info }, + {"bme280", (kernel_ulong_t)&bme280_chip_info }, + {"bmp380", (kernel_ulong_t)&bmp380_chip_info }, { }, }; MODULE_DEVICE_TABLE(i2c, bmp280_i2c_id); diff --git a/drivers/iio/pressure/bmp280-spi.c b/drivers/iio/pressure/bmp280-spi.c index 011c68e07ebf..d5a224b95185 100644 --- a/drivers/iio/pressure/bmp280-spi.c +++ b/drivers/iio/pressure/bmp280-spi.c @@ -47,8 +47,8 @@ static struct regmap_bus bmp280_regmap_bus = { static int bmp280_spi_probe(struct spi_device *spi) { const struct spi_device_id *id = spi_get_device_id(spi); + const struct bmp280_chip_info *chip_info; struct regmap *regmap; - const struct regmap_config *regmap_config; int ret; spi->bits_per_word = 8; @@ -58,25 +58,14 @@ static int bmp280_spi_probe(struct spi_device *spi) 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; - case BMP380_CHIP_ID: - regmap_config = &bmp380_regmap_config; - break; - default: - return -EINVAL; - } + chip_info = device_get_match_data(&spi->dev); + if (!chip_info) + chip_info = (const struct bmp280_chip_info *) id->driver_data; regmap = devm_regmap_init(&spi->dev, &bmp280_regmap_bus, &spi->dev, - regmap_config); + chip_info->regmap_config); if (IS_ERR(regmap)) { dev_err(&spi->dev, "failed to allocate register map\n"); return PTR_ERR(regmap); @@ -84,28 +73,28 @@ static int bmp280_spi_probe(struct spi_device *spi) return bmp280_common_probe(&spi->dev, regmap, - id->driver_data, + chip_info, id->name, spi->irq); } 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", }, - { .compatible = "bosch,bmp380", }, + { .compatible = "bosch,bmp085", .data = &bmp180_chip_info }, + { .compatible = "bosch,bmp180", .data = &bmp180_chip_info }, + { .compatible = "bosch,bmp181", .data = &bmp180_chip_info }, + { .compatible = "bosch,bmp280", .data = &bmp280_chip_info }, + { .compatible = "bosch,bme280", .data = &bmp280_chip_info }, + { .compatible = "bosch,bmp380", .data = &bmp380_chip_info }, { }, }; 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 }, - { "bmp380", BMP380_CHIP_ID }, + { "bmp180", (kernel_ulong_t)&bmp180_chip_info }, + { "bmp181", (kernel_ulong_t)&bmp180_chip_info }, + { "bmp280", (kernel_ulong_t)&bmp280_chip_info }, + { "bme280", (kernel_ulong_t)&bmp280_chip_info }, + { "bmp380", (kernel_ulong_t)&bmp380_chip_info }, { } }; MODULE_DEVICE_TABLE(spi, bmp280_spi_id); diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h index c791325c7416..387723fd0772 100644 --- a/drivers/iio/pressure/bmp280.h +++ b/drivers/iio/pressure/bmp280.h @@ -1,7 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0 */ #include #include +#include #include +#include + /* BMP380 specific registers */ #define BMP380_REG_CMD 0x7E @@ -191,6 +194,165 @@ #define BMP280_PRESS_SKIPPED 0x80000 #define BMP280_HUMIDITY_SKIPPED 0x8000 +/* Core exported structs */ + +static const char *const bmp280_supply_names[] = { + "vddd", "vdda" +}; + +#define BMP280_NUM_SUPPLIES ARRAY_SIZE(bmp280_supply_names) + +struct bmp180_calib { + s16 AC1; + s16 AC2; + s16 AC3; + u16 AC4; + u16 AC5; + u16 AC6; + s16 B1; + s16 B2; + s16 MB; + s16 MC; + s16 MD; +}; + +/* See datasheet Section 4.2.2. */ +struct bmp280_calib { + u16 T1; + s16 T2; + s16 T3; + u16 P1; + s16 P2; + s16 P3; + s16 P4; + s16 P5; + s16 P6; + s16 P7; + s16 P8; + s16 P9; + u8 H1; + s16 H2; + u8 H3; + s16 H4; + s16 H5; + s8 H6; +}; + +/* See datasheet Section 3.11.1. */ +struct bmp380_calib { + u16 T1; + u16 T2; + s8 T3; + s16 P1; + s16 P2; + s8 P3; + s8 P4; + u16 P5; + u16 P6; + s8 P7; + s8 P8; + s16 P9; + s8 P10; + s8 P11; +}; + +struct bmp280_data { + struct device *dev; + struct mutex lock; + struct regmap *regmap; + struct completion done; + bool use_eoc; + const struct bmp280_chip_info *chip_info; + union { + struct bmp180_calib bmp180; + struct bmp280_calib bmp280; + struct bmp380_calib bmp380; + } calib; + struct regulator_bulk_data supplies[BMP280_NUM_SUPPLIES]; + unsigned int start_up_time; /* in microseconds */ + + /* log of base 2 of oversampling rate */ + u8 oversampling_press; + u8 oversampling_temp; + u8 oversampling_humid; + u8 iir_filter_coeff; + + /* + * BMP380 devices introduce sampling frequency configuration. See + * datasheet sections 3.3.3. and 4.3.19 for more details. + * + * BMx280 devices allowed indirect configuration of sampling frequency + * changing the t_standby duration between measurements, as detailed on + * section 3.6.3 of the datasheet. + */ + int sampling_freq; + + /* + * Carryover value from temperature conversion, used in pressure + * calculation. + */ + s32 t_fine; + + /* + * DMA (thus cache coherency maintenance) may require the + * transfer buffers to live in their own cache lines. + */ + union { + /* Sensor data buffer */ + u8 buf[3]; + /* Calibration data buffers */ + __le16 bmp280_cal_buf[BMP280_CONTIGUOUS_CALIB_REGS / 2]; + __be16 bmp180_cal_buf[BMP180_REG_CALIB_COUNT / 2]; + u8 bmp380_cal_buf[BMP380_CALIB_REG_COUNT]; + /* Miscellaneous, endianess-aware data buffers */ + __le16 le16; + __be16 be16; + } __aligned(IIO_DMA_MINALIGN); +}; + +struct bmp280_chip_info { + unsigned int id_reg; + const unsigned int chip_id; + + const struct regmap_config *regmap_config; + + const struct iio_chan_spec *channels; + int num_channels; + unsigned int start_up_time; + + const int *oversampling_temp_avail; + int num_oversampling_temp_avail; + int oversampling_temp_default; + + const int *oversampling_press_avail; + int num_oversampling_press_avail; + int oversampling_press_default; + + const int *oversampling_humid_avail; + int num_oversampling_humid_avail; + int oversampling_humid_default; + + const int *iir_filter_coeffs_avail; + int num_iir_filter_coeffs_avail; + int iir_filter_coeff_default; + + const int (*sampling_freq_avail)[2]; + int num_sampling_freq_avail; + int sampling_freq_default; + + int (*chip_config)(struct bmp280_data *); + int (*read_temp)(struct bmp280_data *, int *); + int (*read_press)(struct bmp280_data *, int *, int *); + int (*read_humid)(struct bmp280_data *, int *, int *); + int (*read_calib)(struct bmp280_data *); +}; + +/* Chip infos for each variant */ +extern const struct bmp280_chip_info bmp180_chip_info; +extern const struct bmp280_chip_info bmp280_chip_info; +extern const struct bmp280_chip_info bme280_chip_info; +extern const struct bmp280_chip_info bmp380_chip_info; + /* Regmap configurations */ extern const struct regmap_config bmp180_regmap_config; extern const struct regmap_config bmp280_regmap_config; @@ -199,7 +361,7 @@ extern const struct regmap_config bmp380_regmap_config; /* Probe called from different transports */ int bmp280_common_probe(struct device *dev, struct regmap *regmap, - unsigned int chip, + const struct bmp280_chip_info *, const char *name, int irq); From patchwork Sun Jan 29 01:33:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angel Iglesias X-Patchwork-Id: 13119974 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 411E8C38142 for ; Sun, 29 Jan 2023 01:34:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230302AbjA2Bek (ORCPT ); Sat, 28 Jan 2023 20:34:40 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46054 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230156AbjA2Beg (ORCPT ); Sat, 28 Jan 2023 20:34:36 -0500 Received: from mail-wm1-x336.google.com (mail-wm1-x336.google.com [IPv6:2a00:1450:4864:20::336]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 792D41ADFF; Sat, 28 Jan 2023 17:34:31 -0800 (PST) Received: by mail-wm1-x336.google.com with SMTP id fl11-20020a05600c0b8b00b003daf72fc844so7824059wmb.0; Sat, 28 Jan 2023 17:34:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=noifTElFu9mmHKT03DqbqnypIlOKd/W5pFkjf4BBLe4=; b=jpreqJpDTKuNCmKTUb4yBLFnDrq86M7Wd6Jv10pMve92idxjs7EPSdotVFRmFan85G 7dfu2qXsi4bWejbcN4P/IpMSM51lCihn1vbsQ0Gbk5PiZoQLUx9li2flS6PCoBLiw+fl hsWiDUHOsPlxSdQ86hkVoX+bai5XtaYQS7u+R5GmyXJL8rqv86P3G5Tinompx4qDzKrx 5Ufh4nT0hVW+DXyaXPYAVK3gd0xzFbOVaZIZ2SzzCARj+ZuCLQpppB/LxtoJOi5o5t+6 xaySNAJIA8Nd4DGX4QGYGu8RIkf8jlYnsldLUOA1VuDAVQpeoaoVwngnHhjn6UjBbRUj /wlw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=noifTElFu9mmHKT03DqbqnypIlOKd/W5pFkjf4BBLe4=; b=rJ1kivCPGMPmsvpXACJKbUpl/byTMmE3l/m70DDDN1yTtIjm8GfrrEDQeZDjRtXcEB uCKhX/x6DmxjYTm7zCSUimb7CLjdKtdbmT2IbFU21DLR9EkqwuDshOGQk6xE45+O+LJ1 9iA4Kv0TE4ftm89TL+wcpHFubLxMKgzJccZkKVL4cLottPhiZPEC0/u/oL2L4sA/FybA H7Gmhcnjhnx9Kfg0zpyVo6v+3upiutnx0TeitXOuS2E4yMwNh7vr+/F8v1JcYQ2K0S8+ MIQUzA14pFN++R0V7FXQVg5H9fcT1h2qicCHfZvNx7D8ylw34lo5y2kZUklLzD8ShyWH EQWQ== X-Gm-Message-State: AFqh2kpMyn5DHn7Ci7X1iagu9syglg83AEHMbqac0wx8WDQYo4mkUTX4 jU6/fb50DAT15nR86zAL8LArokm4IcI= X-Google-Smtp-Source: AMrXdXvVHQP4qiE+A4DKODzzhuFvhtpEf94dndAeTkt5LN7XVdO0gnFYLtsNkLOOxSB2dFnDxKAdUA== X-Received: by 2002:a05:600c:4f42:b0:3db:2e62:1d69 with SMTP id m2-20020a05600c4f4200b003db2e621d69mr34551985wmq.31.1674956069435; Sat, 28 Jan 2023 17:34:29 -0800 (PST) Received: from localhost.localdomain (143.red-83-35-57.dynamicip.rima-tde.net. [83.35.57.143]) by smtp.gmail.com with ESMTPSA id r7-20020a05600c434700b003dc3f195abesm5197132wme.39.2023.01.28.17.34.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 28 Jan 2023 17:34:29 -0800 (PST) From: Angel Iglesias To: linux-iio@vger.kernel.org Cc: Angel Iglesias , Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Andy Shevchenko , Andreas Klinger , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 2/7] iio: pressure: bmp280: Add preinit callback Date: Sun, 29 Jan 2023 02:33:04 +0100 Message-Id: X-Mailer: git-send-email 2.39.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Adds preinit callback to execute operations on probe before applying initial configuration. Signed-off-by: Angel Iglesias diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c index 2c8773db4b73..6467034b1d3e 100644 --- a/drivers/iio/pressure/bmp280-core.c +++ b/drivers/iio/pressure/bmp280-core.c @@ -1076,6 +1076,12 @@ static const int bmp380_odr_table[][2] = { [BMP380_ODR_0_0015HZ] = {0, 1526}, }; +static int bmp380_preinit(struct bmp280_data *data) +{ + /* BMP3xx requires soft-reset as part of initialization */ + return bmp380_cmd(data, BMP380_CMD_SOFT_RESET); +} + static int bmp380_chip_config(struct bmp280_data *data) { bool change = false, aux; @@ -1206,6 +1212,7 @@ const struct bmp280_chip_info bmp380_chip_info = { .read_temp = bmp380_read_temp, .read_press = bmp380_read_press, .read_calib = bmp380_read_calib, + .preinit = bmp380_preinit, }; EXPORT_SYMBOL_NS(bmp380_chip_info, IIO_BMP280); @@ -1605,11 +1612,11 @@ int bmp280_common_probe(struct device *dev, return -EINVAL; } - /* BMP3xx requires soft-reset as part of initialization */ - if (chip_id == BMP380_CHIP_ID) { - ret = bmp380_cmd(data, BMP380_CMD_SOFT_RESET); - if (ret < 0) - return ret; + if (data->chip_info->preinit) { + ret = data->chip_info->preinit(data); + if (ret) + return dev_err_probe(data->dev, ret, + "error running preinit tasks\n"); } ret = data->chip_info->chip_config(data); diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h index 387723fd0772..be17104ef0a2 100644 --- a/drivers/iio/pressure/bmp280.h +++ b/drivers/iio/pressure/bmp280.h @@ -345,6 +345,7 @@ struct bmp280_chip_info { int (*read_press)(struct bmp280_data *, int *, int *); int (*read_humid)(struct bmp280_data *, int *, int *); int (*read_calib)(struct bmp280_data *); + int (*preinit)(struct bmp280_data *); }; /* Chip infos for each variant */ From patchwork Sun Jan 29 01:33:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angel Iglesias X-Patchwork-Id: 13119975 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 16ACEC636CD for ; Sun, 29 Jan 2023 01:34:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230519AbjA2Beo (ORCPT ); Sat, 28 Jan 2023 20:34:44 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46104 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230415AbjA2Bem (ORCPT ); Sat, 28 Jan 2023 20:34:42 -0500 Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 838536E90; Sat, 28 Jan 2023 17:34:40 -0800 (PST) Received: by mail-wm1-x332.google.com with SMTP id c4-20020a1c3504000000b003d9e2f72093so7812374wma.1; Sat, 28 Jan 2023 17:34:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=AFBA6s5bUSQHKQZCR86FqzNyuwtdgl9QTJx6x9ni9F4=; b=VH5GtG2GT8h1gDoyFtU+s0tcejchUSM7o9pZfktwqqMoncROB3KT271+9lnG8DvUlu Z18QiusI/CkhwGksNq+j1M6fxmGmjfq48ji++DoLiqKvfl08R1M+THPACq0FjYXT+rM2 T/4Ep0s1MRJ+XF5sgeRTpuv/qwEPUb+Vi8L986VvpFkdR4da5oaUeE6BzkMtJsKjbGAu RBxk7+r+fyRo+SNNvVkJpyIEdGVwH+tQGcH6zFufPH7c/pSMhwl44KwVQcgR8l2GKyot WDb28KOtsZkdasgmJT+MXDs8CziuMBb6vFjo6lGNNVsiMDYt3VuSuFW9gJt8ir8ANhnK OM7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=AFBA6s5bUSQHKQZCR86FqzNyuwtdgl9QTJx6x9ni9F4=; b=hlJ7N3Fimw8plmvJdXJW+948Pl03A9jOicnyavMs9j8+iylanIhu1BJ5D1/IaeY2Oc lxJSoJ0E/89qY8cowA2oDoWaiFe/NYaUJgYLvrVeaahAC486Vp5rzjY84zjS+F6cvHeN TdZHrneoiesS+I2zHcIH6Oykbj8oe/dJ5NTs+9dpOnpBMM75zIIROaYyx4Vk2Efvnhum J9pbFAi8yG+jzGbA8HcPYzBjS4PDzEPLDw1r4DONCiDk4Ls/T8iHczf2iYuADxnxApfL dCeMfcZw5yaGgX1VFD6p7WsFCTg3hHzYWBrvaDuArC7+/cTQKT//IiNWRfbuEkvPqtxC qZkg== X-Gm-Message-State: AFqh2kryAxiFoNjgcAXNXh4VLAANiiZbZbL6O+H7QA5M2l364qKXrf0m F9mFCiI/Go2GARyg9zS72a/F86Eud8Y= X-Google-Smtp-Source: AMrXdXsE73BjVrDiu1Be+/qn/WFA+vMxgCMo1PvaH0Id3EU6JhoDwuyzVYqPUQQCBV1cR7XoeCf63w== X-Received: by 2002:a05:600c:540d:b0:3d9:fb59:c16b with SMTP id he13-20020a05600c540d00b003d9fb59c16bmr41793830wmb.36.1674956078932; Sat, 28 Jan 2023 17:34:38 -0800 (PST) Received: from localhost.localdomain (143.red-83-35-57.dynamicip.rima-tde.net. [83.35.57.143]) by smtp.gmail.com with ESMTPSA id r7-20020a05600c434700b003dc3f195abesm5197132wme.39.2023.01.28.17.34.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 28 Jan 2023 17:34:38 -0800 (PST) From: Angel Iglesias To: linux-iio@vger.kernel.org Cc: Angel Iglesias , Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Andy Shevchenko , Andreas Klinger , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 3/7] iio: pressure: bmp280: Make read calibration callback optional Date: Sun, 29 Jan 2023 02:33:05 +0100 Message-Id: <61b0aee1c4838caed97774dccd88ed9fae279f76.1674954271.git.ang.iglesiasg@gmail.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Newer models do not require read the calibration parameters and apply the compensation algorithms in the sensor. Suggested-by: Jonathan Cameron Signed-off-by: Angel Iglesias diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c index 6467034b1d3e..22addaaa5393 100644 --- a/drivers/iio/pressure/bmp280-core.c +++ b/drivers/iio/pressure/bmp280-core.c @@ -1631,10 +1631,12 @@ int bmp280_common_probe(struct device *dev, * time once. They will not change. */ - ret = data->chip_info->read_calib(data); - if (ret < 0) - return dev_err_probe(data->dev, ret, - "failed to read calibration coefficients\n"); + if (data->chip_info->read_calib) { + ret = data->chip_info->read_calib(data); + if (ret < 0) + return dev_err_probe(data->dev, ret, + "failed to read calibration coefficients\n"); + } /* * Attempt to grab an optional EOC IRQ - only the BMP085 has this From patchwork Sun Jan 29 01:33:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angel Iglesias X-Patchwork-Id: 13119976 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C30DFC38142 for ; Sun, 29 Jan 2023 01:35:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231648AbjA2BfD (ORCPT ); Sat, 28 Jan 2023 20:35:03 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46228 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232055AbjA2Bez (ORCPT ); Sat, 28 Jan 2023 20:34:55 -0500 Received: from mail-wm1-x336.google.com (mail-wm1-x336.google.com [IPv6:2a00:1450:4864:20::336]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D2D42227A7; Sat, 28 Jan 2023 17:34:48 -0800 (PST) Received: by mail-wm1-x336.google.com with SMTP id fl11-20020a05600c0b8b00b003daf72fc844so7824280wmb.0; Sat, 28 Jan 2023 17:34:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=bM0qucXfvVQKhID/FnUOMltEKs8rxZzOAPjYUvwbaic=; b=c2y4WG3NAKhRDnoZCtb0LhLspsMfb7BhPNCSyhuDN8PtyRRjOSG3UYQHuty82opyEF wN5ow9JvF1IGNTvVWZ6/VOcSQ22Dd6fAa1pyFxQXEqAMFCntjOaJijiWxiOd9vUyzX2k iUIr0HXlL/1FwPeXNQ315OolktCjRYi1eoVNo58qmu12ZiaQTqNzq36EbHBcut1ctxXW RGISl+tyJs3vLQPHJC0GxsdG6Mo8EcfvheDH+ikKju3ZR68x5O8fA9SXBUi1cdbh47Q4 XYtpHJ1gDOhqgS7+IY9FJMZk2Q661OYlJ0+GI2WtD1tqVkI7vTJpdR8BzYmV1AZoGdtx SWVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=bM0qucXfvVQKhID/FnUOMltEKs8rxZzOAPjYUvwbaic=; b=p7Ia0cK/yZH2QHReeKcw+9XEYzX8Jy+K63FFNqb8AE9T2jHNhtQH5lQCLso/UeuRsv RajumN8mGlQ4IRKX/2ampwc8huazZQq1ysaa6I3n8wOWVysE0yNKzOE8YdqqN/8BDRcK fq+G99cSjNVny8j7BEvSCO/xEZaWrl4KKObcYx+3eeENl1TgTJrBKxRKSH49OT9PnLXa KXihszGcVOyGGxdozd20uB/o5rP76yjUPc1qjxHPGx5iLYaNPPtxyAxDEXtllYOD636g /aKLczhLHdlbFVp+n0J6w4R+hlhE5RoU5xmbr4xuDk206ROYudXLbPeZhmRFpYZxq1tj xMZg== X-Gm-Message-State: AFqh2kqckW5gw9Wb9Bu8rgWJL7eqv6dUBsCRX6zKqbVUEQHKBsEmpNT5 HTslwed33V7gNHd9OnqqwDgjykceQtw= X-Google-Smtp-Source: AMrXdXtcfTfF8757XXTQ05Zqcx6IoSfu3Rpq0oy4KPBtmkV66FgUPcoBEUnL8Cosc8yIFU5WKZDzTg== X-Received: by 2002:a05:600c:2d08:b0:3cf:7dc1:f424 with SMTP id x8-20020a05600c2d0800b003cf7dc1f424mr44150800wmf.3.1674956088325; Sat, 28 Jan 2023 17:34:48 -0800 (PST) Received: from localhost.localdomain (143.red-83-35-57.dynamicip.rima-tde.net. [83.35.57.143]) by smtp.gmail.com with ESMTPSA id r7-20020a05600c434700b003dc3f195abesm5197132wme.39.2023.01.28.17.34.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 28 Jan 2023 17:34:48 -0800 (PST) From: Angel Iglesias To: linux-iio@vger.kernel.org Cc: Angel Iglesias , Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Andy Shevchenko , Andreas Klinger , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 4/7] iio: pressure: Kconfig: Delete misleading I2C reference on bmp280 title Date: Sun, 29 Jan 2023 02:33:06 +0100 Message-Id: X-Mailer: git-send-email 2.39.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Title entry for BMP280 called the driver an I2C implementation, when the driver supports both I2C and SPI. Signed-off-by: Angel Iglesias diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig index c9453389e4f7..cec4b429cd64 100644 --- a/drivers/iio/pressure/Kconfig +++ b/drivers/iio/pressure/Kconfig @@ -17,7 +17,7 @@ config ABP060MG will be called abp060mg. config BMP280 - tristate "Bosch Sensortec BMP180/BMP280/BMP380 pressure sensor I2C driver" + tristate "Bosch Sensortec BMP180/BMP280/BMP380 pressure sensor driver" depends on (I2C || SPI_MASTER) select REGMAP select BMP280_I2C if (I2C) From patchwork Sun Jan 29 01:33:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angel Iglesias X-Patchwork-Id: 13119977 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F192CC61D97 for ; Sun, 29 Jan 2023 01:35:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233782AbjA2Bfp (ORCPT ); Sat, 28 Jan 2023 20:35:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46476 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231567AbjA2Bfg (ORCPT ); Sat, 28 Jan 2023 20:35:36 -0500 Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7DC1A227BB; Sat, 28 Jan 2023 17:34:59 -0800 (PST) Received: by mail-wm1-x329.google.com with SMTP id l35-20020a05600c1d2300b003dc4634a466so1786576wms.4; Sat, 28 Jan 2023 17:34:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=X5OPwoktr/gHLCZIx1nzPWjzcvgFIbWWXHyNhPqOslY=; b=ASp2JV8xsqi/naxj1oeuPaSQq99D5QfIeiYf+g+MXDzOXCarrPJP+P2PyLzmtGhk5+ /bARaPZ4meSCKlB5cmWm41ojBpkTLSPP4Vt164OcHKUl5rtq7BqQkt8TWMfCXzW3wx7J 8BKMKlZZDw8DN79zYn2HxWE0tg7syR/+JuaQi9lte2fpWKIt7L0feSAsWPLFZvo2I6sN VjcTkufdzkXPGUSjnUvYZLia8PfTpOnmcOctAE8s3XFjEco4EKK+z9+ubeYWlrvooaFx uNIQs3KWyWyPV8fzdnowXrEEkfrtge7p+/tvzVKBMH3LSBUSs6R+V1/YqDNBqztPZ49M bG1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=X5OPwoktr/gHLCZIx1nzPWjzcvgFIbWWXHyNhPqOslY=; b=JW70G1I4HfMdZR9P6w3hAymXiqcfkIRSA8KBA3K01NH1ff6pTerE8TG9QS9xKCyR+H 5XH1rSjtvAOqY+OaImHutvj5DhhiSWzFjWTx2+1uzkIeB3M9WY1ylccFNEcEsTiJvq2O imzL4nID7phGm7VkYtH2YcrmYme8pNOShzXcbKePPTcYPRIH/+6ugOLlBOQnpTrhlbXm AMTUrvCT3kJ0yoUz/O7N1uTRXgy1OZe6FYXeloAch7oOVFeUCFazeHOnhC7bvZ2VeCh1 /9SdDxoMft3F69BsqHjZkXj+dHd0Yl+fmOxNNV8sfd3Thl4gDbSOzxqZK1JTiqIOj5Gp 8Mag== X-Gm-Message-State: AO0yUKX3wMrLBtYBK/772cDm5Y3+6MUhpkVV+8/21DW47ZYCajOotD6c skOZQWuxgbhQn/DXiBC/SX4ULSIOW/U= X-Google-Smtp-Source: AK7set/OGtDpMplzR30bAhx/iRoYeymYvSOfbirw7zWEU09d9SrgLUD3VIK3qHG49o7GYF8GMjAQ+w== X-Received: by 2002:a05:600c:3d86:b0:3dc:53a2:2690 with SMTP id bi6-20020a05600c3d8600b003dc53a22690mr535459wmb.7.1674956097873; Sat, 28 Jan 2023 17:34:57 -0800 (PST) Received: from localhost.localdomain (143.red-83-35-57.dynamicip.rima-tde.net. [83.35.57.143]) by smtp.gmail.com with ESMTPSA id r7-20020a05600c434700b003dc3f195abesm5197132wme.39.2023.01.28.17.34.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 28 Jan 2023 17:34:57 -0800 (PST) From: Angel Iglesias To: linux-iio@vger.kernel.org Cc: Angel Iglesias , Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Andy Shevchenko , Andreas Klinger , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 5/7] iio: pressure: bmp280: Add support for new sensor BMP580 Date: Sun, 29 Jan 2023 02:33:07 +0100 Message-Id: <97a234ddac057eea1e6790d7fa4a66564abec2ed.1674954271.git.ang.iglesiasg@gmail.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Adds compatibility with the new sensor generation, the BMP580. The measurement and initialization codepaths are adapted from the device datasheet and the repository from manufacturer at https://github.com/boschsensortec/BMP5-Sensor-API. Signed-off-by: Angel Iglesias diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig index cec4b429cd64..02b97e89de50 100644 --- a/drivers/iio/pressure/Kconfig +++ b/drivers/iio/pressure/Kconfig @@ -17,14 +17,14 @@ config ABP060MG will be called abp060mg. config BMP280 - tristate "Bosch Sensortec BMP180/BMP280/BMP380 pressure sensor driver" + tristate "Bosch Sensortec BMP180/BMP280/BMP380/BMP580 pressure sensor driver" depends on (I2C || SPI_MASTER) select REGMAP select BMP280_I2C if (I2C) select BMP280_SPI if (SPI_MASTER) help - Say yes here to build support for Bosch Sensortec BMP180, BMP280 and - BMP380 pressure and temperature sensors. Also supports the BME280 with + Say yes here to build support for Bosch Sensortec BMP180, BMP280, BMP380 + and BMP580 pressure and temperature sensors. Also supports the BME280 with an additional humidity sensor channel. To compile this driver as a module, choose M here: the core module diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c index 22addaaa5393..c65fb4025ad9 100644 --- a/drivers/iio/pressure/bmp280-core.c +++ b/drivers/iio/pressure/bmp280-core.c @@ -13,6 +13,7 @@ * https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmp280-ds001.pdf * https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bme280-ds002.pdf * https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmp388-ds001.pdf + * https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmp581-ds004.pdf * * Notice: * The link to the bmp180 datasheet points to an outdated version missing these changes: @@ -71,6 +72,41 @@ enum bmp380_odr { BMP380_ODR_0_0015HZ, }; +enum bmp580_odr { + BMP580_ODR_240HZ, + BMP580_ODR_218HZ, + BMP580_ODR_199HZ, + BMP580_ODR_179HZ, + BMP580_ODR_160HZ, + BMP580_ODR_149HZ, + BMP580_ODR_140HZ, + BMP580_ODR_129HZ, + BMP580_ODR_120HZ, + BMP580_ODR_110HZ, + BMP580_ODR_100HZ, + BMP580_ODR_89HZ, + BMP580_ODR_80HZ, + BMP580_ODR_70HZ, + BMP580_ODR_60HZ, + BMP580_ODR_50HZ, + BMP580_ODR_45HZ, + BMP580_ODR_40HZ, + BMP580_ODR_35HZ, + BMP580_ODR_30HZ, + BMP580_ODR_25HZ, + BMP580_ODR_20HZ, + BMP580_ODR_15HZ, + BMP580_ODR_10HZ, + BMP580_ODR_5HZ, + BMP580_ODR_4HZ, + BMP580_ODR_3HZ, + BMP580_ODR_2HZ, + BMP580_ODR_1HZ, + BMP580_ODR_0_5HZ, + BMP580_ODR_0_25HZ, + BMP580_ODR_0_125HZ, +}; + /* * These enums are used for indexing into the array of compensation * parameters for BMP280. @@ -1216,6 +1252,303 @@ const struct bmp280_chip_info bmp380_chip_info = { }; EXPORT_SYMBOL_NS(bmp380_chip_info, IIO_BMP280); +/* + * BMP5xx soft reset procedure + */ +static int bmp580_soft_reset(struct bmp280_data *data) +{ + unsigned int reg; + int ret; + + /* Write reset word to CMD register */ + ret = regmap_write(data->regmap, BMP580_REG_CMD, BMP580_CMD_SOFT_RESET); + if (ret) { + dev_err(data->dev, "failed to send reset command to device\n"); + return ret; + } + /* Wait 2ms for reset completion */ + usleep_range(2000, 2500); + + /* Dummy read of chip_id */ + ret = regmap_read(data->regmap, BMP580_REG_CHIP_ID, ®); + if (ret) { + dev_err(data->dev, "failed to reestablish comms after reset\n"); + return ret; + } + + /* Check if POR bit is set on interrupt reg */ + ret = regmap_read(data->regmap, BMP580_REG_INT_STATUS, ®); + if (ret) { + dev_err(data->dev, "error reading interrupt status register\n"); + return ret; + } + if (!(reg & BMP580_INT_STATUS_POR_MASK)) { + dev_err(data->dev, "error resetting sensor\n"); + return -EINVAL; + } + + return 0; +} + +/* + * Contrary to previous sensors families, compensation algorithm is builtin. + * We are only required to read the register raw data and adapt the ranges + * for what is expected on IIO ABI. + */ + +static int bmp580_read_temp(struct bmp280_data *data, int *val) +{ + s32 raw_temp; + int ret; + + ret = regmap_bulk_read(data->regmap, BMP580_REG_TEMP_XLSB, data->buf, + sizeof(data->buf)); + if (ret) { + dev_err(data->dev, "failed to read temperature\n"); + return ret; + } + + raw_temp = get_unaligned_le24(data->buf); + if (raw_temp == BMP580_TEMP_SKIPPED) { + dev_err(data->dev, "reading temperature skipped\n"); + return -EIO; + } + + /* + * Temperature is returned in Celsius degrees in fractional + * form down 2^16. We reescale by x1000 to return milli Celsius + * to respect IIO ABI. + */ + *val = (raw_temp * 1000) >> 16; + return IIO_VAL_INT; +} + +static int bmp580_read_press(struct bmp280_data *data, int *val, int *val2) +{ + u32 raw_press; + int ret; + + ret = regmap_bulk_read(data->regmap, BMP580_REG_PRESS_XLSB, data->buf, + sizeof(data->buf)); + if (ret) { + dev_err(data->dev, "failed to read pressure\n"); + return ret; + } + + raw_press = get_unaligned_le24(data->buf); + if (raw_press == BMP580_PRESS_SKIPPED) { + dev_err(data->dev, "reading pressure skipped\n"); + return -EIO; + } + /* + * Pressure is returned in Pascals in fractional form down 2^16. + * We reescale /1000 to convert to kilopascal to respect IIO ABI. + */ + *val = raw_press; + *val2 = 64000; /* 2^6 * 1000 */ + return IIO_VAL_FRACTIONAL; +} + +static const int bmp580_odr_table[][2] = { + [BMP580_ODR_240HZ] = {240, 0}, + [BMP580_ODR_218HZ] = {218, 0}, + [BMP580_ODR_199HZ] = {199, 0}, + [BMP580_ODR_179HZ] = {179, 0}, + [BMP580_ODR_160HZ] = {160, 0}, + [BMP580_ODR_149HZ] = {149, 0}, + [BMP580_ODR_140HZ] = {140, 0}, + [BMP580_ODR_129HZ] = {129, 0}, + [BMP580_ODR_120HZ] = {120, 0}, + [BMP580_ODR_110HZ] = {110, 0}, + [BMP580_ODR_100HZ] = {100, 0}, + [BMP580_ODR_89HZ] = {89, 0}, + [BMP580_ODR_80HZ] = {80, 0}, + [BMP580_ODR_70HZ] = {70, 0}, + [BMP580_ODR_60HZ] = {60, 0}, + [BMP580_ODR_50HZ] = {50, 0}, + [BMP580_ODR_45HZ] = {45, 0}, + [BMP580_ODR_40HZ] = {40, 0}, + [BMP580_ODR_35HZ] = {35, 0}, + [BMP580_ODR_30HZ] = {30, 0}, + [BMP580_ODR_25HZ] = {25, 0}, + [BMP580_ODR_20HZ] = {20, 0}, + [BMP580_ODR_15HZ] = {15, 0}, + [BMP580_ODR_10HZ] = {10, 0}, + [BMP580_ODR_5HZ] = {5, 0}, + [BMP580_ODR_4HZ] = {4, 0}, + [BMP580_ODR_3HZ] = {3, 0}, + [BMP580_ODR_2HZ] = {2, 0}, + [BMP580_ODR_1HZ] = {1, 0}, + [BMP580_ODR_0_5HZ] = {0, 500000}, + [BMP580_ODR_0_25HZ] = {0, 250000}, + [BMP580_ODR_0_125HZ] = {0, 125000}, +}; + +static int bmp580_preinit(struct bmp280_data *data) +{ + unsigned int reg; + int ret; + + /* Issue soft-reset command */ + ret = bmp580_soft_reset(data); + if (ret) + return ret; + + /* Post powerup sequence */ + ret = regmap_read(data->regmap, BMP580_REG_CHIP_ID, ®); + if (ret) + return ret; + + /* Print warn message if we don't know the chip id */ + if (reg != BMP580_CHIP_ID && reg != BMP580_CHIP_ID_ALT) + dev_warn(data->dev, "preinit: unexpected chip_id\n"); + + ret = regmap_read(data->regmap, BMP580_REG_STATUS, ®); + if (ret) + return ret; + + /* Check nvm status */ + if (!(reg & BMP580_STATUS_NVM_RDY_MASK) || (reg & BMP580_STATUS_NVM_ERR_MASK)) { + dev_err(data->dev, "preinit: nvm error on powerup sequence\n"); + return -EIO; + } + + return 0; +} + +static int bmp580_chip_config(struct bmp280_data *data) +{ + bool change = false, aux; + unsigned int tmp; + u8 reg_val; + int ret; + + /* Sets sensor in standby mode */ + ret = regmap_update_bits(data->regmap, BMP580_REG_ODR_CONFIG, + BMP580_MODE_MASK | BMP580_ODR_DEEPSLEEP_DIS, + BMP580_ODR_DEEPSLEEP_DIS | + FIELD_PREP(BMP580_MODE_MASK, BMP580_MODE_SLEEP)); + if (ret) { + dev_err(data->dev, "failed to change sensor to standby mode\n"); + return ret; + } + /* From datasheet's table 4: electrical characteristics */ + usleep_range(2500, 3000); + + /* Set default DSP mode settings */ + reg_val = FIELD_PREP(BMP580_DSP_COMP_MASK, BMP580_DSP_PRESS_TEMP_COMP_EN) | + BMP580_DSP_SHDW_IIR_TEMP_EN | BMP580_DSP_SHDW_IIR_PRESS_EN; + + ret = regmap_update_bits(data->regmap, BMP580_REG_DSP_CONFIG, + BMP580_DSP_COMP_MASK | + BMP580_DSP_SHDW_IIR_TEMP_EN | + BMP580_DSP_SHDW_IIR_PRESS_EN, reg_val); + + /* Configure oversampling */ + reg_val = FIELD_PREP(BMP580_OSR_TEMP_MASK, data->oversampling_temp) | + FIELD_PREP(BMP580_OSR_PRESS_MASK, data->oversampling_press) | + BMP580_OSR_PRESS_EN; + + ret = regmap_update_bits_check(data->regmap, BMP580_REG_OSR_CONFIG, + BMP580_OSR_TEMP_MASK | BMP580_OSR_PRESS_MASK | + BMP580_OSR_PRESS_EN, + reg_val, &aux); + if (ret) { + dev_err(data->dev, "failed to write oversampling register\n"); + return ret; + } + change = change || aux; + + /* Configure output data rate */ + ret = regmap_update_bits_check(data->regmap, BMP580_REG_ODR_CONFIG, BMP580_ODR_MASK, + FIELD_PREP(BMP580_ODR_MASK, data->sampling_freq), + &aux); + if (ret) { + dev_err(data->dev, "failed to write ODR configuration register\n"); + return ret; + } + change = change || aux; + + /* Set filter data */ + reg_val = FIELD_PREP(BMP580_DSP_IIR_PRESS_MASK, data->iir_filter_coeff) | + FIELD_PREP(BMP580_DSP_IIR_TEMP_MASK, data->iir_filter_coeff); + + ret = regmap_update_bits_check(data->regmap, BMP580_REG_DSP_IIR, + BMP580_DSP_IIR_PRESS_MASK | + BMP580_DSP_IIR_TEMP_MASK, + reg_val, &aux); + if (ret) { + dev_err(data->dev, "failed to write config register\n"); + return ret; + } + change = change || aux; + + /* Restore sensor to normal operation mode */ + ret = regmap_write_bits(data->regmap, BMP580_REG_ODR_CONFIG, + BMP580_MODE_MASK, + FIELD_PREP(BMP580_MODE_MASK, BMP580_MODE_NORMAL)); + if (ret) { + dev_err(data->dev, "failed to set normal mode\n"); + return ret; + } + /* From datasheet's table 4: electrical characteristics */ + usleep_range(3000, 3500); + + if (change) { + /* + * Check if ODR and OSR settings are valid or we are + * operating in a degraded mode. + */ + ret = regmap_read(data->regmap, BMP580_REG_EFF_OSR, &tmp); + if (ret) { + dev_err(data->dev, "error reading effective OSR register\n"); + return ret; + } + if (!(tmp & BMP580_EFF_OSR_VALID_ODR)) { + dev_warn(data->dev, "OSR and ODR incompatible settings detected\n"); + /* Set current OSR settings from data on effective OSR */ + data->oversampling_temp = FIELD_GET(BMP580_EFF_OSR_TEMP_MASK, tmp); + data->oversampling_press = FIELD_GET(BMP580_EFF_OSR_PRESS_MASK, tmp); + return -EINVAL; + } + } + + return 0; +} + +static const int bmp580_oversampling_avail[] = { 1, 2, 4, 8, 16, 32, 64, 128 }; + +const struct bmp280_chip_info bmp580_chip_info = { + .id_reg = BMP580_REG_CHIP_ID, + .chip_id = BMP580_CHIP_ID, + .regmap_config = &bmp580_regmap_config, + .start_up_time = 2000, + .channels = bmp380_channels, + .num_channels = 2, + + .oversampling_temp_avail = bmp580_oversampling_avail, + .num_oversampling_temp_avail = ARRAY_SIZE(bmp580_oversampling_avail), + .oversampling_temp_default = ilog2(1), + + .oversampling_press_avail = bmp580_oversampling_avail, + .num_oversampling_press_avail = ARRAY_SIZE(bmp580_oversampling_avail), + .oversampling_press_default = ilog2(4), + + .sampling_freq_avail = bmp580_odr_table, + .num_sampling_freq_avail = ARRAY_SIZE(bmp580_odr_table) * 2, + .sampling_freq_default = BMP580_ODR_50HZ, + + .iir_filter_coeffs_avail = bmp380_iir_filter_coeffs_avail, + .num_iir_filter_coeffs_avail = ARRAY_SIZE(bmp380_iir_filter_coeffs_avail), + .iir_filter_coeff_default = 2, + + .chip_config = bmp580_chip_config, + .read_temp = bmp580_read_temp, + .read_press = bmp580_read_press, + .preinit = bmp580_preinit, +}; +EXPORT_SYMBOL_NS(bmp580_chip_info, IIO_BMP280); + static int bmp180_measure(struct bmp280_data *data, u8 ctrl_meas) { const int conversion_time_max[] = { 4500, 7500, 13500, 25500 }; diff --git a/drivers/iio/pressure/bmp280-i2c.c b/drivers/iio/pressure/bmp280-i2c.c index 5f908e2c9826..567b945e6427 100644 --- a/drivers/iio/pressure/bmp280-i2c.c +++ b/drivers/iio/pressure/bmp280-i2c.c @@ -34,6 +34,7 @@ static const struct of_device_id bmp280_of_i2c_match[] = { { .compatible = "bosch,bmp280", .data = &bmp280_chip_info }, { .compatible = "bosch,bme280", .data = &bme280_chip_info }, { .compatible = "bosch,bmp380", .data = &bmp380_chip_info }, + { .compatible = "bosch,bmp580", .data = &bmp580_chip_info }, { }, }; MODULE_DEVICE_TABLE(of, bmp280_of_i2c_match); @@ -44,6 +45,7 @@ static const struct i2c_device_id bmp280_i2c_id[] = { {"bmp280", (kernel_ulong_t)&bmp280_chip_info }, {"bme280", (kernel_ulong_t)&bme280_chip_info }, {"bmp380", (kernel_ulong_t)&bmp380_chip_info }, + {"bmp580", (kernel_ulong_t)&bmp580_chip_info }, { }, }; MODULE_DEVICE_TABLE(i2c, bmp280_i2c_id); diff --git a/drivers/iio/pressure/bmp280-regmap.c b/drivers/iio/pressure/bmp280-regmap.c index c98c67970265..3ee56720428c 100644 --- a/drivers/iio/pressure/bmp280-regmap.c +++ b/drivers/iio/pressure/bmp280-regmap.c @@ -115,6 +115,54 @@ static bool bmp380_is_volatile_reg(struct device *dev, unsigned int reg) } } +static bool bmp580_is_writeable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case BMP580_REG_NVM_DATA_MSB: + case BMP580_REG_NVM_DATA_LSB: + case BMP580_REG_NVM_ADDR: + case BMP580_REG_ODR_CONFIG: + case BMP580_REG_OSR_CONFIG: + case BMP580_REG_INT_SOURCE: + case BMP580_REG_INT_CONFIG: + case BMP580_REG_OOR_THR_MSB: + case BMP580_REG_OOR_THR_LSB: + case BMP580_REG_OOR_CONFIG: + case BMP580_REG_OOR_RANGE: + case BMP580_REG_IF_CONFIG: + case BMP580_REG_FIFO_CONFIG: + case BMP580_REG_FIFO_SEL: + case BMP580_REG_DSP_CONFIG: + case BMP580_REG_DSP_IIR: + case BMP580_REG_CMD: + return true; + default: + return false; + } +} + +static bool bmp580_is_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case BMP580_REG_NVM_DATA_MSB: + case BMP580_REG_NVM_DATA_LSB: + case BMP580_REG_FIFO_COUNT: + case BMP580_REG_INT_STATUS: + case BMP580_REG_PRESS_XLSB: + case BMP580_REG_PRESS_LSB: + case BMP580_REG_PRESS_MSB: + case BMP580_REG_FIFO_DATA: + case BMP580_REG_TEMP_XLSB: + case BMP580_REG_TEMP_LSB: + case BMP580_REG_TEMP_MSB: + case BMP580_REG_EFF_OSR: + case BMP580_REG_STATUS: + return true; + default: + return false; + } +} + const struct regmap_config bmp280_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -138,3 +186,15 @@ const struct regmap_config bmp380_regmap_config = { .volatile_reg = bmp380_is_volatile_reg, }; EXPORT_SYMBOL_NS(bmp380_regmap_config, IIO_BMP280); + +const struct regmap_config bmp580_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = BMP580_REG_CMD, + .cache_type = REGCACHE_RBTREE, + + .writeable_reg = bmp580_is_writeable_reg, + .volatile_reg = bmp580_is_volatile_reg, +}; +EXPORT_SYMBOL_NS(bmp580_regmap_config, IIO_BMP280); diff --git a/drivers/iio/pressure/bmp280-spi.c b/drivers/iio/pressure/bmp280-spi.c index d5a224b95185..1dff9bb7c4e9 100644 --- a/drivers/iio/pressure/bmp280-spi.c +++ b/drivers/iio/pressure/bmp280-spi.c @@ -85,6 +85,7 @@ static const struct of_device_id bmp280_of_spi_match[] = { { .compatible = "bosch,bmp280", .data = &bmp280_chip_info }, { .compatible = "bosch,bme280", .data = &bmp280_chip_info }, { .compatible = "bosch,bmp380", .data = &bmp380_chip_info }, + { .compatible = "bosch,bmp580", .data = &bmp580_chip_info }, { }, }; MODULE_DEVICE_TABLE(of, bmp280_of_spi_match); @@ -95,6 +96,7 @@ static const struct spi_device_id bmp280_spi_id[] = { { "bmp280", (kernel_ulong_t)&bmp280_chip_info }, { "bme280", (kernel_ulong_t)&bmp280_chip_info }, { "bmp380", (kernel_ulong_t)&bmp380_chip_info }, + { "bmp580", (kernel_ulong_t)&bmp580_chip_info }, { } }; MODULE_DEVICE_TABLE(spi, bmp280_spi_id); diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h index be17104ef0a2..f29d44b09efc 100644 --- a/drivers/iio/pressure/bmp280.h +++ b/drivers/iio/pressure/bmp280.h @@ -6,6 +6,107 @@ #include +/* BMP580 specific registers */ +#define BMP580_REG_CMD 0x7E +#define BMP580_REG_EFF_OSR 0x38 +#define BMP580_REG_ODR_CONFIG 0x37 +#define BMP580_REG_OSR_CONFIG 0x36 +#define BMP580_REG_IF_CONFIG 0x13 +#define BMP580_REG_REV_ID 0x02 +#define BMP580_REG_CHIP_ID 0x01 +/* OOR allows to configure a pressure alarm */ +#define BMP580_REG_OOR_CONFIG 0x35 +#define BMP580_REG_OOR_RANGE 0x34 +#define BMP580_REG_OOR_THR_MSB 0x33 +#define BMP580_REG_OOR_THR_LSB 0x32 +/* DSP registers (IIR filters) */ +#define BMP580_REG_DSP_IIR 0x31 +#define BMP580_REG_DSP_CONFIG 0x30 +/* NVM access registers */ +#define BMP580_REG_NVM_DATA_MSB 0x2D +#define BMP580_REG_NVM_DATA_LSB 0x2C +#define BMP580_REG_NVM_ADDR 0x2B +/* Status registers */ +#define BMP580_REG_STATUS 0x28 +#define BMP580_REG_INT_STATUS 0x27 +#define BMP580_REG_CHIP_STATUS 0x11 +/* Data registers */ +#define BMP580_REG_FIFO_DATA 0x29 +#define BMP580_REG_PRESS_MSB 0x22 +#define BMP580_REG_PRESS_LSB 0x21 +#define BMP580_REG_PRESS_XLSB 0x20 +#define BMP580_REG_TEMP_MSB 0x1F +#define BMP580_REG_TEMP_LSB 0x1E +#define BMP580_REG_TEMP_XLSB 0x1D +/* FIFO config registers */ +#define BMP580_REG_FIFO_SEL 0x18 +#define BMP580_REG_FIFO_COUNT 0x17 +#define BMP580_REG_FIFO_CONFIG 0x16 +/* Interruptions config registers */ +#define BMP580_REG_INT_SOURCE 0x15 +#define BMP580_REG_INT_CONFIG 0x14 + +#define BMP580_CMD_NOOP 0x00 +#define BMP580_CMD_EXTMODE_SEQ_0 0x73 +#define BMP580_CMD_EXTMODE_SEQ_1 0xB4 +#define BMP580_CMD_EXTMODE_SEQ_2 0x69 +#define BMP580_CMD_NVM_OP_SEQ_0 0x5D +#define BMP580_CMD_NVM_READ_SEQ_1 0xA5 +#define BMP580_CMD_NVM_WRITE_SEQ_1 0xA0 +#define BMP580_CMD_SOFT_RESET 0xB6 + +#define BMP580_INT_STATUS_POR_MASK BIT(4) + +#define BMP580_STATUS_CORE_RDY_MASK BIT(0) +#define BMP580_STATUS_NVM_RDY_MASK BIT(1) +#define BMP580_STATUS_NVM_ERR_MASK BIT(2) +#define BMP580_STATUS_NVM_CMD_ERR_MASK BIT(3) + +#define BMP580_OSR_PRESS_MASK GENMASK(5, 3) +#define BMP580_OSR_TEMP_MASK GENMASK(2, 0) +#define BMP580_OSR_PRESS_EN BIT(6) +#define BMP580_EFF_OSR_PRESS_MASK GENMASK(5, 3) +#define BMP580_EFF_OSR_TEMP_MASK GENMASK(2, 0) +#define BMP580_EFF_OSR_VALID_ODR BIT(7) + +#define BMP580_ODR_MASK GENMASK(6, 2) +#define BMP580_MODE_MASK GENMASK(1, 0) +#define BMP580_MODE_SLEEP 0 +#define BMP580_MODE_NORMAL 1 +#define BMP580_MODE_FORCED 2 +#define BMP580_MODE_CONTINOUS 3 +#define BMP580_ODR_DEEPSLEEP_DIS BIT(7) + +#define BMP580_DSP_COMP_MASK GENMASK(1, 0) +#define BMP580_DSP_COMP_DIS 0 +#define BMP580_DSP_TEMP_COMP_EN 1 +/* + * In section 7.27 of datasheet, modes 2 and 3 are technically the same. + * Pressure compensation means also enabling temperature compensation + */ +#define BMP580_DSP_PRESS_COMP_EN 2 +#define BMP580_DSP_PRESS_TEMP_COMP_EN 3 +#define BMP580_DSP_IIR_FORCED_FLUSH BIT(2) +#define BMP580_DSP_SHDW_IIR_TEMP_EN BIT(3) +#define BMP580_DSP_FIFO_IIR_TEMP_EN BIT(4) +#define BMP580_DSP_SHDW_IIR_PRESS_EN BIT(5) +#define BMP580_DSP_FIFO_IIR_PRESS_EN BIT(6) +#define BMP580_DSP_OOR_IIR_PRESS_EN BIT(7) + +#define BMP580_DSP_IIR_PRESS_MASK GENMASK(5, 3) +#define BMP580_DSP_IIR_TEMP_MASK GENMASK(2, 0) +#define BMP580_FILTER_OFF 0 +#define BMP580_FILTER_1X 1 +#define BMP580_FILTER_3X 2 +#define BMP580_FILTER_7X 3 +#define BMP580_FILTER_15X 4 +#define BMP580_FILTER_31X 5 +#define BMP580_FILTER_63X 6 +#define BMP580_FILTER_127X 7 + +#define BMP580_TEMP_SKIPPED 0x7f7f7f +#define BMP580_PRESS_SKIPPED 0x7f7f7f + /* BMP380 specific registers */ #define BMP380_REG_CMD 0x7E #define BMP380_REG_CONFIG 0x1F @@ -184,6 +285,8 @@ #define BMP280_REG_ID 0xD0 #define BMP380_CHIP_ID 0x50 +#define BMP580_CHIP_ID 0x50 +#define BMP580_CHIP_ID_ALT 0x51 #define BMP180_CHIP_ID 0x55 #define BMP280_CHIP_ID 0x58 #define BME280_CHIP_ID 0x60 @@ -353,11 +456,13 @@ extern const struct bmp280_chip_info bmp180_chip_info; extern const struct bmp280_chip_info bmp280_chip_info; extern const struct bmp280_chip_info bme280_chip_info; extern const struct bmp280_chip_info bmp380_chip_info; +extern const struct bmp280_chip_info bmp580_chip_info; /* Regmap configurations */ extern const struct regmap_config bmp180_regmap_config; extern const struct regmap_config bmp280_regmap_config; extern const struct regmap_config bmp380_regmap_config; +extern const struct regmap_config bmp580_regmap_config; /* Probe called from different transports */ int bmp280_common_probe(struct device *dev, From patchwork Sun Jan 29 01:33:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angel Iglesias X-Patchwork-Id: 13119978 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 81619C38142 for ; Sun, 29 Jan 2023 01:36:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234711AbjA2BgB (ORCPT ); Sat, 28 Jan 2023 20:36:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47226 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232628AbjA2Bfn (ORCPT ); Sat, 28 Jan 2023 20:35:43 -0500 Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4581223C64; Sat, 28 Jan 2023 17:35:09 -0800 (PST) Received: by mail-wm1-x329.google.com with SMTP id l41-20020a05600c1d2900b003daf986faaeso5945579wms.3; Sat, 28 Jan 2023 17:35:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=H4fPPorGvJaEHWHXxPRWBCDldwjlaX0Z+q61uPOSuPo=; b=ceY+MdeznrAVhfOXeFxFV4OkwcSQWzojzffUAafOIxL8cBMYUJkvJSx/5oT2tKuNHv aVvoIEQ5YmtBmUB8l4zS4xMTrKjW8zk6XokRl+kdt35aZtlI9KPpNxXaP2/g8EPtOOYv n6GYK2270xwFyP7eNW8ms0/V6rRbGoLI1ndxDsSTHpKz8Dn86ex+t5CiYkktu6oGhghJ q3QwsxV3ui1nFeQhzOdLGWGV0kuKy8X/BsT7bF/XjJOI3w1XCsNLDwZgJwCDvCXjgMyQ N8uG80Z3cbesp1J8RVsNkRO3RPTT2zsaOx9SpzG0Eiuq19R9h/+UmhnqIdIvOwikW9qE rhNA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=H4fPPorGvJaEHWHXxPRWBCDldwjlaX0Z+q61uPOSuPo=; b=YTJPy1hxX8EHZANZ/p9wMAEocl3/x7T0fWD74AL/ao6W0xh91Q/AsO4lvKnq6hpWpB dwujP7YvhTRIOvVmvPg+QfmEzzonz5kLH+Dl4vcrcAx2gkEM6xJeGtxdoD6ZoxqwJByy dIjEiGo268C04Om3+15Cdk8tcc74AoIgIgu54E6kwpngC7w7hJvPtsTOw19mVkoHye0i 92UPbtsduUhS6Jml9P5b5W/W1KGG40AtPQu73/EN6ZV862dNt+dSUOkokJd5dTfRbVsG Pkk/RJChl1m33sGZVvm/LsPr9xrY5uN/7ryVEgwzXT5UrgNb16Xh3/7SCi5SG7vDfWEq SoPQ== X-Gm-Message-State: AFqh2kpayRMSLDh4xryqPgtBuyLce2EUmmurTNrGLfzNFdd2gEwJWfQY ZN2q9hoCTkKJUgiQtsxfnR8/92I3YZA= X-Google-Smtp-Source: AMrXdXvVleLbJ1l71VKbn3RArWQSbjlMwVwC/zcNFPLY4LRhcXiMGIzXh4Be5UdOXd7UO68NZPFjdA== X-Received: by 2002:a05:600c:3110:b0:3dc:e66:4cb9 with SMTP id g16-20020a05600c311000b003dc0e664cb9mr20982368wmo.13.1674956107358; Sat, 28 Jan 2023 17:35:07 -0800 (PST) Received: from localhost.localdomain (143.red-83-35-57.dynamicip.rima-tde.net. [83.35.57.143]) by smtp.gmail.com with ESMTPSA id r7-20020a05600c434700b003dc3f195abesm5197132wme.39.2023.01.28.17.35.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 28 Jan 2023 17:35:07 -0800 (PST) From: Angel Iglesias To: linux-iio@vger.kernel.org Cc: Angel Iglesias , Krzysztof Kozlowski , Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Andy Shevchenko , Andreas Klinger , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 6/7] dt-bindings: iio: pressure: bmp085: Add BMP580 compatible string Date: Sun, 29 Jan 2023 02:33:08 +0100 Message-Id: <9d840fc038896c1b73cf0922fc11190eaf4116cc.1674954271.git.ang.iglesiasg@gmail.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Add bosch,bmp580 to compatible string for the new family of sensors. This family includes the BMP580 and BMP581 sensors. The register map in this family presents significant departures from previous generations. Signed-off-by: Angel Iglesias Acked-by: Krzysztof Kozlowski diff --git a/Documentation/devicetree/bindings/iio/pressure/bmp085.yaml b/Documentation/devicetree/bindings/iio/pressure/bmp085.yaml index 72cd2c2d3f17..f52c4794e21b 100644 --- a/Documentation/devicetree/bindings/iio/pressure/bmp085.yaml +++ b/Documentation/devicetree/bindings/iio/pressure/bmp085.yaml @@ -17,6 +17,7 @@ description: | https://www.bosch-sensortec.com/bst/products/all_products/bmp280 https://www.bosch-sensortec.com/bst/products/all_products/bme280 https://www.bosch-sensortec.com/bst/products/all_products/bmp380 + https://www.bosch-sensortec.com/bst/products/all_products/bmp580 properties: compatible: @@ -26,6 +27,7 @@ properties: - bosch,bmp280 - bosch,bme280 - bosch,bmp380 + - bosch,bmp580 reg: maxItems: 1 From patchwork Sun Jan 29 01:33:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angel Iglesias X-Patchwork-Id: 13119979 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 54560C61D97 for ; Sun, 29 Jan 2023 01:36:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233616AbjA2BgS (ORCPT ); Sat, 28 Jan 2023 20:36:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47512 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232518AbjA2Bfx (ORCPT ); Sat, 28 Jan 2023 20:35:53 -0500 Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 57E0724109; Sat, 28 Jan 2023 17:35:21 -0800 (PST) Received: by mail-wm1-x332.google.com with SMTP id j29-20020a05600c1c1d00b003dc52fed235so392522wms.1; Sat, 28 Jan 2023 17:35:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=t7EoOIyQeLcoH6apOH/p+8qL29vfGf4A8BXO8aUOa/8=; b=RG7uxBvtPo8Vrp57nCfhqwOMrmgry9P8aMSO/97by2iC5Zr1J+bETTR6g36KReXqKi e2LJPGKby1NwhYM6ZbsuqIPXxcLfUylDXiWMImFTrtHfOkv6PkO1PtLd7l2Ec5cTbIZh 7anYN3WZGnzdchvGCHXe0BiXS1BdJlh5PI7DhC45ZpWINi5YwtKS/D226+vaHuvUhaLZ iYnvw5mReh7A0R/Y9jS1A6C54min5JnmKb7rljtSCAenZ6muhGqXWKAepCFUMw1xn/Gv 6sNS6+0o4QgqmvvlUMLxdBkfwBBwwZWtjJdEcCowUIMzrUjnGnu4++z0SzEnV8XSTPz0 xbdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=t7EoOIyQeLcoH6apOH/p+8qL29vfGf4A8BXO8aUOa/8=; b=QaRr3QuEUV0vaQPT6596oUfpdDQU0hbcZM16swZTdgs0kcklWagpx5Pj9OPBHUNRDR N/yGId5F7Y123OkICguNe3wGcSLJZm/SSNfe3d/OgPSjq+VUXLPZVeNzuAC/RNZ+s6An g/84vNN7tbeA1DTb6Hylyl33WXoxbqTpOaLtdRNwqeIEPTmvrR5KjDeg9a9zjOGIwr2o gmb7hqU/lguB190rKy2ON7YB0hnu4ZLlho7lc1PLCAjnAHazfjBuBeOopHGidmxnN3rB ZItgr6fSnihQZzEtjf/kHwuIgvJPoVjGuK5oXz8o0CH7dQdni0Isga1WnLiXvXZg6qfG 1PSw== X-Gm-Message-State: AFqh2kp8bJoVuSy5XTDLhHJmiD9VzTCrlPzbj25NPSG0mX+ixDjS5B7U EwmtaN9wGNKZnflQyPRgso6okrkqbuY= X-Google-Smtp-Source: AMrXdXv7vZNjbfrNwFGSjOY9aFIOrYvtHPic/PBugevRUWg4bREcM01kNs/YMZotZL672gc2I5iCYg== X-Received: by 2002:a05:600c:4e05:b0:3db:1d8:9f25 with SMTP id b5-20020a05600c4e0500b003db01d89f25mr43422801wmq.2.1674956116740; Sat, 28 Jan 2023 17:35:16 -0800 (PST) Received: from localhost.localdomain (143.red-83-35-57.dynamicip.rima-tde.net. [83.35.57.143]) by smtp.gmail.com with ESMTPSA id r7-20020a05600c434700b003dc3f195abesm5197132wme.39.2023.01.28.17.35.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 28 Jan 2023 17:35:16 -0800 (PST) From: Angel Iglesias To: linux-iio@vger.kernel.org Cc: Angel Iglesias , Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Andy Shevchenko , Andreas Klinger , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 7/7] iio: pressure: bmp280: Add nvmem operations for BMP580 Date: Sun, 29 Jan 2023 02:33:09 +0100 Message-Id: <013686653a60092227c842ae2fd0197f2509ad7c.1674954271.git.ang.iglesiasg@gmail.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org The pressure sensor BMP580 contains a non-volatile memory that stores trimming and configuration params. That memory provides an programmable user range of three 2-byte words. Signed-off-by: Angel Iglesias diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c index c65fb4025ad9..cc2811c9c6f4 100644 --- a/drivers/iio/pressure/bmp280-core.c +++ b/drivers/iio/pressure/bmp280-core.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -1290,6 +1291,88 @@ static int bmp580_soft_reset(struct bmp280_data *data) return 0; } +#define NVM_READ false +#define NVM_WRITE true + +/** + * bmp580_nvm_operation() - Helper function to commit NVM memory operations + * @data: sensor data struct + * @is_write: flag to signal write operation + */ +static int bmp580_nvm_operation(struct bmp280_data *data, bool is_write) +{ + unsigned long deadline; + unsigned int reg; + int ret; + + /* Check NVM ready flag */ + ret = regmap_read(data->regmap, BMP580_REG_STATUS, ®); + if (ret) { + dev_err(data->dev, "failed to check nvm status\n"); + return ret; + } + if (!(reg & BMP580_STATUS_NVM_RDY_MASK)) { + dev_err(data->dev, "sensor's nvm is not ready\n"); + return -EIO; + } + + /* Send NVM operation sequence */ + ret = regmap_write(data->regmap, BMP580_REG_CMD, BMP580_CMD_NVM_OP_SEQ_0); + if (ret) { + dev_err(data->dev, "failed to send nvm operation's first sequence\n"); + return ret; + } + if (is_write) { + /* Send NVM write sequence */ + ret = regmap_write(data->regmap, BMP580_REG_CMD, + BMP580_CMD_NVM_WRITE_SEQ_1); + if (ret) { + dev_err(data->dev, "failed to send nvm write sequence\n"); + return ret; + } + /* Datasheet says on 4.8.1.2 it takes approximately 10ms */ + usleep_range(10000, 10500); + deadline = jiffies + msecs_to_jiffies(10); + } else { + /* Send NVM read sequence */ + ret = regmap_write(data->regmap, BMP580_REG_CMD, + BMP580_CMD_NVM_READ_SEQ_1); + if (ret) { + dev_err(data->dev, "failed to send nvm read sequence\n"); + return ret; + } + /* Datasheet says on 4.8.1.1 it takes approximately 200us */ + usleep_range(200, 250); + deadline = jiffies + usecs_to_jiffies(200); + } + if (ret) { + dev_err(data->dev, "failed to write command sequence\n"); + return -EIO; + } + + /* Wait until NVM is ready again */ + do { + ret = regmap_read(data->regmap, BMP580_REG_STATUS, ®); + if (ret) { + dev_err(data->dev, "failed to check nvm status\n"); + reg &= ~BMP580_STATUS_NVM_RDY_MASK; + } + } while (time_before(jiffies, deadline) && !(reg & BMP580_STATUS_NVM_RDY_MASK)); + if (!(reg & BMP580_STATUS_NVM_RDY_MASK)) { + dev_err(data->dev, + "reached timeout waiting for nvm operation completion\n"); + return -ETIMEDOUT; + } + + /* Check NVM error flags */ + if ((reg & BMP580_STATUS_NVM_ERR_MASK) || (reg & BMP580_STATUS_NVM_CMD_ERR_MASK)) { + dev_err(data->dev, "error processing nvm operation\n"); + return -EIO; + } + + return 0; +} + /* * Contrary to previous sensors families, compensation algorithm is builtin. * We are only required to read the register raw data and adapt the ranges @@ -1384,8 +1467,140 @@ static const int bmp580_odr_table[][2] = { [BMP580_ODR_0_125HZ] = {0, 125000}, }; +const int bmp580_nvmem_addrs[] = { 0x20, 0x21, 0x22 }; + +static int bmp580_nvmem_read(void *priv, unsigned int offset, void *val, + size_t bytes) +{ + struct bmp280_data *data = priv; + u16 *dst = val; + int ret, addr; + + pm_runtime_get_sync(data->dev); + mutex_lock(&data->lock); + + /* Set sensor in standby mode */ + ret = regmap_update_bits(data->regmap, BMP580_REG_ODR_CONFIG, + BMP580_MODE_MASK | BMP580_ODR_DEEPSLEEP_DIS, + BMP580_ODR_DEEPSLEEP_DIS | + FIELD_PREP(BMP580_MODE_MASK, BMP580_MODE_SLEEP)); + if (ret) { + dev_err(data->dev, "failed to change sensor to standby mode\n"); + goto exit; + } + /* Wait standby transition time */ + usleep_range(2500, 3000); + + while (bytes >= sizeof(u16)) { + addr = bmp580_nvmem_addrs[offset / sizeof(u16)]; + + ret = regmap_write(data->regmap, BMP580_REG_NVM_ADDR, + FIELD_PREP(BMP580_NVM_ROW_ADDR_MASK, addr)); + if (ret) { + dev_err(data->dev, "error writing nvm address\n"); + goto exit; + } + + ret = bmp580_nvm_operation(data, NVM_READ); + if (ret) + goto exit; + + ret = regmap_bulk_read(data->regmap, BMP580_REG_NVM_DATA_LSB, &data->le16, + sizeof(data->le16)); + if (ret) { + dev_err(data->dev, "error reading nvm data regs\n"); + goto exit; + } + + *dst++ = le16_to_cpu(data->le16); + bytes -= sizeof(u16); + offset += sizeof(u16); + } +exit: + /* Restore chip config */ + data->chip_info->chip_config(data); + mutex_unlock(&data->lock); + pm_runtime_mark_last_busy(data->dev); + pm_runtime_put_autosuspend(data->dev); + return ret; +} + +static int bmp580_nvmem_write(void *priv, unsigned int offset, void *val, + size_t bytes) +{ + struct bmp280_data *data = priv; + u16 *buf = val; + int ret, addr; + + pm_runtime_get_sync(data->dev); + mutex_lock(&data->lock); + + /* Set sensor in standby mode */ + ret = regmap_update_bits(data->regmap, BMP580_REG_ODR_CONFIG, + BMP580_MODE_MASK | BMP580_ODR_DEEPSLEEP_DIS, + BMP580_ODR_DEEPSLEEP_DIS | + FIELD_PREP(BMP580_MODE_MASK, BMP580_MODE_SLEEP)); + if (ret) { + dev_err(data->dev, "failed to change sensor to standby mode\n"); + goto exit; + } + /* Wait standby transition time */ + usleep_range(2500, 3000); + + while (bytes >= sizeof(u16)) { + addr = bmp580_nvmem_addrs[offset / sizeof(u16)]; + + ret = regmap_write(data->regmap, BMP580_REG_NVM_ADDR, BMP580_NVM_PROG_EN | + FIELD_PREP(BMP580_NVM_ROW_ADDR_MASK, addr)); + if (ret) { + dev_err(data->dev, "error writing nvm address\n"); + goto exit; + } + data->le16 = cpu_to_le16(*buf++); + + ret = regmap_bulk_write(data->regmap, BMP580_REG_NVM_DATA_LSB, &data->le16, + sizeof(data->le16)); + if (ret) { + dev_err(data->dev, "error writing LSB NVM data regs\n"); + goto exit; + } + + ret = bmp580_nvm_operation(data, NVM_WRITE); + if (ret) + goto exit; + + /* Disable programming mode bit */ + ret = regmap_update_bits(data->regmap, BMP580_REG_NVM_ADDR, + BMP580_NVM_PROG_EN, 0); + if (ret) { + dev_err(data->dev, "error resetting nvm write\n"); + goto exit; + } + + bytes -= sizeof(u16); + offset += sizeof(u16); + } +exit: + /* Restore chip config */ + data->chip_info->chip_config(data); + mutex_unlock(&data->lock); + pm_runtime_mark_last_busy(data->dev); + pm_runtime_put_autosuspend(data->dev); + return ret; +} + static int bmp580_preinit(struct bmp280_data *data) { + struct nvmem_config config = { + .dev = data->dev, + .priv = data, + .name = "bmp580_nvmem", + .word_size = sizeof(u16), + .stride = sizeof(u16), + .size = 3 * sizeof(u16), + .reg_read = bmp580_nvmem_read, + .reg_write = bmp580_nvmem_write, + }; unsigned int reg; int ret; @@ -1413,7 +1628,8 @@ static int bmp580_preinit(struct bmp280_data *data) return -EIO; } - return 0; + /* Register nvmem device */ + return PTR_ERR_OR_ZERO(devm_nvmem_register(config.dev, &config)); } static int bmp580_chip_config(struct bmp280_data *data) diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h index f29d44b09efc..1c942b3dc384 100644 --- a/drivers/iio/pressure/bmp280.h +++ b/drivers/iio/pressure/bmp280.h @@ -104,6 +104,9 @@ #define BMP580_FILTER_63X 6 #define BMP580_FILTER_127X 7 +#define BMP580_NVM_ROW_ADDR_MASK GENMASK(5, 0) +#define BMP580_NVM_PROG_EN BIT(6) + #define BMP580_TEMP_SKIPPED 0x7f7f7f #define BMP580_PRESS_SKIPPED 0x7f7f7f