drivers:iio:stm:accel:st_lis2dw12: replace i2c/spi interfaces with regmap

Some drivers like lis2dw12 have not yet benefited from regmap
support which unifies and simplifies access to the communication
interfaces with devices and already implements all the transport
synchronization and optimization mechanisms internally.
This patch add support of regmap api to lis2dw12 and compatible
devices.

Signed-off-by: mariotesi <mario.tesi@st.com>
Change-Id: I412e8a0e27636e3b49f747b5f6cb4e64ee3d0269
This commit is contained in:
mariotesi 2023-11-21 10:32:42 +01:00
parent a4d9103148
commit efe8afbe40
No known key found for this signature in database
GPG Key ID: 0B6EF815710A402D
5 changed files with 173 additions and 207 deletions

View File

@ -10,10 +10,12 @@
#ifndef ST_LIS2DW12_H
#define ST_LIS2DW12_H
#include <linux/bitfield.h>
#include <linux/device.h>
#include <linux/iio/events.h>
#include <linux/iio/iio.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include "../common/stm_iio_types.h"
@ -23,18 +25,8 @@
#define ST_LIS2DW12_MAX_WATERMARK 31
#define ST_LIS2DW12_DATA_SIZE 6
struct st_lis2dw12_transfer_function {
int (*read)(struct device *dev, u8 addr, int len, u8 *data);
int (*write)(struct device *dev, u8 addr, int len, u8 *data);
};
#define ST_LIS2DW12_RX_MAX_LENGTH 96
#define ST_LIS2DW12_TX_MAX_LENGTH 8
struct st_lis2dw12_transfer_buffer {
u8 rx_buf[ST_LIS2DW12_RX_MAX_LENGTH];
u8 tx_buf[ST_LIS2DW12_TX_MAX_LENGTH] ____cacheline_aligned;
};
#define ST_LIS2DW12_SHIFT_VAL(val, mask) (((val) << __ffs(mask)) & \
(mask))
enum st_lis2dw12_fifo_mode {
ST_LIS2DW12_FIFO_BYPASS = 0x0,
@ -65,6 +57,7 @@ struct st_lis2dw12_sensor {
};
struct st_lis2dw12_hw {
struct regmap *regmap;
struct device *dev;
int irq;
int irq_emb;
@ -87,17 +80,73 @@ struct st_lis2dw12_hw {
s64 delta_ts;
s64 ts_irq;
s64 ts;
const struct st_lis2dw12_transfer_function *tf;
struct st_lis2dw12_transfer_buffer tb;
};
static inline int
__st_lis2dw12_write_with_mask(struct st_lis2dw12_hw *hw,
unsigned int addr, int mask,
unsigned int data)
{
int err;
unsigned int val = ST_LIS2DW12_SHIFT_VAL(data, mask);
err = regmap_update_bits(hw->regmap, addr, mask, val);
return err;
}
static inline int
st_lis2dw12_update_bits_locked(struct st_lis2dw12_hw *hw,
unsigned int addr, unsigned int mask,
unsigned int val)
{
int err;
mutex_lock(&hw->lock);
err = __st_lis2dw12_write_with_mask(hw, addr, mask, val);
mutex_unlock(&hw->lock);
return err;
}
static inline int
st_lis2dw12_write_with_mask_locked(struct st_lis2dw12_hw *hw,
unsigned int addr, unsigned int mask,
unsigned int data)
{
int err;
mutex_lock(&hw->lock);
err = __st_lis2dw12_write_with_mask(hw, addr, mask, data);
mutex_unlock(&hw->lock);
return err;
}
static inline int st_lis2dw12_write_locked(struct st_lis2dw12_hw *hw,
unsigned int addr, u8 *val,
unsigned int len)
{
int err;
mutex_lock(&hw->lock);
err = regmap_bulk_write(hw->regmap, addr, val, len);
mutex_unlock(&hw->lock);
return err;
}
static inline int st_lis2dw12_read(struct st_lis2dw12_hw *hw, unsigned int addr,
void *val, unsigned int len)
{
return regmap_bulk_read(hw->regmap, addr, val, len);
}
int st_lis2dw12_probe(struct device *dev, int irq, const char *name,
const struct st_lis2dw12_transfer_function *tf_ops);
struct regmap *regmap);
int st_lis2dw12_fifo_setup(struct st_lis2dw12_hw *hw);
int st_lis2dw12_update_fifo_watermark(struct st_lis2dw12_hw *hw, u8 watermark);
int st_lis2dw12_write_with_mask(struct st_lis2dw12_hw *hw, u8 addr, u8 mask,
u8 val);
ssize_t st_lis2dw12_flush_fifo(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size);

View File

@ -76,8 +76,10 @@ static int st_lis2dw12_update_fifo(struct iio_dev *iio_dev, bool enable)
}
mode = enable ? ST_LIS2DW12_FIFO_CONTINUOUS : ST_LIS2DW12_FIFO_BYPASS;
err = st_lis2dw12_write_with_mask(hw, ST_LIS2DW12_FIFO_CTRL_ADDR,
ST_LIS2DW12_FIFOMODE_MASK, mode);
err = st_lis2dw12_write_with_mask_locked(hw,
ST_LIS2DW12_FIFO_CTRL_ADDR,
ST_LIS2DW12_FIFOMODE_MASK,
mode);
if (err < 0)
return err;
@ -86,8 +88,10 @@ static int st_lis2dw12_update_fifo(struct iio_dev *iio_dev, bool enable)
int st_lis2dw12_update_fifo_watermark(struct st_lis2dw12_hw *hw, u8 watermark)
{
return st_lis2dw12_write_with_mask(hw, ST_LIS2DW12_FIFO_CTRL_ADDR,
ST_LIS2DW12_FTH_MASK, watermark);
return st_lis2dw12_write_with_mask_locked(hw,
ST_LIS2DW12_FIFO_CTRL_ADDR,
ST_LIS2DW12_FTH_MASK,
watermark);
}
ssize_t st_lis2dw12_set_hwfifo_watermark(struct device *dev,
@ -144,14 +148,14 @@ static const struct iio_buffer_setup_ops st_lis2dw12_acc_buffer_setup_ops = {
static int st_lis2dw12_read_fifo(struct st_lis2dw12_hw *hw)
{
u8 iio_buff[ALIGN(ST_LIS2DW12_DATA_SIZE, sizeof(s64)) + sizeof(s64)];
u8 buff[ST_LIS2DW12_RX_MAX_LENGTH], status, samples;
u8 buff[6 * ST_LIS2DW12_DATA_SIZE], status, samples;
struct iio_dev *iio_dev = hw->iio_devs[ST_LIS2DW12_ID_ACC];
struct iio_chan_spec const *ch = iio_dev->channels;
int i, err, word_len, fifo_len, read_len = 0;
s64 delta_ts;
err = hw->tf->read(hw->dev, ST_LIS2DW12_FIFO_SAMPLES_ADDR,
sizeof(status), &status);
err = st_lis2dw12_read(hw, ST_LIS2DW12_FIFO_SAMPLES_ADDR,
&status, sizeof(status));
if (err < 0)
return err;
@ -161,7 +165,7 @@ static int st_lis2dw12_read_fifo(struct st_lis2dw12_hw *hw)
while (read_len < fifo_len) {
word_len = min_t(int, fifo_len - read_len, sizeof(buff));
err = hw->tf->read(hw->dev, ch[0].address, word_len, buff);
err = st_lis2dw12_read(hw, ch[0].address, buff, word_len);
if (err < 0)
return err;
@ -215,8 +219,8 @@ static irqreturn_t st_lis2dw12_emb_event(struct st_lis2dw12_hw *hw)
s64 code;
int err;
err = hw->tf->read(hw->dev, ST_LIS2DW12_ALL_INT_SRC_ADDR,
sizeof(status), &status);
err = st_lis2dw12_read(hw, ST_LIS2DW12_ALL_INT_SRC_ADDR,
&status, sizeof(status));
if (err < 0)
return IRQ_HANDLED;
@ -228,8 +232,8 @@ static irqreturn_t st_lis2dw12_emb_event(struct st_lis2dw12_hw *hw)
enum iio_chan_type type;
u8 source;
err = hw->tf->read(hw->dev, ST_LIS2DW12_TAP_SRC_ADDR,
sizeof(source), &source);
err = st_lis2dw12_read(hw, ST_LIS2DW12_TAP_SRC_ADDR,
&source, sizeof(source));
if (err < 0)
return IRQ_HANDLED;
@ -259,8 +263,8 @@ static irqreturn_t st_lis2dw12_emb_event(struct st_lis2dw12_hw *hw)
if (status & ST_LIS2DW12_ALL_INT_SRC_WU_MASK) {
u8 wu_src;
err = hw->tf->read(hw->dev, ST_LIS2DW12_WU_SRC_ADDR,
sizeof(wu_src), &wu_src);
err = st_lis2dw12_read(hw, ST_LIS2DW12_WU_SRC_ADDR,
&wu_src, sizeof(wu_src));
if (err < 0)
return IRQ_HANDLED;
@ -304,8 +308,8 @@ static irqreturn_t st_lis2dw12_handler_thread(int irq, void *private)
u8 status;
int err;
err = hw->tf->read(hw->dev, ST_LIS2DW12_STATUS_ADDR,
sizeof(status), &status);
err = st_lis2dw12_read(hw, ST_LIS2DW12_STATUS_ADDR,
&status, sizeof(status));
if (err < 0)
return IRQ_HANDLED;

View File

@ -201,32 +201,6 @@ static const struct iio_chan_spec st_lis2dw12_wu_channels[] = {
ST_LIS2DW12_EVENT_CHANNEL(STM_IIO_GESTURE, &st_lis2dw12_rthr_event),
};
int st_lis2dw12_write_with_mask(struct st_lis2dw12_hw *hw, u8 addr, u8 mask,
u8 val)
{
u8 data;
int err;
mutex_lock(&hw->lock);
err = hw->tf->read(hw->dev, addr, sizeof(data), &data);
if (err < 0) {
dev_err(hw->dev, "failed to read %02x register\n", addr);
goto unlock;
}
data = (data & ~mask) | ((val << __ffs(mask)) & mask);
err = hw->tf->write(hw->dev, addr, sizeof(data), &data);
if (err < 0)
dev_err(hw->dev, "failed to write %02x register\n", addr);
unlock:
mutex_unlock(&hw->lock);
return err;
}
static int st_lis2dw12_set_fs(struct st_lis2dw12_sensor *sensor, u16 gain)
{
int i, err;
@ -238,9 +212,10 @@ static int st_lis2dw12_set_fs(struct st_lis2dw12_sensor *sensor, u16 gain)
if (i == ARRAY_SIZE(st_lis2dw12_fs_table))
return -EINVAL;
err = st_lis2dw12_write_with_mask(sensor->hw, ST_LIS2DW12_CTRL6_ADDR,
ST_LIS2DW12_FS_MASK,
st_lis2dw12_fs_table[i].val);
err = st_lis2dw12_write_with_mask_locked(sensor->hw,
ST_LIS2DW12_CTRL6_ADDR,
ST_LIS2DW12_FS_MASK,
st_lis2dw12_fs_table[i].val);
if (err < 0)
return err;
@ -324,19 +299,17 @@ static int st_lis2dw12_set_odr(struct st_lis2dw12_sensor *sensor, u16 req_odr)
val = (st_lis2dw12_odr_table[i].val << __ffs(ST_LIS2DW12_ODR_MASK)) |
(mode << __ffs(ST_LIS2DW12_MODE_MASK)) | 0x01;
err = hw->tf->write(hw->dev, ST_LIS2DW12_CTRL1_ADDR, sizeof(val),
&val);
err = st_lis2dw12_write_locked(hw, ST_LIS2DW12_CTRL1_ADDR,
&val, sizeof(val));
return err < 0 ? err : 0;
}
static int st_lis2dw12_check_whoami(struct st_lis2dw12_hw *hw)
{
int err;
u8 data;
int data, err;
err = hw->tf->read(hw->dev, ST_LIS2DW12_WHOAMI_ADDR, sizeof(data),
&data);
err = regmap_read(hw->regmap, ST_LIS2DW12_WHOAMI_ADDR, &data);
if (err < 0) {
dev_err(hw->dev, "failed to read whoami register\n");
return err;
@ -422,20 +395,21 @@ static int st_lis2dw12_init_hw(struct st_lis2dw12_hw *hw)
int err;
/* soft reset the device */
err = st_lis2dw12_write_with_mask(hw, ST_LIS2DW12_CTRL2_ADDR,
ST_LIS2DW12_RESET_MASK, 1);
err = st_lis2dw12_write_with_mask_locked(hw, ST_LIS2DW12_CTRL2_ADDR,
ST_LIS2DW12_RESET_MASK, 1);
if (err < 0)
return err;
/* enable BDU */
err = st_lis2dw12_write_with_mask(hw, ST_LIS2DW12_CTRL2_ADDR,
ST_LIS2DW12_BDU_MASK, 1);
err = st_lis2dw12_write_with_mask_locked(hw, ST_LIS2DW12_CTRL2_ADDR,
ST_LIS2DW12_BDU_MASK, 1);
if (err < 0)
return err;
/* enable all interrupts */
err = st_lis2dw12_write_with_mask(hw, ST_LIS2DW12_ABS_INT_CFG_ADDR,
ST_LIS2DW12_ALL_INT_MASK, 1);
err = st_lis2dw12_write_with_mask_locked(hw,
ST_LIS2DW12_ABS_INT_CFG_ADDR,
ST_LIS2DW12_ALL_INT_MASK, 1);
if (err < 0)
return err;
@ -445,54 +419,57 @@ static int st_lis2dw12_init_hw(struct st_lis2dw12_hw *hw)
return err;
/* configure default free fall event threshold */
err = st_lis2dw12_write_with_mask(hw, ST_LIS2DW12_FREE_FALL_ADDR,
ST_LIS2DW12_FREE_FALL_THS_MASK, 1);
err = st_lis2dw12_write_with_mask_locked(hw, ST_LIS2DW12_FREE_FALL_ADDR,
ST_LIS2DW12_FREE_FALL_THS_MASK,
1);
if (err < 0)
return err;
/* configure default free fall event duration */
err = st_lis2dw12_write_with_mask(hw, ST_LIS2DW12_FREE_FALL_ADDR,
ST_LIS2DW12_FREE_FALL_DUR_MASK, 1);
err = st_lis2dw12_write_with_mask_locked(hw, ST_LIS2DW12_FREE_FALL_ADDR,
ST_LIS2DW12_FREE_FALL_DUR_MASK,
1);
if (err < 0)
return err;
/* enable tap event on all axes */
err = st_lis2dw12_write_with_mask(hw, ST_LIS2DW12_TAP_THS_Z_ADDR,
ST_LIS2DW12_TAP_AXIS_MASK, 0x7);
err = st_lis2dw12_write_with_mask_locked(hw, ST_LIS2DW12_TAP_THS_Z_ADDR,
ST_LIS2DW12_TAP_AXIS_MASK,
0x7);
if (err < 0)
return err;
/* configure default threshold for Tap event recognition */
err = st_lis2dw12_write_with_mask(hw, ST_LIS2DW12_TAP_THS_X_ADDR,
ST_LIS2DW12_TAP_THS_MAK, 9);
err = st_lis2dw12_write_with_mask_locked(hw, ST_LIS2DW12_TAP_THS_X_ADDR,
ST_LIS2DW12_TAP_THS_MAK, 9);
if (err < 0)
return err;
err = st_lis2dw12_write_with_mask(hw, ST_LIS2DW12_TAP_THS_Y_ADDR,
ST_LIS2DW12_TAP_THS_MAK, 9);
err = st_lis2dw12_write_with_mask_locked(hw, ST_LIS2DW12_TAP_THS_Y_ADDR,
ST_LIS2DW12_TAP_THS_MAK, 9);
if (err < 0)
return err;
err = st_lis2dw12_write_with_mask(hw, ST_LIS2DW12_TAP_THS_Z_ADDR,
ST_LIS2DW12_TAP_THS_MAK, 9);
err = st_lis2dw12_write_with_mask_locked(hw, ST_LIS2DW12_TAP_THS_Z_ADDR,
ST_LIS2DW12_TAP_THS_MAK, 9);
if (err < 0)
return err;
/* low noise enabled by default */
err = st_lis2dw12_write_with_mask(hw, ST_LIS2DW12_CTRL6_ADDR,
ST_LIS2DW12_LN_MASK, 1);
err = st_lis2dw12_write_with_mask_locked(hw, ST_LIS2DW12_CTRL6_ADDR,
ST_LIS2DW12_LN_MASK, 1);
if (err < 0)
return err;
/* BW = ODR/4 */
err = st_lis2dw12_write_with_mask(hw, ST_LIS2DW12_CTRL6_ADDR,
ST_LIS2DW12_BW_MASK, 1);
err = st_lis2dw12_write_with_mask_locked(hw, ST_LIS2DW12_CTRL6_ADDR,
ST_LIS2DW12_BW_MASK, 1);
if (err < 0)
return err;
/* enable latched mode */
err = st_lis2dw12_write_with_mask(hw, ST_LIS2DW12_CTRL3_ADDR,
ST_LIS2DW12_LIR_MASK, 1);
err = st_lis2dw12_write_with_mask_locked(hw, ST_LIS2DW12_CTRL3_ADDR,
ST_LIS2DW12_LIR_MASK, 1);
if (err < 0)
return err;
@ -501,8 +478,8 @@ static int st_lis2dw12_init_hw(struct st_lis2dw12_hw *hw)
if (err < 0)
return err;
return st_lis2dw12_write_with_mask(hw, hw->irq_reg,
ST_LIS2DW12_FTH_INT_MASK, 1);
return st_lis2dw12_write_with_mask_locked(hw, hw->irq_reg,
ST_LIS2DW12_FTH_INT_MASK, 1);
}
static ssize_t
@ -568,7 +545,7 @@ static int st_lis2dw12_read_oneshot(struct st_lis2dw12_sensor *sensor,
delay = 3000000 / sensor->odr;
usleep_range(delay, delay + 1);
err = hw->tf->read(hw->dev, addr, sizeof(data), data);
err = st_lis2dw12_read(hw, addr, &data, sizeof(data));
if (err < 0)
return err;
@ -672,8 +649,8 @@ static int st_lis2dw12_write_event_config(struct iio_dev *iio_dev,
int err;
/* Read initial configuration data */
err = hw->tf->read(hw->dev, ST_LIS2DW12_INT_DUR_ADDR,
sizeof(data), data);
err = st_lis2dw12_read(hw, ST_LIS2DW12_INT_DUR_ADDR,
&data, sizeof(data));
if (err < 0)
return -EINVAL;
@ -707,13 +684,14 @@ static int st_lis2dw12_write_event_config(struct iio_dev *iio_dev,
return -EINVAL;
}
err = hw->tf->write(hw->dev, ST_LIS2DW12_INT_DUR_ADDR,
sizeof(data), data);
err = st_lis2dw12_write_locked(hw, ST_LIS2DW12_INT_DUR_ADDR,
data, sizeof(data));
if (err < 0)
return err;
err = st_lis2dw12_write_with_mask(hw, ST_LIS2DW12_CTRL4_INT1_CTRL_ADDR,
drdy_mask, drdy_val);
err = st_lis2dw12_write_with_mask_locked(hw,
ST_LIS2DW12_CTRL4_INT1_CTRL_ADDR,
drdy_mask, drdy_val);
if (err < 0)
return err;
@ -817,8 +795,8 @@ static ssize_t st_lis2dw12_enable_selftest(struct device *dev,
msleep(200);
for (i = 0; i < 5; i++) {
err = hw->tf->read(hw->dev, ST_LIS2DW12_OUT_X_L_ADDR,
sizeof(data), data);
err = st_lis2dw12_read(hw, ST_LIS2DW12_OUT_X_L_ADDR,
&data, sizeof(data));
if (err < 0)
goto unlock;
@ -830,16 +808,16 @@ static ssize_t st_lis2dw12_enable_selftest(struct device *dev,
}
/* enable self test */
err = st_lis2dw12_write_with_mask(hw, ST_LIS2DW12_CTRL3_ADDR,
ST_LIS2DW12_ST_MASK, val);
err = st_lis2dw12_write_with_mask_locked(hw, ST_LIS2DW12_CTRL3_ADDR,
ST_LIS2DW12_ST_MASK, val);
if (err < 0)
goto unlock;
msleep(200);
for (i = 0; i < 5; i++) {
err = hw->tf->read(hw->dev, ST_LIS2DW12_OUT_X_L_ADDR,
sizeof(data), data);
err = st_lis2dw12_read(hw, ST_LIS2DW12_OUT_X_L_ADDR,
&data, sizeof(data));
if (err < 0)
goto unlock;
@ -861,8 +839,8 @@ static ssize_t st_lis2dw12_enable_selftest(struct device *dev,
hw->st_status = ST_LIS2DW12_ST_FAIL;
/* disable self test */
err = st_lis2dw12_write_with_mask(hw, ST_LIS2DW12_CTRL3_ADDR,
ST_LIS2DW12_ST_MASK, 0);
err = st_lis2dw12_write_with_mask_locked(hw, ST_LIS2DW12_CTRL3_ADDR,
ST_LIS2DW12_ST_MASK, 0);
if (err < 0)
goto unlock;
@ -1032,7 +1010,7 @@ static struct iio_dev *st_lis2dw12_alloc_iiodev(struct st_lis2dw12_hw *hw,
}
int st_lis2dw12_probe(struct device *dev, int irq, const char *name,
const struct st_lis2dw12_transfer_function *tf_ops)
struct regmap *regmap)
{
struct st_lis2dw12_hw *hw;
int i, err;
@ -1048,7 +1026,7 @@ int st_lis2dw12_probe(struct device *dev, int irq, const char *name,
hw->dev = dev;
hw->irq = irq;
hw->tf = tf_ops;
hw->regmap = regmap;
hw->watermark = 1;
err = st_lis2dw12_check_whoami(hw);

View File

@ -14,54 +14,27 @@
#include "st_lis2dw12.h"
static int st_lis2dw12_i2c_read(struct device *dev, u8 addr, int len, u8 *data)
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_msg msg[2];
msg[0].addr = client->addr;
msg[0].flags = client->flags;
msg[0].len = 1;
msg[0].buf = &addr;
msg[1].addr = client->addr;
msg[1].flags = client->flags | I2C_M_RD;
msg[1].len = len;
msg[1].buf = data;
return i2c_transfer(client->adapter, msg, 2);
}
static int st_lis2dw12_i2c_write(struct device *dev, u8 addr, int len, u8 *data)
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_msg msg;
u8 send[4];
if (len >= ARRAY_SIZE(send))
return -ENOMEM;
send[0] = addr;
memcpy(&send[1], data, len * sizeof(u8));
msg.addr = client->addr;
msg.flags = client->flags;
msg.len = len + 1;
msg.buf = send;
return i2c_transfer(client->adapter, &msg, 1);
}
static const struct st_lis2dw12_transfer_function st_lis2dw12_transfer_fn = {
.read = st_lis2dw12_i2c_read,
.write = st_lis2dw12_i2c_write,
static const struct regmap_config st_lis2dw12_i2c_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
static int st_lis2dw12_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
return st_lis2dw12_probe(&client->dev, client->irq, client->name,
&st_lis2dw12_transfer_fn);
struct regmap *regmap;
regmap = devm_regmap_init_i2c(client, &st_lis2dw12_i2c_regmap_config);
if (IS_ERR(regmap)) {
dev_err(&client->dev,
"Failed to register i2c regmap %d\n",
(int)PTR_ERR(regmap));
return PTR_ERR(regmap);
}
return st_lis2dw12_probe(&client->dev, client->irq,
client->name, regmap);
}
static const struct of_device_id st_lis2dw12_i2c_of_match[] = {

View File

@ -14,62 +14,24 @@
#include "st_lis2dw12.h"
#define SENSORS_SPI_READ BIT(7)
static int st_lis2dw12_spi_read(struct device *dev, u8 addr, int len, u8 *data)
{
struct spi_device *spi = to_spi_device(dev);
struct st_lis2dw12_hw *hw = spi_get_drvdata(spi);
int err;
struct spi_transfer xfers[] = {
{
.tx_buf = hw->tb.tx_buf,
.bits_per_word = 8,
.len = 1,
},
{
.rx_buf = hw->tb.rx_buf,
.bits_per_word = 8,
.len = len,
}
};
hw->tb.tx_buf[0] = addr | SENSORS_SPI_READ;
err = spi_sync_transfer(spi, xfers, ARRAY_SIZE(xfers));
if (err < 0)
return err;
memcpy(data, hw->tb.rx_buf, len * sizeof(u8));
return len;
}
static int st_lis2dw12_spi_write(struct device *dev, u8 addr, int len,
u8 *data)
{
struct spi_device *spi = to_spi_device(dev);
struct st_lis2dw12_hw *hw = spi_get_drvdata(spi);
if (len >= ST_LIS2DW12_TX_MAX_LENGTH)
return -ENOMEM;
hw->tb.tx_buf[0] = addr;
memcpy(&hw->tb.tx_buf[1], data, len);
return spi_write(spi, hw->tb.tx_buf, len + 1);
}
static const struct st_lis2dw12_transfer_function st_lis2dw12_transfer_fn = {
.read = st_lis2dw12_spi_read,
.write = st_lis2dw12_spi_write,
static const struct regmap_config st_lis2dw12_spi_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
static int st_lis2dw12_spi_probe(struct spi_device *spi)
{
return st_lis2dw12_probe(&spi->dev, spi->irq, spi->modalias,
&st_lis2dw12_transfer_fn);
struct regmap *regmap;
regmap = devm_regmap_init_spi(spi, &st_lis2dw12_spi_regmap_config);
if (IS_ERR(regmap)) {
dev_err(&spi->dev,
"Failed to register spi regmap %d\n",
(int)PTR_ERR(regmap));
return PTR_ERR(regmap);
}
return st_lis2dw12_probe(&spi->dev, spi->irq, spi->modalias, regmap);
}
static const struct of_device_id st_lis2dw12_spi_of_match[] = {