Re: [PATCH v2 2/2] iio: imu: smi240: imu driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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





[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux