Message ID | 20240215164332.506736-1-vassilisamir@gmail.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel+bounces-67321-ouuuleilei=gmail.com@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:b825:b0:106:860b:bbdd with SMTP id da37csp526046dyb; Thu, 15 Feb 2024 08:44:47 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVuGv0MgqsOz7/8X9a/wTQouqds/KRQcTz+QS97ohnU/Ptrc8k98T8ZLXqVw6X0Ribw8LAbyF4Izjlre9AVmSSam84X3Q== X-Google-Smtp-Source: AGHT+IEp1dbO2sIMHhrjLQgPa+teTVUu/GDdKVBUSikuW84Rz9MfVgh8AienTNDGGi7zHvTNRqeM X-Received: by 2002:aa7:df0c:0:b0:562:1a77:19a7 with SMTP id c12-20020aa7df0c000000b005621a7719a7mr2166707edy.11.1708015487032; Thu, 15 Feb 2024 08:44:47 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708015487; cv=pass; d=google.com; s=arc-20160816; b=aFxVC0A6fzt+N3rdb3bBWnQ9JKHN2AtRE1342ci9Ip2gSxl3tvRO3RCB1goaJwUTWG 7E4sKG/bssk15Kn2oZgL135soVYBtlL0jnF+yP6HbCOKAzcBvze7U+43Dn261IgVJzmk P0PJCtxYbU6QTpLidza3BRW3eFfMXRbBDNKLqGvJH1TNcGAN7ckoqB1rlCLGAD//AA53 whvBCnBf8zn09Oq5D1Lf76rddx0mmVDvMEeegxxZmVqZE2+e9i61Ly6LHzEoYISuxEVD PZTPt74tJyqm87UmUC1S6hpfu+Wn7NO6ZBAsQNWuNdryevONSbxqDBexXYJ7ZrSqzfRe lcnw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:date:subject:cc:to :from:dkim-signature; bh=1TLzx8puHnp9fRr2h2Fsmx/iYsbbA0ajrwZKXLailLc=; fh=os0ann2utgIo9u/ZZPweFpdXeWnSz+bOA71VnlbXazo=; b=KGWJzKGRGVihD5cwHZDdC8O2gxf0vcC6HbZYZeLWdXxQty0bVkJhM2I5gWy5Gq6Ka3 ni2u67nNI0qKfO1mgVPu8pGQ4kMlsHBXxHkYFW82NEvaSrAJnGCPgv4j9FR60VU6U9Lg 2QQx8waAxfiPbYVJnIDTmVk13iV1xlZX1F8U3rjRZxUNqm3Op5Zb0cmVY94AwMas/G+O +CuyKNAF0zPZBtN801gtL2KxK5FoysBz6N/Zbnj3rGHkgGg3MWqkdm7UESdcANKp8DJQ lEw3AJV4pA97Qx+PLnbieJ+bUMS7Z0QzN+L5XaAk3yxSObKZfIcMda7HGjQV7SXjqrFR Pqig==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=FLiVbRHY; arc=pass (i=1 spf=pass spfdomain=gmail.com dkim=pass dkdomain=gmail.com dmarc=pass fromdomain=gmail.com); spf=pass (google.com: domain of linux-kernel+bounces-67321-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-67321-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id n28-20020a056402515c00b005638fa60d3esi752101edd.573.2024.02.15.08.44.46 for <ouuuleilei@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Feb 2024 08:44:47 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-67321-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=FLiVbRHY; arc=pass (i=1 spf=pass spfdomain=gmail.com dkim=pass dkdomain=gmail.com dmarc=pass fromdomain=gmail.com); spf=pass (google.com: domain of linux-kernel+bounces-67321-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-67321-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 78CC21F226D8 for <ouuuleilei@gmail.com>; Thu, 15 Feb 2024 16:44:46 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id EB7D813665B; Thu, 15 Feb 2024 16:44:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="FLiVbRHY" Received: from mail-ej1-f45.google.com (mail-ej1-f45.google.com [209.85.218.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7F18939FFA; Thu, 15 Feb 2024 16:44:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708015472; cv=none; b=lPpzXWqSGHzejYzhEHaXZRjqrfL3kFAOGRWAHLMLhw6TgQ6bIC2OTHeL6KU8gGpIA5xwXfEHt+qIFF9EKMYjseUvDwUVIfytsRj266E1b/629ANCVZ0LhIYInOyVt7pkHNz1aG+6C0aL66dfeSpy62455M1mx7fJcJ/ppsbq8Cs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708015472; c=relaxed/simple; bh=GMzJUKfh0pZFT9mnw2FojixEMfapW3e0QRXrJatKCRE=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=gn4sPmXZ+VJPQzvTPIZ+UiNzSQITKQljxa+UjBXjewdyJ3gL1/FtqfPSJF0LWmJqzcd+1e9oQKSlxpn2srA7SRBr5la8d4ghEBcluCs7LxnTSMBTazZKNrkLe+VYWHeZWhR6lnrN4RfT+8PewLbs/E/MfG1i7kGN24N0JIbHcE4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=FLiVbRHY; arc=none smtp.client-ip=209.85.218.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-ej1-f45.google.com with SMTP id a640c23a62f3a-a3d5e77cfbeso202377066b.0; Thu, 15 Feb 2024 08:44:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1708015469; x=1708620269; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=1TLzx8puHnp9fRr2h2Fsmx/iYsbbA0ajrwZKXLailLc=; b=FLiVbRHY7kTTZRdIOZo/LOYcPZt1+kmUmQSYHev6uut8hZGyhizP6xz5WSSYerZLYK 30H1FbJBqj4PvFsiDud9DFGq81yJhP8mNgI51aj0OW07XVYtRugoQYdL4hshoDNCIAKj uwBvUhR+yn8yLTtaOhYnaiTqsbk7UXvHt50M+ieR64pZRCm+uMcNQxw1PRBkxttixdgE 87/S5cSme5s1MG80hZBWxRceZ9hQyGt8foZi1/1LZsQA/4SUeOEX772Nkg+0jUYCZdCD x3ROLyroXWm8p5KhuyzlWcRzQ2/gadzpO3TkLgEnatN3pqGyNWjfejWNnS2FQzP78zO3 nQAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708015469; x=1708620269; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=1TLzx8puHnp9fRr2h2Fsmx/iYsbbA0ajrwZKXLailLc=; b=JrxpyJNg7JwqrNsdHp3HceSy9e6w5vP0miVePNYh+uXCN5vSm8XVYFT4s9re9KnC9E F5RNCHboLq7k9fimmphkdlYOyJllwS6JrP1lm9CykccQYlike0AjRw3ryyakOLotzZS/ qGPsfek5qtajyR/j7QqyQIyHLzra6UKLHdqg/1DFLxiGl5mfEcKtyOLoQM7XJ01OBIhb toDYd+JigI6YXqN9PxxAqhHxKptM7IQo0CayOxPMoc3Di5CypiBgoJ1Z01UBQVosJSGn 6+D3coOKPE6rcvW6xeNnffmoH2IprOm2RtHcz01y9sjCuJB8fUm+u8uP/t2R//60E3r/ D1KQ== X-Forwarded-Encrypted: i=1; AJvYcCWLONArceth8VuW+8g8uUkAlZVorCTKmWgE2ET4TmVdHfxRmTLSz0F50b/rsB+wAyUyxngkbvnLn3nbKdmDoinkQNb2iqmNGo2OqNwhuLDETSw4X/UPKcupiW3Eh2pz6ISrPNcR+rJR X-Gm-Message-State: AOJu0YxpEVbFfCzutudiMzqdyGag61hPgSX/5dNdRc7m7oPvhvhOWUbN gFzR21Xiae23pzsr78iYO+6p5WofQVb5mV3O7NPh663/HB1ZElUc50ieYqOLM/+LtTjQ X-Received: by 2002:a17:906:c284:b0:a3d:1f59:743d with SMTP id r4-20020a170906c28400b00a3d1f59743dmr4803646ejz.8.1708015468487; Thu, 15 Feb 2024 08:44:28 -0800 (PST) Received: from localhost.localdomain ([2a04:ee41:82:7577:bec0:4907:5147:9931]) by smtp.gmail.com with ESMTPSA id s26-20020a170906a19a00b00a3d636e412bsm727645ejy.123.2024.02.15.08.44.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Feb 2024 08:44:27 -0800 (PST) From: Vasileios Amoiridis <vassilisamir@gmail.com> To: jic23@kernel.org Cc: lars@metafoo.de, ang.iglesiasg@gmail.com, andriy.shevchenko@linux.intel.com, 579lpy@gmail.com, linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, Vasileios Amoiridis <vassilisamir@gmail.com> Subject: [PATCH] drivers: iio: pressure: Add SPI support for BMP38x and BMP390 Date: Thu, 15 Feb 2024 17:43:32 +0100 Message-Id: <20240215164332.506736-1-vassilisamir@gmail.com> X-Mailer: git-send-email 2.25.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: <linux-kernel.vger.kernel.org> List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790984047580217193 X-GMAIL-MSGID: 1790984047580217193 |
Series |
drivers: iio: pressure: Add SPI support for BMP38x and BMP390
|
|
Commit Message
Vasileios Amoiridis
Feb. 15, 2024, 4:43 p.m. UTC
According to the datasheet of BMP38x and BMP390 devices, in SPI
operation, the first byte that returns after a read operation is
garbage and it needs to be dropped and return the rest of the
bytes.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
---
drivers/iio/pressure/bmp280-spi.c | 47 ++++++++++++++++++++++++++++++-
drivers/iio/pressure/bmp280.h | 2 ++
2 files changed, 48 insertions(+), 1 deletion(-)
Comments
On Thu, Feb 15, 2024 at 05:43:32PM +0100, Vasileios Amoiridis wrote: > According to the datasheet of BMP38x and BMP390 devices, in SPI > operation, the first byte that returns after a read operation is > garbage and it needs to be dropped and return the rest of the > bytes. Thank you for the patch, my comments below. .. > +static int bmp380_regmap_spi_read(void *context, const void *reg, > + size_t reg_size, void *val, size_t val_size) > +{ > + struct spi_device *spi = to_spi_device(context); > + u8 ret[BMP380_SPI_MAX_REG_COUNT_READ + 1]; > + ssize_t status; > + u8 buf; AFAIU this buffer is not DMA-capable. > + memcpy(&buf, reg, reg_size); I prefer to see a switch case with cases based on allowed sizes and proper endianess accessors. > + buf |= 0x80; This is done by regmap, no? > + /* > + * According to the BMP380, BMP388, BMP390 datasheets, for a basic > + * read operation, after the write is done, 2 bytes are received and > + * the first one has to be dropped. The 2nd one is the requested > + * value. > + */ > + status = spi_write_then_read(spi, &buf, 1, ret, val_size + 1); sizeof() ? > + if (status) > + return status; > + memcpy(val, ret + 1, val_size); As per above. > + return 0; > +}
On Thu, 2024-02-15 at 17:43 +0100, Vasileios Amoiridis wrote: > According to the datasheet of BMP38x and BMP390 devices, in SPI > operation, the first byte that returns after a read operation is > garbage and it needs to be dropped and return the rest of the > bytes. Hey good catch! It flew past me when I added this devices because I tested only on i2c at the time. Kind regards, Angel > Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com> > --- > drivers/iio/pressure/bmp280-spi.c | 47 ++++++++++++++++++++++++++++++- > drivers/iio/pressure/bmp280.h | 2 ++ > 2 files changed, 48 insertions(+), 1 deletion(-) > > diff --git a/drivers/iio/pressure/bmp280-spi.c b/drivers/iio/pressure/bmp280- > spi.c > index 433d6fac83c4..c4b4a5d67f94 100644 > --- a/drivers/iio/pressure/bmp280-spi.c > +++ b/drivers/iio/pressure/bmp280-spi.c > @@ -35,6 +35,32 @@ static int bmp280_regmap_spi_read(void *context, const void > *reg, > return spi_write_then_read(spi, reg, reg_size, val, val_size); > } > > +static int bmp380_regmap_spi_read(void *context, const void *reg, > + size_t reg_size, void *val, size_t > val_size) > +{ > + struct spi_device *spi = to_spi_device(context); > + u8 ret[BMP380_SPI_MAX_REG_COUNT_READ + 1]; > + ssize_t status; > + u8 buf; > + > + memcpy(&buf, reg, reg_size); > + buf |= 0x80; > + > + /* > + * According to the BMP380, BMP388, BMP390 datasheets, for a basic > + * read operation, after the write is done, 2 bytes are received and > + * the first one has to be dropped. The 2nd one is the requested > + * value. > + */ > + status = spi_write_then_read(spi, &buf, 1, ret, val_size + 1); > + if (status) > + return status; > + > + memcpy(val, ret + 1, val_size); > + > + return 0; > +} > + > static struct regmap_bus bmp280_regmap_bus = { > .write = bmp280_regmap_spi_write, > .read = bmp280_regmap_spi_read, > @@ -42,10 +68,18 @@ static struct regmap_bus bmp280_regmap_bus = { > .val_format_endian_default = REGMAP_ENDIAN_BIG, > }; > > +static struct regmap_bus bmp380_regmap_bus = { > + .write = bmp280_regmap_spi_write, > + .read = bmp380_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); > const struct bmp280_chip_info *chip_info; > + struct regmap_bus *bmp_regmap_bus; > struct regmap *regmap; > int ret; > > @@ -58,8 +92,19 @@ static int bmp280_spi_probe(struct spi_device *spi) > > chip_info = spi_get_device_match_data(spi); > > + switch (chip_info->chip_id[0]) { > + case BMP380_CHIP_ID: > + case BMP390_CHIP_ID: > + bmp_regmap_bus = &bmp380_regmap_bus; > + break; > + default: > + bmp_regmap_bus = &bmp280_regmap_bus; > + break; > + } > + > + > regmap = devm_regmap_init(&spi->dev, > - &bmp280_regmap_bus, > + bmp_regmap_bus, > &spi->dev, > chip_info->regmap_config); > if (IS_ERR(regmap)) { > diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h > index 4012387d7956..ca482b7e4295 100644 > --- a/drivers/iio/pressure/bmp280.h > +++ b/drivers/iio/pressure/bmp280.h > @@ -191,6 +191,8 @@ > #define BMP380_TEMP_SKIPPED 0x800000 > #define BMP380_PRESS_SKIPPED 0x800000 > > +#define BMP380_SPI_MAX_REG_COUNT_READ 3 > + > /* BMP280 specific registers */ > #define BMP280_REG_HUMIDITY_LSB 0xFE > #define BMP280_REG_HUMIDITY_MSB 0xFD
On Thu, 15 Feb 2024 19:03:27 +0200 Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote: > On Thu, Feb 15, 2024 at 05:43:32PM +0100, Vasileios Amoiridis wrote: > > According to the datasheet of BMP38x and BMP390 devices, in SPI > > operation, the first byte that returns after a read operation is > > garbage and it needs to be dropped and return the rest of the > > bytes. > > Thank you for the patch, my comments below. > > ... > > > +static int bmp380_regmap_spi_read(void *context, const void *reg, > > + size_t reg_size, void *val, size_t val_size) > > +{ > > + struct spi_device *spi = to_spi_device(context); > > + u8 ret[BMP380_SPI_MAX_REG_COUNT_READ + 1]; > > + ssize_t status; > > + u8 buf; > > AFAIU this buffer is not DMA-capable. Doesn't matter in this case as spi_write_then_read() bounces anyway so you don't need to provide it with a dma safe buffer. It's in the docs, so we can rely on this not changing. https://elixir.bootlin.com/linux/latest/source/drivers/spi/spi.c#L4391
On Thu, 15 Feb 2024 17:43:32 +0100 Vasileios Amoiridis <vassilisamir@gmail.com> wrote: > According to the datasheet of BMP38x and BMP390 devices, in SPI > operation, the first byte that returns after a read operation is > garbage and it needs to be dropped and return the rest of the > bytes. Make it clear in the patch title that this is a fix and add a fixes tag. > > Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com> > --- > drivers/iio/pressure/bmp280-spi.c | 47 ++++++++++++++++++++++++++++++- > drivers/iio/pressure/bmp280.h | 2 ++ > 2 files changed, 48 insertions(+), 1 deletion(-) > > diff --git a/drivers/iio/pressure/bmp280-spi.c b/drivers/iio/pressure/bmp280-spi.c > index 433d6fac83c4..c4b4a5d67f94 100644 > --- a/drivers/iio/pressure/bmp280-spi.c > +++ b/drivers/iio/pressure/bmp280-spi.c > @@ -35,6 +35,32 @@ static int bmp280_regmap_spi_read(void *context, const void *reg, > return spi_write_then_read(spi, reg, reg_size, val, val_size); > } > > +static int bmp380_regmap_spi_read(void *context, const void *reg, > + size_t reg_size, void *val, size_t val_size) > +{ > + struct spi_device *spi = to_spi_device(context); > + u8 ret[BMP380_SPI_MAX_REG_COUNT_READ + 1]; Given you rely on val_size < 3 you should check for that explcitly rather than potentially overflowing the buffer. ret is not a good naming choice for this variable as it's commonly used for integer return values. Call it read_buf or something like that. > + ssize_t status; > + u8 buf; > + > + memcpy(&buf, reg, reg_size); > + buf |= 0x80; Can you use regmap_bus read_flag_mask for this? Seems to apply to all devices supported. + that's common for spi regmaps Mind you I note the bmp280_regmap_spi_write() is masking the bit out which seems backwards - all the registers are defined with the bit set for that part but not the 380. Ah well - not part of this fix even if it's odd. > + > + /* > + * According to the BMP380, BMP388, BMP390 datasheets, for a basic > + * read operation, after the write is done, 2 bytes are received and > + * the first one has to be dropped. The 2nd one is the requested > + * value. > + */ > + status = spi_write_then_read(spi, &buf, 1, ret, val_size + 1); > + if (status) > + return status; > + > + memcpy(val, ret + 1, val_size); > + > + return 0; > +} > + > static struct regmap_bus bmp280_regmap_bus = { > .write = bmp280_regmap_spi_write, > .read = bmp280_regmap_spi_read, > @@ -42,10 +68,18 @@ static struct regmap_bus bmp280_regmap_bus = { > .val_format_endian_default = REGMAP_ENDIAN_BIG, > }; > > +static struct regmap_bus bmp380_regmap_bus = { > + .write = bmp280_regmap_spi_write, > + .read = bmp380_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); > const struct bmp280_chip_info *chip_info; > + struct regmap_bus *bmp_regmap_bus; > struct regmap *regmap; > int ret; > > @@ -58,8 +92,19 @@ static int bmp280_spi_probe(struct spi_device *spi) > > chip_info = spi_get_device_match_data(spi); > > + switch (chip_info->chip_id[0]) { > + case BMP380_CHIP_ID: > + case BMP390_CHIP_ID: > + bmp_regmap_bus = &bmp380_regmap_bus; > + break; > + default: > + bmp_regmap_bus = &bmp280_regmap_bus; > + break; > + } > + > + > regmap = devm_regmap_init(&spi->dev, > - &bmp280_regmap_bus, > + bmp_regmap_bus, > &spi->dev, > chip_info->regmap_config); > if (IS_ERR(regmap)) { > diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h > index 4012387d7956..ca482b7e4295 100644 > --- a/drivers/iio/pressure/bmp280.h > +++ b/drivers/iio/pressure/bmp280.h > @@ -191,6 +191,8 @@ > #define BMP380_TEMP_SKIPPED 0x800000 > #define BMP380_PRESS_SKIPPED 0x800000 > > +#define BMP380_SPI_MAX_REG_COUNT_READ 3 This doesn't seem useful as only used in one place. > + > /* BMP280 specific registers */ > #define BMP280_REG_HUMIDITY_LSB 0xFE > #define BMP280_REG_HUMIDITY_MSB 0xFD
On Fri, Feb 16, 2024 at 11:18:34AM +0000, Jonathan Cameron wrote: > On Thu, 15 Feb 2024 17:43:32 +0100 > Vasileios Amoiridis <vassilisamir@gmail.com> wrote: > > > According to the datasheet of BMP38x and BMP390 devices, in SPI > > operation, the first byte that returns after a read operation is > > garbage and it needs to be dropped and return the rest of the > > bytes. > > Make it clear in the patch title that this is a fix and add a fixes tag. > The original support for SPI was added 8 years ago. Should I include that commit of 8 years ago in the fixes tag or just use a the word "fixes" with the rest of the title? > > > > Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com> > > --- > > drivers/iio/pressure/bmp280-spi.c | 47 ++++++++++++++++++++++++++++++- > > drivers/iio/pressure/bmp280.h | 2 ++ > > 2 files changed, 48 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/iio/pressure/bmp280-spi.c b/drivers/iio/pressure/bmp280-spi.c > > index 433d6fac83c4..c4b4a5d67f94 100644 > > --- a/drivers/iio/pressure/bmp280-spi.c > > +++ b/drivers/iio/pressure/bmp280-spi.c > > @@ -35,6 +35,32 @@ static int bmp280_regmap_spi_read(void *context, const void *reg, > > return spi_write_then_read(spi, reg, reg_size, val, val_size); > > } > > > > +static int bmp380_regmap_spi_read(void *context, const void *reg, > > + size_t reg_size, void *val, size_t val_size) > > +{ > > + struct spi_device *spi = to_spi_device(context); > > + u8 ret[BMP380_SPI_MAX_REG_COUNT_READ + 1]; > > Given you rely on val_size < 3 you should check for that explcitly rather than > potentially overflowing the buffer. > ret is not a good naming choice for this variable as it's commonly used for > integer return values. Call it read_buf or something like that. > Thanks for pointing this out it makes a lot of sense. > > + ssize_t status; > > + u8 buf; > > + > > + memcpy(&buf, reg, reg_size); > > + buf |= 0x80; > > Can you use regmap_bus read_flag_mask for this? Seems to apply to > all devices supported. + that's common for spi regmaps > Yes I noticed it yesterday in my tests that this was missing and it actually applies to all the devices. So the read_flag_mask should be added to both regmap_bus structs. > > Mind you I note the bmp280_regmap_spi_write() is masking the bit out which seems > backwards - all the registers are defined with the bit set for that part > but not the 380. Ah well - not part of this fix even if it's odd. > > > > + > > + /* > > + * According to the BMP380, BMP388, BMP390 datasheets, for a basic > > + * read operation, after the write is done, 2 bytes are received and > > + * the first one has to be dropped. The 2nd one is the requested > > + * value. > > + */ > > + status = spi_write_then_read(spi, &buf, 1, ret, val_size + 1); > > + if (status) > > + return status; > > + > > + memcpy(val, ret + 1, val_size); > > + > > + return 0; > > +} > > + > > static struct regmap_bus bmp280_regmap_bus = { > > .write = bmp280_regmap_spi_write, > > .read = bmp280_regmap_spi_read, > > @@ -42,10 +68,18 @@ static struct regmap_bus bmp280_regmap_bus = { > > .val_format_endian_default = REGMAP_ENDIAN_BIG, > > }; > > > > +static struct regmap_bus bmp380_regmap_bus = { > > + .write = bmp280_regmap_spi_write, > > + .read = bmp380_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); > > const struct bmp280_chip_info *chip_info; > > + struct regmap_bus *bmp_regmap_bus; > > struct regmap *regmap; > > int ret; > > > > @@ -58,8 +92,19 @@ static int bmp280_spi_probe(struct spi_device *spi) > > > > chip_info = spi_get_device_match_data(spi); > > > > + switch (chip_info->chip_id[0]) { > > + case BMP380_CHIP_ID: > > + case BMP390_CHIP_ID: > > + bmp_regmap_bus = &bmp380_regmap_bus; > > + break; > > + default: > > + bmp_regmap_bus = &bmp280_regmap_bus; > > + break; > > + } > > + > > + > > regmap = devm_regmap_init(&spi->dev, > > - &bmp280_regmap_bus, > > + bmp_regmap_bus, > > &spi->dev, > > chip_info->regmap_config); > > if (IS_ERR(regmap)) { > > diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h > > index 4012387d7956..ca482b7e4295 100644 > > --- a/drivers/iio/pressure/bmp280.h > > +++ b/drivers/iio/pressure/bmp280.h > > @@ -191,6 +191,8 @@ > > #define BMP380_TEMP_SKIPPED 0x800000 > > #define BMP380_PRESS_SKIPPED 0x800000 > > > > +#define BMP380_SPI_MAX_REG_COUNT_READ 3 > This doesn't seem useful as only used in one place. Could this define be moved in the bmp280-spi.c file or to not even use a define? > > + > > /* BMP280 specific registers */ > > #define BMP280_REG_HUMIDITY_LSB 0xFE > > #define BMP280_REG_HUMIDITY_MSB 0xFD >
On Fri, Feb 16, 2024 at 11:05:43AM +0000, Jonathan Cameron wrote: > On Thu, 15 Feb 2024 19:03:27 +0200 > Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote: > > > On Thu, Feb 15, 2024 at 05:43:32PM +0100, Vasileios Amoiridis wrote: > > > According to the datasheet of BMP38x and BMP390 devices, in SPI > > > operation, the first byte that returns after a read operation is > > > garbage and it needs to be dropped and return the rest of the > > > bytes. > > > > Thank you for the patch, my comments below. > > > > ... > > > > > +static int bmp380_regmap_spi_read(void *context, const void *reg, > > > + size_t reg_size, void *val, size_t val_size) > > > +{ > > > + struct spi_device *spi = to_spi_device(context); > > > + u8 ret[BMP380_SPI_MAX_REG_COUNT_READ + 1]; > > > + ssize_t status; > > > + u8 buf; > > > > AFAIU this buffer is not DMA-capable. > > Doesn't matter in this case as spi_write_then_read() bounces anyway so you don't need > to provide it with a dma safe buffer. It's in the docs, so we can rely > on this not changing. > > https://elixir.bootlin.com/linux/latest/source/drivers/spi/spi.c#L4391 > Since the read_flag_mask can be used in the struct regmap_bus, there is no need for an extra u8 buffer to manipulate the bits. Instead, the reg value from the function inputs can be used as in any other case.
On Fri, 16 Feb 2024 14:26:44 +0100 Vasileios Amoiridis <vassilisamir@gmail.com> wrote: > On Fri, Feb 16, 2024 at 11:18:34AM +0000, Jonathan Cameron wrote: > > On Thu, 15 Feb 2024 17:43:32 +0100 > > Vasileios Amoiridis <vassilisamir@gmail.com> wrote: > > > > > According to the datasheet of BMP38x and BMP390 devices, in SPI > > > operation, the first byte that returns after a read operation is > > > garbage and it needs to be dropped and return the rest of the > > > bytes. > > > > Make it clear in the patch title that this is a fix and add a fixes tag. > > > > The original support for SPI was added 8 years ago. Should I include that commit > of 8 years ago in the fixes tag or just use a the word "fixes" with the rest of the > title? > Original git commit for the fixes tag. Lets us know this wants to go in all stable kernels. Also fixes in the title. > > > + ssize_t status; > > > + u8 buf; > > > + > > > + memcpy(&buf, reg, reg_size); > > > + buf |= 0x80; > > > > Can you use regmap_bus read_flag_mask for this? Seems to apply to > > all devices supported. + that's common for spi regmaps > > > > Yes I noticed it yesterday in my tests that this was missing and it actually > applies to all the devices. So the read_flag_mask should be added to both > regmap_bus structs. It's there sort of indirectly for the bmp280 - the register addresses all happen to include that bit, then it is cleared explicitly for the other direction. > > > > Mind you I note the bmp280_regmap_spi_write() is masking the bit out which seems > > backwards - all the registers are defined with the bit set for that part > > but not the 380. Ah well - not part of this fix even if it's odd. > > > > > diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h > > > index 4012387d7956..ca482b7e4295 100644 > > > --- a/drivers/iio/pressure/bmp280.h > > > +++ b/drivers/iio/pressure/bmp280.h > > > @@ -191,6 +191,8 @@ > > > #define BMP380_TEMP_SKIPPED 0x800000 > > > #define BMP380_PRESS_SKIPPED 0x800000 > > > > > > +#define BMP380_SPI_MAX_REG_COUNT_READ 3 > > This doesn't seem useful as only used in one place. > > Could this define be moved in the bmp280-spi.c file or to not even use a define? Not use it. Don't see how it is helpful. Just check that the thing will fit in the array using an ARRAY_SIZE()... > > > > + > > > /* BMP280 specific registers */ > > > #define BMP280_REG_HUMIDITY_LSB 0xFE > > > #define BMP280_REG_HUMIDITY_MSB 0xFD > >
On Fri, Feb 16, 2024 at 03:47:42PM +0000, Jonathan Cameron wrote: > On Fri, 16 Feb 2024 14:26:44 +0100 > Vasileios Amoiridis <vassilisamir@gmail.com> wrote: > > > On Fri, Feb 16, 2024 at 11:18:34AM +0000, Jonathan Cameron wrote: > > > On Thu, 15 Feb 2024 17:43:32 +0100 > > > Vasileios Amoiridis <vassilisamir@gmail.com> wrote: > > > > > > > According to the datasheet of BMP38x and BMP390 devices, in SPI > > > > operation, the first byte that returns after a read operation is > > > > garbage and it needs to be dropped and return the rest of the > > > > bytes. > > > > > > Make it clear in the patch title that this is a fix and add a fixes tag. > > > > > > > The original support for SPI was added 8 years ago. Should I include that commit > > of 8 years ago in the fixes tag or just use a the word "fixes" with the rest of the > > title? > > > Original git commit for the fixes tag. Lets us know this wants to go in all stable kernels. > Also fixes in the title. Ok, will do that! > > > > > > + ssize_t status; > > > > + u8 buf; > > > > + > > > > + memcpy(&buf, reg, reg_size); > > > > + buf |= 0x80; > > > > > > Can you use regmap_bus read_flag_mask for this? Seems to apply to > > > all devices supported. + that's common for spi regmaps > > > > > > > Yes I noticed it yesterday in my tests that this was missing and it actually > > applies to all the devices. So the read_flag_mask should be added to both > > regmap_bus structs. > > It's there sort of indirectly for the bmp280 - the register addresses all happen > to include that bit, then it is cleared explicitly for the other direction. Oh okay, now I understand what you mean. Ok then I can also send a different patch for this as well just to keep the code consistent. > > > > > > > > > Mind you I note the bmp280_regmap_spi_write() is masking the bit out which seems > > > backwards - all the registers are defined with the bit set for that part > > > but not the 380. Ah well - not part of this fix even if it's odd. > > > > > > > > diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h > > > > index 4012387d7956..ca482b7e4295 100644 > > > > --- a/drivers/iio/pressure/bmp280.h > > > > +++ b/drivers/iio/pressure/bmp280.h > > > > @@ -191,6 +191,8 @@ > > > > #define BMP380_TEMP_SKIPPED 0x800000 > > > > #define BMP380_PRESS_SKIPPED 0x800000 > > > > > > > > +#define BMP380_SPI_MAX_REG_COUNT_READ 3 > > > This doesn't seem useful as only used in one place. > > > > Could this define be moved in the bmp280-spi.c file or to not even use a define? > Not use it. Don't see how it is helpful. Just check that the > thing will fit in the array using an ARRAY_SIZE()... Understood. > > > > > > + > > > > /* BMP280 specific registers */ > > > > #define BMP280_REG_HUMIDITY_LSB 0xFE > > > > #define BMP280_REG_HUMIDITY_MSB 0xFD > > > > Thank you very much for the feedback, I'll work on the patches and submit them again. Best regards, Vasileios Amoiridis
diff --git a/drivers/iio/pressure/bmp280-spi.c b/drivers/iio/pressure/bmp280-spi.c index 433d6fac83c4..c4b4a5d67f94 100644 --- a/drivers/iio/pressure/bmp280-spi.c +++ b/drivers/iio/pressure/bmp280-spi.c @@ -35,6 +35,32 @@ static int bmp280_regmap_spi_read(void *context, const void *reg, return spi_write_then_read(spi, reg, reg_size, val, val_size); } +static int bmp380_regmap_spi_read(void *context, const void *reg, + size_t reg_size, void *val, size_t val_size) +{ + struct spi_device *spi = to_spi_device(context); + u8 ret[BMP380_SPI_MAX_REG_COUNT_READ + 1]; + ssize_t status; + u8 buf; + + memcpy(&buf, reg, reg_size); + buf |= 0x80; + + /* + * According to the BMP380, BMP388, BMP390 datasheets, for a basic + * read operation, after the write is done, 2 bytes are received and + * the first one has to be dropped. The 2nd one is the requested + * value. + */ + status = spi_write_then_read(spi, &buf, 1, ret, val_size + 1); + if (status) + return status; + + memcpy(val, ret + 1, val_size); + + return 0; +} + static struct regmap_bus bmp280_regmap_bus = { .write = bmp280_regmap_spi_write, .read = bmp280_regmap_spi_read, @@ -42,10 +68,18 @@ static struct regmap_bus bmp280_regmap_bus = { .val_format_endian_default = REGMAP_ENDIAN_BIG, }; +static struct regmap_bus bmp380_regmap_bus = { + .write = bmp280_regmap_spi_write, + .read = bmp380_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); const struct bmp280_chip_info *chip_info; + struct regmap_bus *bmp_regmap_bus; struct regmap *regmap; int ret; @@ -58,8 +92,19 @@ static int bmp280_spi_probe(struct spi_device *spi) chip_info = spi_get_device_match_data(spi); + switch (chip_info->chip_id[0]) { + case BMP380_CHIP_ID: + case BMP390_CHIP_ID: + bmp_regmap_bus = &bmp380_regmap_bus; + break; + default: + bmp_regmap_bus = &bmp280_regmap_bus; + break; + } + + regmap = devm_regmap_init(&spi->dev, - &bmp280_regmap_bus, + bmp_regmap_bus, &spi->dev, chip_info->regmap_config); if (IS_ERR(regmap)) { diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h index 4012387d7956..ca482b7e4295 100644 --- a/drivers/iio/pressure/bmp280.h +++ b/drivers/iio/pressure/bmp280.h @@ -191,6 +191,8 @@ #define BMP380_TEMP_SKIPPED 0x800000 #define BMP380_PRESS_SKIPPED 0x800000 +#define BMP380_SPI_MAX_REG_COUNT_READ 3 + /* BMP280 specific registers */ #define BMP280_REG_HUMIDITY_LSB 0xFE #define BMP280_REG_HUMIDITY_MSB 0xFD