[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <561b467a-58aa-471c-8ea6-cd6ef927c287@kernel.org>
Date: Sat, 10 Aug 2024 14:44:21 +0200
From: Krzysztof Kozlowski <krzk@...nel.org>
To: Jianping.Shen@...bosch.com, jic23@...nel.org, lars@...afoo.de,
robh@...nel.org, krzk+dt@...nel.org, conor+dt@...nel.org,
dima.fedrau@...il.com, marcelo.schmitt1@...il.com,
linux-iio@...r.kernel.org, devicetree@...r.kernel.org,
linux-kernel@...r.kernel.org, Christian.Lorenz3@...bosch.com,
Ulrike.Frauendorf@...bosch.com, Kai.Dolde@...bosch.com
Subject: Re: [PATCH v2 2/2] iio: imu: smi240: imu driver
On 09/08/2024 13:16, Jianping.Shen@...bosch.com wrote:
> From: "Shen Jianping (ME-SE/EAD2)" <Jianping.Shen@...bosch.com>
>
> iio: imu: smi240: driver improvements
?????
> Signed-off-by: Shen Jianping (ME-SE/EAD2) <Jianping.Shen@...bosch.com>
> ---
>
...
> + ret = regmap_read(data->regmap, SMI240_CHIP_ID_REG, &response);
> + if (ret)
> + return dev_err_probe(dev, ret, "Read chip id failed\n");
> +
> + if (response != SMI240_CHIP_ID)
> + dev_info(dev, "Unknown chip id: 0x%04x\n", response);
> +
> + ret = smi240_init(data);
> + if (ret)
> + return dev_err_probe(dev, ret,
> + "Device initialization failed\n");
> +
> + indio_dev->channels = smi240_channels;
> + indio_dev->num_channels = ARRAY_SIZE(smi240_channels);
> + indio_dev->name = "smi240";
> + indio_dev->modes = INDIO_DIRECT_MODE;
> + indio_dev->info = &smi240_info;
> +
> + ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
> + iio_pollfunc_store_time,
> + smi240_trigger_handler, NULL);
> + if (ret)
> + return dev_err_probe(dev, ret,
> + "Setup triggered buffer failed\n");
> +
> + ret = devm_iio_device_register(dev, indio_dev);
> + if (ret)
> + return dev_err_probe(dev, ret, "Register IIO device failed\n");
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(smi240_core_probe);
> +
> +MODULE_AUTHOR("Markus Lochmann <markus.lochmann@...bosch.com>");
> +MODULE_AUTHOR("Stefan Gutmann <stefan.gutmann@...bosch.com>");
> +MODULE_DESCRIPTION("Bosch SMI240 driver");
> +MODULE_LICENSE("Dual BSD/GPL");
Hm? How many modules do you have here? What are their names?
> diff --git a/drivers/iio/imu/smi240/smi240_spi.c b/drivers/iio/imu/smi240/smi240_spi.c
> new file mode 100644
> index 00000000000..ac9e37ffa37
> --- /dev/null
> +++ b/drivers/iio/imu/smi240/smi240_spi.c
> @@ -0,0 +1,173 @@
> +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
> +/*
> + * Copyright (c) 2024 Robert Bosch GmbH.
> + *
> + */
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/regmap.h>
> +#include <linux/spi/spi.h>
> +#include <linux/bitfield.h>
> +#include <linux/iio/iio.h>
> +
> +#include "smi240.h"
> +
> +#define SMI240_CRC_INIT 0x05
> +#define SMI240_CRC_POLY 0x0B
> +#define SMI240_BUS_ID 0x00
> +
> +#define SMI240_SD_BIT_MASK 0x80000000
> +#define SMI240_CS_BIT_MASK 0x00000008
> +
> +#define SMI240_WRITE_ADDR_MASK GENMASK(29, 22)
> +#define SMI240_WRITE_BIT_MASK 0x00200000
> +#define SMI240_WRITE_DATA_MASK GENMASK(18, 3)
> +#define SMI240_CAP_BIT_MASK 0x00100000
> +#define SMI240_READ_DATA_MASK GENMASK(19, 4)
> +
> +static u8 smi240_crc3(u32 data, u8 init, u8 poly)
> +{
> + u8 crc = init;
> + u8 do_xor;
> + s8 i = 31;
> +
> + do {
> + do_xor = crc & 0x04;
> + crc <<= 1;
> + crc |= 0x01 & (data >> i);
> + if (do_xor)
> + crc ^= poly;
> +
> + crc &= 0x07;
> + } while (--i >= 0);
> +
> + return crc;
> +}
> +
> +static bool smi240_sensor_data_is_valid(u32 data)
> +{
> + if (smi240_crc3(data, SMI240_CRC_INIT, SMI240_CRC_POLY) != 0)
> + return false;
> +
> + if (FIELD_GET(SMI240_SD_BIT_MASK, data) &
> + FIELD_GET(SMI240_CS_BIT_MASK, data))
> + return false;
> +
> + return true;
> +}
> +
> +static int smi240_regmap_spi_read(void *context, const void *reg_buf,
> + size_t reg_size, void *val_buf,
> + size_t val_size)
> +{
> + int ret;
> + __be32 request, response;
> + struct spi_device *spi = context;
> + struct iio_dev *indio_dev = dev_get_drvdata(&spi->dev);
> + struct smi240_data *data = iio_priv(indio_dev);
> +
> + request = SMI240_BUS_ID << 30;
> + request |= FIELD_PREP(SMI240_CAP_BIT_MASK, data->capture);
> + request |= FIELD_PREP(SMI240_WRITE_ADDR_MASK, *(u8 *)reg_buf);
> + request |= smi240_crc3(request, SMI240_CRC_INIT, SMI240_CRC_POLY);
> + request = cpu_to_be32(request);
> +
> + /*
> + * SMI240 module consists of a 32Bit Out Of Frame (OOF)
> + * SPI protocol, where the slave interface responds to
> + * the Master request in the next frame.
> + * CS signal must toggle (> 700 ns) between the frames.
> + */
> + ret = spi_write(spi, &request, sizeof(request));
> + if (ret)
> + return ret;
> +
> + ret = spi_read(spi, &response, sizeof(response));
> + if (ret)
> + return ret;
> +
> + response = be32_to_cpu(response);
> +
> + if (!smi240_sensor_data_is_valid(response))
> + return -EIO;
> +
> + response = FIELD_GET(SMI240_READ_DATA_MASK, response);
> + memcpy(val_buf, &response, val_size);
> +
> + return 0;
> +}
> +
> +static int smi240_regmap_spi_write(void *context, const void *data,
> + size_t count)
> +{
> + __be32 request;
> + struct spi_device *spi = context;
> + u8 reg_addr = ((u8 *)data)[0];
> + u16 reg_data = ((u8 *)data)[2] << 8 | ((u8 *)data)[1];
> +
> + request = SMI240_BUS_ID << 30;
> + request |= FIELD_PREP(SMI240_WRITE_BIT_MASK, 1);
> + request |= FIELD_PREP(SMI240_WRITE_ADDR_MASK, reg_addr);
> + request |= FIELD_PREP(SMI240_WRITE_DATA_MASK, reg_data);
> + request |= smi240_crc3(request, SMI240_CRC_INIT, SMI240_CRC_POLY);
> + request = cpu_to_be32(request);
> +
> + return spi_write(spi, &request, sizeof(request));
> +}
> +
> +static struct regmap_bus smi240_regmap_bus = {
Not const?
> + .read = smi240_regmap_spi_read,
> + .write = smi240_regmap_spi_write,
> +};
> +
> +static const struct regmap_config smi240_regmap_config = {
> + .reg_bits = 8,
> + .val_bits = 16,
> + .val_format_endian = REGMAP_ENDIAN_LITTLE,
> +};
> +
> +static int smi240_spi_probe(struct spi_device *spi)
> +{
> + struct regmap *regmap;
> +
> + u32 max_frequency = 10000000;
> +
> + of_property_read_u32(spi->dev.of_node, "spi-max-frequency",
> + &max_frequency);
Why?
> +
> + spi->bits_per_word = 8;
That's default.
> + spi->max_speed_hz = max_frequency;
Why? Core does it.
> + spi->mode = SPI_MODE_0;
I really wonder why you need all this code...
> +
> + regmap = devm_regmap_init(&spi->dev, &smi240_regmap_bus, &spi->dev,
> + &smi240_regmap_config);
> + if (IS_ERR(regmap))
> + return dev_err_probe(&spi->dev, PTR_ERR(regmap),
> + "Failed to initialize SPI Regmap\n");
> +
> + return smi240_core_probe(&spi->dev, regmap);
> +}
> +
> +static const struct spi_device_id smi240_spi_id[] = { { "smi240", 0 }, {} };
Don't wrap it.
> +MODULE_DEVICE_TABLE(spi, smi240_spi_id);
> +
> +static const struct of_device_id smi240_of_match[] = {
> + { .compatible = "bosch,smi240" },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, smi240_of_match);
> +
> +static struct spi_driver smi240_spi_driver = {
> + .probe = smi240_spi_probe,
> + .id_table = smi240_spi_id,
> + .driver = {
> + .of_match_table = of_match_ptr(smi240_of_match),
Why did it appear? You introduce now warnings.
Best regards,
Krzysztof
Powered by blists - more mailing lists