0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "tcan4x5x.h"
0011
0012 #define TCAN4X5X_SPI_INSTRUCTION_WRITE (0x61 << 24)
0013 #define TCAN4X5X_SPI_INSTRUCTION_READ (0x41 << 24)
0014
0015 #define TCAN4X5X_MAX_REGISTER 0x87fc
0016
0017 static int tcan4x5x_regmap_gather_write(void *context,
0018 const void *reg, size_t reg_len,
0019 const void *val, size_t val_len)
0020 {
0021 struct spi_device *spi = context;
0022 struct tcan4x5x_priv *priv = spi_get_drvdata(spi);
0023 struct tcan4x5x_map_buf *buf_tx = &priv->map_buf_tx;
0024 struct spi_transfer xfer[] = {
0025 {
0026 .tx_buf = buf_tx,
0027 .len = sizeof(buf_tx->cmd) + val_len,
0028 },
0029 };
0030
0031 memcpy(&buf_tx->cmd, reg, sizeof(buf_tx->cmd.cmd) +
0032 sizeof(buf_tx->cmd.addr));
0033 tcan4x5x_spi_cmd_set_len(&buf_tx->cmd, val_len);
0034 memcpy(buf_tx->data, val, val_len);
0035
0036 return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
0037 }
0038
0039 static int tcan4x5x_regmap_write(void *context, const void *data, size_t count)
0040 {
0041 return tcan4x5x_regmap_gather_write(context, data, sizeof(__be32),
0042 data + sizeof(__be32),
0043 count - sizeof(__be32));
0044 }
0045
0046 static int tcan4x5x_regmap_read(void *context,
0047 const void *reg_buf, size_t reg_len,
0048 void *val_buf, size_t val_len)
0049 {
0050 struct spi_device *spi = context;
0051 struct tcan4x5x_priv *priv = spi_get_drvdata(spi);
0052 struct tcan4x5x_map_buf *buf_rx = &priv->map_buf_rx;
0053 struct tcan4x5x_map_buf *buf_tx = &priv->map_buf_tx;
0054 struct spi_transfer xfer[2] = {
0055 {
0056 .tx_buf = buf_tx,
0057 }
0058 };
0059 struct spi_message msg;
0060 int err;
0061
0062 spi_message_init(&msg);
0063 spi_message_add_tail(&xfer[0], &msg);
0064
0065 memcpy(&buf_tx->cmd, reg_buf, sizeof(buf_tx->cmd.cmd) +
0066 sizeof(buf_tx->cmd.addr));
0067 tcan4x5x_spi_cmd_set_len(&buf_tx->cmd, val_len);
0068
0069 if (spi->controller->flags & SPI_CONTROLLER_HALF_DUPLEX) {
0070 xfer[0].len = sizeof(buf_tx->cmd);
0071
0072 xfer[1].rx_buf = val_buf;
0073 xfer[1].len = val_len;
0074 spi_message_add_tail(&xfer[1], &msg);
0075 } else {
0076 xfer[0].rx_buf = buf_rx;
0077 xfer[0].len = sizeof(buf_tx->cmd) + val_len;
0078
0079 if (TCAN4X5X_SANITIZE_SPI)
0080 memset(buf_tx->data, 0x0, val_len);
0081 }
0082
0083 err = spi_sync(spi, &msg);
0084 if (err)
0085 return err;
0086
0087 if (!(spi->controller->flags & SPI_CONTROLLER_HALF_DUPLEX))
0088 memcpy(val_buf, buf_rx->data, val_len);
0089
0090 return 0;
0091 }
0092
0093 static const struct regmap_range tcan4x5x_reg_table_yes_range[] = {
0094 regmap_reg_range(0x0000, 0x002c),
0095 regmap_reg_range(0x0800, 0x083c),
0096 regmap_reg_range(0x1000, 0x10fc),
0097 regmap_reg_range(0x8000, 0x87fc),
0098 };
0099
0100 static const struct regmap_access_table tcan4x5x_reg_table = {
0101 .yes_ranges = tcan4x5x_reg_table_yes_range,
0102 .n_yes_ranges = ARRAY_SIZE(tcan4x5x_reg_table_yes_range),
0103 };
0104
0105 static const struct regmap_config tcan4x5x_regmap = {
0106 .reg_bits = 24,
0107 .reg_stride = 4,
0108 .pad_bits = 8,
0109 .val_bits = 32,
0110 .wr_table = &tcan4x5x_reg_table,
0111 .rd_table = &tcan4x5x_reg_table,
0112 .max_register = TCAN4X5X_MAX_REGISTER,
0113 .cache_type = REGCACHE_NONE,
0114 .read_flag_mask = (__force unsigned long)
0115 cpu_to_be32(TCAN4X5X_SPI_INSTRUCTION_READ),
0116 .write_flag_mask = (__force unsigned long)
0117 cpu_to_be32(TCAN4X5X_SPI_INSTRUCTION_WRITE),
0118 };
0119
0120 static const struct regmap_bus tcan4x5x_bus = {
0121 .write = tcan4x5x_regmap_write,
0122 .gather_write = tcan4x5x_regmap_gather_write,
0123 .read = tcan4x5x_regmap_read,
0124 .reg_format_endian_default = REGMAP_ENDIAN_BIG,
0125 .val_format_endian_default = REGMAP_ENDIAN_BIG,
0126 .max_raw_read = 256,
0127 .max_raw_write = 256,
0128 };
0129
0130 int tcan4x5x_regmap_init(struct tcan4x5x_priv *priv)
0131 {
0132 priv->regmap = devm_regmap_init(&priv->spi->dev, &tcan4x5x_bus,
0133 priv->spi, &tcan4x5x_regmap);
0134 return PTR_ERR_OR_ZERO(priv->regmap);
0135 }