1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2021 Analog Devices, Inc.
4 * Author: Cosmin Tanislav <cosmin.tanislav@analog.com>
7 #include <linux/mod_devicetable.h>
8 #include <linux/module.h>
9 #include <linux/regmap.h>
10 #include <linux/spi/spi.h>
12 #include <linux/iio/iio.h>
16 #define ADXL367_SPI_WRITE_COMMAND 0x0A
17 #define ADXL367_SPI_READ_COMMAND 0x0B
18 #define ADXL367_SPI_FIFO_COMMAND 0x0D
20 struct adxl367_spi_state
{
21 struct spi_device
*spi
;
23 struct spi_message reg_write_msg
;
24 struct spi_transfer reg_write_xfer
[2];
26 struct spi_message reg_read_msg
;
27 struct spi_transfer reg_read_xfer
[2];
29 struct spi_message fifo_msg
;
30 struct spi_transfer fifo_xfer
[2];
33 * DMA (thus cache coherency maintenance) may require the
34 * transfer buffers live in their own cache lines.
36 u8 reg_write_tx_buf
[1] __aligned(IIO_DMA_MINALIGN
);
37 u8 reg_read_tx_buf
[2];
41 static int adxl367_read_fifo(void *context
, __be16
*fifo_buf
,
42 unsigned int fifo_entries
)
44 struct adxl367_spi_state
*st
= context
;
46 st
->fifo_xfer
[1].rx_buf
= fifo_buf
;
47 st
->fifo_xfer
[1].len
= fifo_entries
* sizeof(*fifo_buf
);
49 return spi_sync(st
->spi
, &st
->fifo_msg
);
52 static int adxl367_read(void *context
, const void *reg_buf
, size_t reg_size
,
53 void *val_buf
, size_t val_size
)
55 struct adxl367_spi_state
*st
= context
;
56 u8 reg
= ((const u8
*)reg_buf
)[0];
58 st
->reg_read_tx_buf
[1] = reg
;
59 st
->reg_read_xfer
[1].rx_buf
= val_buf
;
60 st
->reg_read_xfer
[1].len
= val_size
;
62 return spi_sync(st
->spi
, &st
->reg_read_msg
);
65 static int adxl367_write(void *context
, const void *val_buf
, size_t val_size
)
67 struct adxl367_spi_state
*st
= context
;
69 st
->reg_write_xfer
[1].tx_buf
= val_buf
;
70 st
->reg_write_xfer
[1].len
= val_size
;
72 return spi_sync(st
->spi
, &st
->reg_write_msg
);
75 static const struct regmap_bus adxl367_spi_regmap_bus
= {
77 .write
= adxl367_write
,
80 static const struct regmap_config adxl367_spi_regmap_config
= {
85 static const struct adxl367_ops adxl367_spi_ops
= {
86 .read_fifo
= adxl367_read_fifo
,
89 static int adxl367_spi_probe(struct spi_device
*spi
)
91 struct adxl367_spi_state
*st
;
92 struct regmap
*regmap
;
94 st
= devm_kzalloc(&spi
->dev
, sizeof(*st
), GFP_KERNEL
);
101 * Xfer: [XFR1] [ XFR2 ]
102 * Master: 0x0A ADDR DATA0 DATA1 ... DATAN
103 * Slave: .... ..........................
105 st
->reg_write_tx_buf
[0] = ADXL367_SPI_WRITE_COMMAND
;
106 st
->reg_write_xfer
[0].tx_buf
= st
->reg_write_tx_buf
;
107 st
->reg_write_xfer
[0].len
= sizeof(st
->reg_write_tx_buf
);
108 spi_message_init_with_transfers(&st
->reg_write_msg
,
109 st
->reg_write_xfer
, 2);
112 * Xfer: [ XFR1 ] [ XFR2 ]
113 * Master: 0x0B ADDR .....................
114 * Slave: ......... DATA0 DATA1 ... DATAN
116 st
->reg_read_tx_buf
[0] = ADXL367_SPI_READ_COMMAND
;
117 st
->reg_read_xfer
[0].tx_buf
= st
->reg_read_tx_buf
;
118 st
->reg_read_xfer
[0].len
= sizeof(st
->reg_read_tx_buf
);
119 spi_message_init_with_transfers(&st
->reg_read_msg
,
120 st
->reg_read_xfer
, 2);
123 * Xfer: [XFR1] [ XFR2 ]
124 * Master: 0x0D .....................
125 * Slave: .... DATA0 DATA1 ... DATAN
127 st
->fifo_tx_buf
[0] = ADXL367_SPI_FIFO_COMMAND
;
128 st
->fifo_xfer
[0].tx_buf
= st
->fifo_tx_buf
;
129 st
->fifo_xfer
[0].len
= sizeof(st
->fifo_tx_buf
);
130 spi_message_init_with_transfers(&st
->fifo_msg
, st
->fifo_xfer
, 2);
132 regmap
= devm_regmap_init(&spi
->dev
, &adxl367_spi_regmap_bus
, st
,
133 &adxl367_spi_regmap_config
);
135 return PTR_ERR(regmap
);
137 return adxl367_probe(&spi
->dev
, &adxl367_spi_ops
, st
, regmap
, spi
->irq
);
140 static const struct spi_device_id adxl367_spi_id
[] = {
144 MODULE_DEVICE_TABLE(spi
, adxl367_spi_id
);
146 static const struct of_device_id adxl367_of_match
[] = {
147 { .compatible
= "adi,adxl367" },
150 MODULE_DEVICE_TABLE(of
, adxl367_of_match
);
152 static struct spi_driver adxl367_spi_driver
= {
154 .name
= "adxl367_spi",
155 .of_match_table
= adxl367_of_match
,
157 .probe
= adxl367_spi_probe
,
158 .id_table
= adxl367_spi_id
,
161 module_spi_driver(adxl367_spi_driver
);
163 MODULE_IMPORT_NS(IIO_ADXL367
);
164 MODULE_AUTHOR("Cosmin Tanislav <cosmin.tanislav@analog.com>");
165 MODULE_DESCRIPTION("Analog Devices ADXL367 3-axis accelerometer SPI driver");
166 MODULE_LICENSE("GPL");