adxl367_spi.c (4339B)
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2021 Analog Devices, Inc. 4 * Author: Cosmin Tanislav <cosmin.tanislav@analog.com> 5 */ 6 7#include <linux/mod_devicetable.h> 8#include <linux/module.h> 9#include <linux/regmap.h> 10#include <linux/spi/spi.h> 11 12#include "adxl367.h" 13 14#define ADXL367_SPI_WRITE_COMMAND 0x0A 15#define ADXL367_SPI_READ_COMMAND 0x0B 16#define ADXL367_SPI_FIFO_COMMAND 0x0D 17 18struct adxl367_spi_state { 19 struct spi_device *spi; 20 21 struct spi_message reg_write_msg; 22 struct spi_transfer reg_write_xfer[2]; 23 24 struct spi_message reg_read_msg; 25 struct spi_transfer reg_read_xfer[2]; 26 27 struct spi_message fifo_msg; 28 struct spi_transfer fifo_xfer[2]; 29 30 /* 31 * DMA (thus cache coherency maintenance) requires the 32 * transfer buffers to live in their own cache lines. 33 */ 34 u8 reg_write_tx_buf[1] ____cacheline_aligned; 35 u8 reg_read_tx_buf[2]; 36 u8 fifo_tx_buf[1]; 37}; 38 39static int adxl367_read_fifo(void *context, __be16 *fifo_buf, 40 unsigned int fifo_entries) 41{ 42 struct adxl367_spi_state *st = context; 43 44 st->fifo_xfer[1].rx_buf = fifo_buf; 45 st->fifo_xfer[1].len = fifo_entries * sizeof(*fifo_buf); 46 47 return spi_sync(st->spi, &st->fifo_msg); 48} 49 50static int adxl367_read(void *context, const void *reg_buf, size_t reg_size, 51 void *val_buf, size_t val_size) 52{ 53 struct adxl367_spi_state *st = context; 54 u8 reg = ((const u8 *)reg_buf)[0]; 55 56 st->reg_read_tx_buf[1] = reg; 57 st->reg_read_xfer[1].rx_buf = val_buf; 58 st->reg_read_xfer[1].len = val_size; 59 60 return spi_sync(st->spi, &st->reg_read_msg); 61} 62 63static int adxl367_write(void *context, const void *val_buf, size_t val_size) 64{ 65 struct adxl367_spi_state *st = context; 66 67 st->reg_write_xfer[1].tx_buf = val_buf; 68 st->reg_write_xfer[1].len = val_size; 69 70 return spi_sync(st->spi, &st->reg_write_msg); 71} 72 73static struct regmap_bus adxl367_spi_regmap_bus = { 74 .read = adxl367_read, 75 .write = adxl367_write, 76}; 77 78static const struct regmap_config adxl367_spi_regmap_config = { 79 .reg_bits = 8, 80 .val_bits = 8, 81}; 82 83static const struct adxl367_ops adxl367_spi_ops = { 84 .read_fifo = adxl367_read_fifo, 85}; 86 87static int adxl367_spi_probe(struct spi_device *spi) 88{ 89 struct adxl367_spi_state *st; 90 struct regmap *regmap; 91 92 st = devm_kzalloc(&spi->dev, sizeof(*st), GFP_KERNEL); 93 if (!st) 94 return -ENOMEM; 95 96 st->spi = spi; 97 98 /* 99 * Xfer: [XFR1] [ XFR2 ] 100 * Master: 0x0A ADDR DATA0 DATA1 ... DATAN 101 * Slave: .... .......................... 102 */ 103 st->reg_write_tx_buf[0] = ADXL367_SPI_WRITE_COMMAND; 104 st->reg_write_xfer[0].tx_buf = st->reg_write_tx_buf; 105 st->reg_write_xfer[0].len = sizeof(st->reg_write_tx_buf); 106 spi_message_init_with_transfers(&st->reg_write_msg, 107 st->reg_write_xfer, 2); 108 109 /* 110 * Xfer: [ XFR1 ] [ XFR2 ] 111 * Master: 0x0B ADDR ..................... 112 * Slave: ......... DATA0 DATA1 ... DATAN 113 */ 114 st->reg_read_tx_buf[0] = ADXL367_SPI_READ_COMMAND; 115 st->reg_read_xfer[0].tx_buf = st->reg_read_tx_buf; 116 st->reg_read_xfer[0].len = sizeof(st->reg_read_tx_buf); 117 spi_message_init_with_transfers(&st->reg_read_msg, 118 st->reg_read_xfer, 2); 119 120 /* 121 * Xfer: [XFR1] [ XFR2 ] 122 * Master: 0x0D ..................... 123 * Slave: .... DATA0 DATA1 ... DATAN 124 */ 125 st->fifo_tx_buf[0] = ADXL367_SPI_FIFO_COMMAND; 126 st->fifo_xfer[0].tx_buf = st->fifo_tx_buf; 127 st->fifo_xfer[0].len = sizeof(st->fifo_tx_buf); 128 spi_message_init_with_transfers(&st->fifo_msg, st->fifo_xfer, 2); 129 130 regmap = devm_regmap_init(&spi->dev, &adxl367_spi_regmap_bus, st, 131 &adxl367_spi_regmap_config); 132 if (IS_ERR(regmap)) 133 return PTR_ERR(regmap); 134 135 return adxl367_probe(&spi->dev, &adxl367_spi_ops, st, regmap, spi->irq); 136} 137 138static const struct spi_device_id adxl367_spi_id[] = { 139 { "adxl367", 0 }, 140 { }, 141}; 142MODULE_DEVICE_TABLE(spi, adxl367_spi_id); 143 144static const struct of_device_id adxl367_of_match[] = { 145 { .compatible = "adi,adxl367" }, 146 { }, 147}; 148MODULE_DEVICE_TABLE(of, adxl367_of_match); 149 150static struct spi_driver adxl367_spi_driver = { 151 .driver = { 152 .name = "adxl367_spi", 153 .of_match_table = adxl367_of_match, 154 }, 155 .probe = adxl367_spi_probe, 156 .id_table = adxl367_spi_id, 157}; 158 159module_spi_driver(adxl367_spi_driver); 160 161MODULE_IMPORT_NS(IIO_ADXL367); 162MODULE_AUTHOR("Cosmin Tanislav <cosmin.tanislav@analog.com>"); 163MODULE_DESCRIPTION("Analog Devices ADXL367 3-axis accelerometer SPI driver"); 164MODULE_LICENSE("GPL");