FILE
smi330_i2c.c
File preview with syntax highlighting.
linux-6.19.14/drivers/iio/imu/smi330/smi330_i2c.c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2/* 3 * Copyright (c) 2025 Robert Bosch GmbH. 4 */ 5#include <linux/i2c.h> 6#include <linux/mod_devicetable.h> 7#include <linux/module.h> 8#include <linux/regmap.h> 9 10#include "smi330.h" 11 12#define SMI330_NUM_DUMMY_BYTES 2 13#define SMI330_I2C_MAX_RX_BUFFER_SIZE \ 14 (SMI330_NUM_DUMMY_BYTES + SMI330_SCAN_LEN * sizeof(s16)) 15 16struct smi330_i2c_priv { 17 struct i2c_client *i2c; 18 u8 rx_buffer[SMI330_I2C_MAX_RX_BUFFER_SIZE]; 19}; 20 21static int smi330_regmap_i2c_read(void *context, const void *reg_buf, 22 size_t reg_size, void *val_buf, 23 size_t val_size) 24{ 25 struct smi330_i2c_priv *priv = context; 26 int ret; 27 28 if (SMI330_NUM_DUMMY_BYTES + val_size > SMI330_I2C_MAX_RX_BUFFER_SIZE) 29 return -EINVAL; 30 31 /* 32 * SMI330 I2C read frame: 33 * <Slave address[6:0], RnW> <x, Register address[6:0]> 34 * <Slave address[6:0], RnW> <Dummy[7:0]> <Dummy[7:0]> <Data_0[7:0]> <Data_1[15:8]>... 35 * <Data_N[7:0]> <Data_N[15:8]> 36 * Remark: Slave address is not considered part of the frame in the following definitions 37 */ 38 struct i2c_msg msgs[] = { 39 { 40 .addr = priv->i2c->addr, 41 .flags = priv->i2c->flags, 42 .len = reg_size, 43 .buf = (u8 *)reg_buf, 44 }, 45 { 46 .addr = priv->i2c->addr, 47 .flags = priv->i2c->flags | I2C_M_RD, 48 .len = SMI330_NUM_DUMMY_BYTES + val_size, 49 .buf = priv->rx_buffer, 50 }, 51 }; 52 53 ret = i2c_transfer(priv->i2c->adapter, msgs, ARRAY_SIZE(msgs)); 54 if (ret < 0) 55 return ret; 56 57 memcpy(val_buf, priv->rx_buffer + SMI330_NUM_DUMMY_BYTES, val_size); 58 59 return 0; 60} 61 62static int smi330_regmap_i2c_write(void *context, const void *data, 63 size_t count) 64{ 65 struct smi330_i2c_priv *priv = context; 66 u8 reg; 67 68 /* 69 * SMI330 I2C write frame: 70 * <Slave address[6:0], RnW> <x, Register address[6:0]> <Data_0[7:0]> <Data_1[15:8]>... 71 * <Data_N[7:0]> <Data_N[15:8]> 72 * Remark: Slave address is not considered part of the frame in the following definitions 73 */ 74 reg = *(u8 *)data; 75 return i2c_smbus_write_i2c_block_data(priv->i2c, reg, 76 count - sizeof(u8), 77 data + sizeof(u8)); 78} 79 80static const struct regmap_bus smi330_regmap_bus = { 81 .read = smi330_regmap_i2c_read, 82 .write = smi330_regmap_i2c_write, 83}; 84 85static int smi330_i2c_probe(struct i2c_client *i2c) 86{ 87 struct device *dev = &i2c->dev; 88 struct smi330_i2c_priv *priv; 89 struct regmap *regmap; 90 91 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 92 if (!priv) 93 return -ENOMEM; 94 95 priv->i2c = i2c; 96 regmap = devm_regmap_init(dev, &smi330_regmap_bus, priv, 97 &smi330_regmap_config); 98 if (IS_ERR(regmap)) 99 return dev_err_probe(dev, PTR_ERR(regmap), 100 "Failed to initialize I2C Regmap\n"); 101 102 return smi330_core_probe(dev, regmap); 103} 104 105static const struct i2c_device_id smi330_i2c_device_id[] = { 106 { .name = "smi330" }, 107 { } 108}; 109MODULE_DEVICE_TABLE(i2c, smi330_i2c_device_id); 110 111static const struct of_device_id smi330_of_match[] = { 112 { .compatible = "bosch,smi330" }, 113 { } 114}; 115MODULE_DEVICE_TABLE(of, smi330_of_match); 116 117static struct i2c_driver smi330_i2c_driver = { 118 .probe = smi330_i2c_probe, 119 .id_table = smi330_i2c_device_id, 120 .driver = { 121 .of_match_table = smi330_of_match, 122 .name = "smi330_i2c", 123 }, 124}; 125module_i2c_driver(smi330_i2c_driver); 126 127MODULE_AUTHOR("Stefan Gutmann <stefan.gutmann@de.bosch.com>"); 128MODULE_AUTHOR("Roman Huber <roman.huber@de.bosch.com>"); 129MODULE_AUTHOR("Filip Andrei <Andrei.Filip@ro.bosch.com>"); 130MODULE_AUTHOR("Drimbarean Avram Andrei <Avram-Andrei.Drimbarean@ro.bosch.com>"); 131MODULE_DESCRIPTION("Bosch SMI330 I2C driver"); 132MODULE_LICENSE("Dual BSD/GPL"); 133MODULE_IMPORT_NS("IIO_SMI330");
~/
Read-only file preview.