On 09/08/2024 13:16, Jianping.Shen@xxxxxxxxxxxx wrote: > From: "Shen Jianping (ME-SE/EAD2)" <Jianping.Shen@xxxxxxxxxxxx> > > iio: imu: smi240: driver improvements ????? > Signed-off-by: Shen Jianping (ME-SE/EAD2) <Jianping.Shen@xxxxxxxxxxxx> > --- > ... > + 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@xxxxxxxxxxxx>"); > +MODULE_AUTHOR("Stefan Gutmann <stefan.gutmann@xxxxxxxxxxxx>"); > +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