linux/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2//
   3// mcp251xfd - Microchip MCP251xFD Family CAN controller driver
   4//
   5// Copyright (c) 2019, 2020, 2021 Pengutronix,
   6//               Marc Kleine-Budde <kernel@pengutronix.de>
   7//
   8
   9#include "mcp251xfd.h"
  10
  11#include <asm/unaligned.h>
  12
  13static const struct regmap_config mcp251xfd_regmap_crc;
  14
  15static int
  16mcp251xfd_regmap_nocrc_write(void *context, const void *data, size_t count)
  17{
  18        struct spi_device *spi = context;
  19
  20        return spi_write(spi, data, count);
  21}
  22
  23static int
  24mcp251xfd_regmap_nocrc_gather_write(void *context,
  25                                    const void *reg, size_t reg_len,
  26                                    const void *val, size_t val_len)
  27{
  28        struct spi_device *spi = context;
  29        struct mcp251xfd_priv *priv = spi_get_drvdata(spi);
  30        struct mcp251xfd_map_buf_nocrc *buf_tx = priv->map_buf_nocrc_tx;
  31        struct spi_transfer xfer[] = {
  32                {
  33                        .tx_buf = buf_tx,
  34                        .len = sizeof(buf_tx->cmd) + val_len,
  35                },
  36        };
  37
  38        BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16));
  39
  40        if (IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY) &&
  41            reg_len != sizeof(buf_tx->cmd.cmd))
  42                return -EINVAL;
  43
  44        memcpy(&buf_tx->cmd, reg, sizeof(buf_tx->cmd));
  45        memcpy(buf_tx->data, val, val_len);
  46
  47        return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
  48}
  49
  50static inline bool
  51mcp251xfd_update_bits_read_reg(const struct mcp251xfd_priv *priv,
  52                               unsigned int reg)
  53{
  54        struct mcp251xfd_rx_ring *ring;
  55        int n;
  56
  57        switch (reg) {
  58        case MCP251XFD_REG_INT:
  59        case MCP251XFD_REG_TEFCON:
  60        case MCP251XFD_REG_FLTCON(0):
  61        case MCP251XFD_REG_ECCSTAT:
  62        case MCP251XFD_REG_CRC:
  63                return false;
  64        case MCP251XFD_REG_CON:
  65        case MCP251XFD_REG_OSC:
  66        case MCP251XFD_REG_ECCCON:
  67                return true;
  68        default:
  69                mcp251xfd_for_each_rx_ring(priv, ring, n) {
  70                        if (reg == MCP251XFD_REG_FIFOCON(ring->fifo_nr))
  71                                return false;
  72                        if (reg == MCP251XFD_REG_FIFOSTA(ring->fifo_nr))
  73                                return true;
  74                }
  75
  76                WARN(1, "Status of reg 0x%04x unknown.\n", reg);
  77        }
  78
  79        return true;
  80}
  81
  82static int
  83mcp251xfd_regmap_nocrc_update_bits(void *context, unsigned int reg,
  84                                   unsigned int mask, unsigned int val)
  85{
  86        struct spi_device *spi = context;
  87        struct mcp251xfd_priv *priv = spi_get_drvdata(spi);
  88        struct mcp251xfd_map_buf_nocrc *buf_rx = priv->map_buf_nocrc_rx;
  89        struct mcp251xfd_map_buf_nocrc *buf_tx = priv->map_buf_nocrc_tx;
  90        __le32 orig_le32 = 0, mask_le32, val_le32, tmp_le32;
  91        u8 first_byte, last_byte, len;
  92        int err;
  93
  94        BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16));
  95        BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16));
  96
  97        if (IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY) &&
  98            mask == 0)
  99                return -EINVAL;
 100
 101        first_byte = mcp251xfd_first_byte_set(mask);
 102        last_byte = mcp251xfd_last_byte_set(mask);
 103        len = last_byte - first_byte + 1;
 104
 105        if (mcp251xfd_update_bits_read_reg(priv, reg)) {
 106                struct spi_transfer xfer[2] = { };
 107                struct spi_message msg;
 108
 109                spi_message_init(&msg);
 110                spi_message_add_tail(&xfer[0], &msg);
 111
 112                if (priv->devtype_data.quirks & MCP251XFD_QUIRK_HALF_DUPLEX) {
 113                        xfer[0].tx_buf = buf_tx;
 114                        xfer[0].len = sizeof(buf_tx->cmd);
 115
 116                        xfer[1].rx_buf = buf_rx->data;
 117                        xfer[1].len = len;
 118                        spi_message_add_tail(&xfer[1], &msg);
 119                } else {
 120                        xfer[0].tx_buf = buf_tx;
 121                        xfer[0].rx_buf = buf_rx;
 122                        xfer[0].len = sizeof(buf_tx->cmd) + len;
 123
 124                        if (MCP251XFD_SANITIZE_SPI)
 125                                memset(buf_tx->data, 0x0, len);
 126                }
 127
 128                mcp251xfd_spi_cmd_read_nocrc(&buf_tx->cmd, reg + first_byte);
 129                err = spi_sync(spi, &msg);
 130                if (err)
 131                        return err;
 132
 133                memcpy(&orig_le32, buf_rx->data, len);
 134        }
 135
 136        mask_le32 = cpu_to_le32(mask >> BITS_PER_BYTE * first_byte);
 137        val_le32 = cpu_to_le32(val >> BITS_PER_BYTE * first_byte);
 138
 139        tmp_le32 = orig_le32 & ~mask_le32;
 140        tmp_le32 |= val_le32 & mask_le32;
 141
 142        mcp251xfd_spi_cmd_write_nocrc(&buf_tx->cmd, reg + first_byte);
 143        memcpy(buf_tx->data, &tmp_le32, len);
 144
 145        return spi_write(spi, buf_tx, sizeof(buf_tx->cmd) + len);
 146}
 147
 148static int
 149mcp251xfd_regmap_nocrc_read(void *context,
 150                            const void *reg, size_t reg_len,
 151                            void *val_buf, size_t val_len)
 152{
 153        struct spi_device *spi = context;
 154        struct mcp251xfd_priv *priv = spi_get_drvdata(spi);
 155        struct mcp251xfd_map_buf_nocrc *buf_rx = priv->map_buf_nocrc_rx;
 156        struct mcp251xfd_map_buf_nocrc *buf_tx = priv->map_buf_nocrc_tx;
 157        struct spi_transfer xfer[2] = { };
 158        struct spi_message msg;
 159        int err;
 160
 161        BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16));
 162        BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16));
 163
 164        if (IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY) &&
 165            reg_len != sizeof(buf_tx->cmd.cmd))
 166                return -EINVAL;
 167
 168        spi_message_init(&msg);
 169        spi_message_add_tail(&xfer[0], &msg);
 170
 171        if (priv->devtype_data.quirks & MCP251XFD_QUIRK_HALF_DUPLEX) {
 172                xfer[0].tx_buf = reg;
 173                xfer[0].len = sizeof(buf_tx->cmd);
 174
 175                xfer[1].rx_buf = val_buf;
 176                xfer[1].len = val_len;
 177                spi_message_add_tail(&xfer[1], &msg);
 178        } else {
 179                xfer[0].tx_buf = buf_tx;
 180                xfer[0].rx_buf = buf_rx;
 181                xfer[0].len = sizeof(buf_tx->cmd) + val_len;
 182
 183                memcpy(&buf_tx->cmd, reg, sizeof(buf_tx->cmd));
 184                if (MCP251XFD_SANITIZE_SPI)
 185                        memset(buf_tx->data, 0x0, val_len);
 186        }
 187
 188        err = spi_sync(spi, &msg);
 189        if (err)
 190                return err;
 191
 192        if (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_HALF_DUPLEX))
 193                memcpy(val_buf, buf_rx->data, val_len);
 194
 195        return 0;
 196}
 197
 198static int
 199mcp251xfd_regmap_crc_gather_write(void *context,
 200                                  const void *reg_p, size_t reg_len,
 201                                  const void *val, size_t val_len)
 202{
 203        struct spi_device *spi = context;
 204        struct mcp251xfd_priv *priv = spi_get_drvdata(spi);
 205        struct mcp251xfd_map_buf_crc *buf_tx = priv->map_buf_crc_tx;
 206        struct spi_transfer xfer[] = {
 207                {
 208                        .tx_buf = buf_tx,
 209                        .len = sizeof(buf_tx->cmd) + val_len +
 210                                sizeof(buf_tx->crc),
 211                },
 212        };
 213        u16 reg = *(u16 *)reg_p;
 214        u16 crc;
 215
 216        BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16) + sizeof(u8));
 217
 218        if (IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY) &&
 219            reg_len != sizeof(buf_tx->cmd.cmd) +
 220            mcp251xfd_regmap_crc.pad_bits / BITS_PER_BYTE)
 221                return -EINVAL;
 222
 223        mcp251xfd_spi_cmd_write_crc(&buf_tx->cmd, reg, val_len);
 224        memcpy(buf_tx->data, val, val_len);
 225
 226        crc = mcp251xfd_crc16_compute(buf_tx, sizeof(buf_tx->cmd) + val_len);
 227        put_unaligned_be16(crc, buf_tx->data + val_len);
 228
 229        return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
 230}
 231
 232static int
 233mcp251xfd_regmap_crc_write(void *context,
 234                           const void *data, size_t count)
 235{
 236        const size_t data_offset = sizeof(__be16) +
 237                mcp251xfd_regmap_crc.pad_bits / BITS_PER_BYTE;
 238
 239        return mcp251xfd_regmap_crc_gather_write(context,
 240                                                 data, data_offset,
 241                                                 data + data_offset,
 242                                                 count - data_offset);
 243}
 244
 245static int
 246mcp251xfd_regmap_crc_read_check_crc(const struct mcp251xfd_map_buf_crc * const buf_rx,
 247                                    const struct mcp251xfd_map_buf_crc * const buf_tx,
 248                                    unsigned int data_len)
 249{
 250        u16 crc_received, crc_calculated;
 251
 252        crc_received = get_unaligned_be16(buf_rx->data + data_len);
 253        crc_calculated = mcp251xfd_crc16_compute2(&buf_tx->cmd,
 254                                                  sizeof(buf_tx->cmd),
 255                                                  buf_rx->data,
 256                                                  data_len);
 257        if (crc_received != crc_calculated)
 258                return -EBADMSG;
 259
 260        return 0;
 261}
 262
 263static int
 264mcp251xfd_regmap_crc_read_one(struct mcp251xfd_priv *priv,
 265                              struct spi_message *msg, unsigned int data_len)
 266{
 267        const struct mcp251xfd_map_buf_crc *buf_rx = priv->map_buf_crc_rx;
 268        const struct mcp251xfd_map_buf_crc *buf_tx = priv->map_buf_crc_tx;
 269        int err;
 270
 271        BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16) + sizeof(u8));
 272        BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16) + sizeof(u8));
 273
 274        err = spi_sync(priv->spi, msg);
 275        if (err)
 276                return err;
 277
 278        return mcp251xfd_regmap_crc_read_check_crc(buf_rx, buf_tx, data_len);
 279}
 280
 281static int
 282mcp251xfd_regmap_crc_read(void *context,
 283                          const void *reg_p, size_t reg_len,
 284                          void *val_buf, size_t val_len)
 285{
 286        struct spi_device *spi = context;
 287        struct mcp251xfd_priv *priv = spi_get_drvdata(spi);
 288        struct mcp251xfd_map_buf_crc *buf_rx = priv->map_buf_crc_rx;
 289        struct mcp251xfd_map_buf_crc *buf_tx = priv->map_buf_crc_tx;
 290        struct spi_transfer xfer[2] = { };
 291        struct spi_message msg;
 292        u16 reg = *(u16 *)reg_p;
 293        int i, err;
 294
 295        BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16) + sizeof(u8));
 296        BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16) + sizeof(u8));
 297
 298        if (IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY) &&
 299            reg_len != sizeof(buf_tx->cmd.cmd) +
 300            mcp251xfd_regmap_crc.pad_bits / BITS_PER_BYTE)
 301                return -EINVAL;
 302
 303        spi_message_init(&msg);
 304        spi_message_add_tail(&xfer[0], &msg);
 305
 306        if (priv->devtype_data.quirks & MCP251XFD_QUIRK_HALF_DUPLEX) {
 307                xfer[0].tx_buf = buf_tx;
 308                xfer[0].len = sizeof(buf_tx->cmd);
 309
 310                xfer[1].rx_buf = buf_rx->data;
 311                xfer[1].len = val_len + sizeof(buf_tx->crc);
 312                spi_message_add_tail(&xfer[1], &msg);
 313        } else {
 314                xfer[0].tx_buf = buf_tx;
 315                xfer[0].rx_buf = buf_rx;
 316                xfer[0].len = sizeof(buf_tx->cmd) + val_len +
 317                        sizeof(buf_tx->crc);
 318
 319                if (MCP251XFD_SANITIZE_SPI)
 320                        memset(buf_tx->data, 0x0, val_len +
 321                               sizeof(buf_tx->crc));
 322        }
 323
 324        mcp251xfd_spi_cmd_read_crc(&buf_tx->cmd, reg, val_len);
 325
 326        for (i = 0; i < MCP251XFD_READ_CRC_RETRIES_MAX; i++) {
 327                err = mcp251xfd_regmap_crc_read_one(priv, &msg, val_len);
 328                if (!err)
 329                        goto out;
 330                if (err != -EBADMSG)
 331                        return err;
 332
 333                /* MCP251XFD_REG_TBC is the time base counter
 334                 * register. It increments once per SYS clock tick,
 335                 * which is 20 or 40 MHz.
 336                 *
 337                 * Observation on the mcp2518fd shows that if the
 338                 * lowest byte (which is transferred first on the SPI
 339                 * bus) of that register is 0x00 or 0x80 the
 340                 * calculated CRC doesn't always match the transferred
 341                 * one. On the mcp2517fd this problem is not limited
 342                 * to the first byte being 0x00 or 0x80.
 343                 *
 344                 * If the highest bit in the lowest byte is flipped
 345                 * the transferred CRC matches the calculated one. We
 346                 * assume for now the CRC operates on the correct
 347                 * data.
 348                 */
 349                if (reg == MCP251XFD_REG_TBC &&
 350                    ((buf_rx->data[0] & 0xf8) == 0x0 ||
 351                     (buf_rx->data[0] & 0xf8) == 0x80)) {
 352                        /* Flip highest bit in lowest byte of le32 */
 353                        buf_rx->data[0] ^= 0x80;
 354
 355                        /* re-check CRC */
 356                        err = mcp251xfd_regmap_crc_read_check_crc(buf_rx,
 357                                                                  buf_tx,
 358                                                                  val_len);
 359                        if (!err) {
 360                                /* If CRC is now correct, assume
 361                                 * flipped data is OK.
 362                                 */
 363                                goto out;
 364                        }
 365                }
 366
 367                /* MCP251XFD_REG_OSC is the first ever reg we read from.
 368                 *
 369                 * The chip may be in deep sleep and this SPI transfer
 370                 * (i.e. the assertion of the CS) will wake the chip
 371                 * up. This takes about 3ms. The CRC of this transfer
 372                 * is wrong.
 373                 *
 374                 * Or there isn't a chip at all, in this case the CRC
 375                 * will be wrong, too.
 376                 *
 377                 * In both cases ignore the CRC and copy the read data
 378                 * to the caller. It will take care of both cases.
 379                 *
 380                 */
 381                if (reg == MCP251XFD_REG_OSC && val_len == sizeof(__le32)) {
 382                        err = 0;
 383                        goto out;
 384                }
 385
 386                netdev_info(priv->ndev,
 387                            "CRC read error at address 0x%04x (length=%zd, data=%*ph, CRC=0x%04x) retrying.\n",
 388                            reg, val_len, (int)val_len, buf_rx->data,
 389                            get_unaligned_be16(buf_rx->data + val_len));
 390        }
 391
 392        if (err) {
 393                netdev_err(priv->ndev,
 394                           "CRC read error at address 0x%04x (length=%zd, data=%*ph, CRC=0x%04x).\n",
 395                           reg, val_len, (int)val_len, buf_rx->data,
 396                           get_unaligned_be16(buf_rx->data + val_len));
 397
 398                return err;
 399        }
 400 out:
 401        memcpy(val_buf, buf_rx->data, val_len);
 402
 403        return 0;
 404}
 405
 406static const struct regmap_range mcp251xfd_reg_table_yes_range[] = {
 407        regmap_reg_range(0x000, 0x2ec), /* CAN FD Controller Module SFR */
 408        regmap_reg_range(0x400, 0xbfc), /* RAM */
 409        regmap_reg_range(0xe00, 0xe14), /* MCP2517/18FD SFR */
 410};
 411
 412static const struct regmap_access_table mcp251xfd_reg_table = {
 413        .yes_ranges = mcp251xfd_reg_table_yes_range,
 414        .n_yes_ranges = ARRAY_SIZE(mcp251xfd_reg_table_yes_range),
 415};
 416
 417static const struct regmap_config mcp251xfd_regmap_nocrc = {
 418        .name = "nocrc",
 419        .reg_bits = 16,
 420        .reg_stride = 4,
 421        .pad_bits = 0,
 422        .val_bits = 32,
 423        .max_register = 0xffc,
 424        .wr_table = &mcp251xfd_reg_table,
 425        .rd_table = &mcp251xfd_reg_table,
 426        .cache_type = REGCACHE_NONE,
 427        .read_flag_mask = (__force unsigned long)
 428                cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_READ),
 429        .write_flag_mask = (__force unsigned long)
 430                cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_WRITE),
 431};
 432
 433static const struct regmap_bus mcp251xfd_bus_nocrc = {
 434        .write = mcp251xfd_regmap_nocrc_write,
 435        .gather_write = mcp251xfd_regmap_nocrc_gather_write,
 436        .reg_update_bits = mcp251xfd_regmap_nocrc_update_bits,
 437        .read = mcp251xfd_regmap_nocrc_read,
 438        .reg_format_endian_default = REGMAP_ENDIAN_BIG,
 439        .val_format_endian_default = REGMAP_ENDIAN_LITTLE,
 440        .max_raw_read = sizeof_field(struct mcp251xfd_map_buf_nocrc, data),
 441        .max_raw_write = sizeof_field(struct mcp251xfd_map_buf_nocrc, data),
 442};
 443
 444static const struct regmap_config mcp251xfd_regmap_crc = {
 445        .name = "crc",
 446        .reg_bits = 16,
 447        .reg_stride = 4,
 448        .pad_bits = 16,         /* keep data bits aligned */
 449        .val_bits = 32,
 450        .max_register = 0xffc,
 451        .wr_table = &mcp251xfd_reg_table,
 452        .rd_table = &mcp251xfd_reg_table,
 453        .cache_type = REGCACHE_NONE,
 454};
 455
 456static const struct regmap_bus mcp251xfd_bus_crc = {
 457        .write = mcp251xfd_regmap_crc_write,
 458        .gather_write = mcp251xfd_regmap_crc_gather_write,
 459        .read = mcp251xfd_regmap_crc_read,
 460        .reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
 461        .val_format_endian_default = REGMAP_ENDIAN_LITTLE,
 462        .max_raw_read = sizeof_field(struct mcp251xfd_map_buf_crc, data),
 463        .max_raw_write = sizeof_field(struct mcp251xfd_map_buf_crc, data),
 464};
 465
 466static inline bool
 467mcp251xfd_regmap_use_nocrc(struct mcp251xfd_priv *priv)
 468{
 469        return (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG)) ||
 470                (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_RX));
 471}
 472
 473static inline bool
 474mcp251xfd_regmap_use_crc(struct mcp251xfd_priv *priv)
 475{
 476        return (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG) ||
 477                (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_RX);
 478}
 479
 480static int
 481mcp251xfd_regmap_init_nocrc(struct mcp251xfd_priv *priv)
 482{
 483        if (!priv->map_nocrc) {
 484                struct regmap *map;
 485
 486                map = devm_regmap_init(&priv->spi->dev, &mcp251xfd_bus_nocrc,
 487                                       priv->spi, &mcp251xfd_regmap_nocrc);
 488                if (IS_ERR(map))
 489                        return PTR_ERR(map);
 490
 491                priv->map_nocrc = map;
 492        }
 493
 494        if (!priv->map_buf_nocrc_rx) {
 495                priv->map_buf_nocrc_rx =
 496                        devm_kzalloc(&priv->spi->dev,
 497                                     sizeof(*priv->map_buf_nocrc_rx),
 498                                     GFP_KERNEL);
 499                if (!priv->map_buf_nocrc_rx)
 500                        return -ENOMEM;
 501        }
 502
 503        if (!priv->map_buf_nocrc_tx) {
 504                priv->map_buf_nocrc_tx =
 505                        devm_kzalloc(&priv->spi->dev,
 506                                     sizeof(*priv->map_buf_nocrc_tx),
 507                                     GFP_KERNEL);
 508                if (!priv->map_buf_nocrc_tx)
 509                        return -ENOMEM;
 510        }
 511
 512        if (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG))
 513                priv->map_reg = priv->map_nocrc;
 514
 515        if (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_RX))
 516                priv->map_rx = priv->map_nocrc;
 517
 518        return 0;
 519}
 520
 521static void mcp251xfd_regmap_destroy_nocrc(struct mcp251xfd_priv *priv)
 522{
 523        if (priv->map_buf_nocrc_rx) {
 524                devm_kfree(&priv->spi->dev, priv->map_buf_nocrc_rx);
 525                priv->map_buf_nocrc_rx = NULL;
 526        }
 527        if (priv->map_buf_nocrc_tx) {
 528                devm_kfree(&priv->spi->dev, priv->map_buf_nocrc_tx);
 529                priv->map_buf_nocrc_tx = NULL;
 530        }
 531}
 532
 533static int
 534mcp251xfd_regmap_init_crc(struct mcp251xfd_priv *priv)
 535{
 536        if (!priv->map_crc) {
 537                struct regmap *map;
 538
 539                map = devm_regmap_init(&priv->spi->dev, &mcp251xfd_bus_crc,
 540                                       priv->spi, &mcp251xfd_regmap_crc);
 541                if (IS_ERR(map))
 542                        return PTR_ERR(map);
 543
 544                priv->map_crc = map;
 545        }
 546
 547        if (!priv->map_buf_crc_rx) {
 548                priv->map_buf_crc_rx =
 549                        devm_kzalloc(&priv->spi->dev,
 550                                     sizeof(*priv->map_buf_crc_rx),
 551                                     GFP_KERNEL);
 552                if (!priv->map_buf_crc_rx)
 553                        return -ENOMEM;
 554        }
 555
 556        if (!priv->map_buf_crc_tx) {
 557                priv->map_buf_crc_tx =
 558                        devm_kzalloc(&priv->spi->dev,
 559                                     sizeof(*priv->map_buf_crc_tx),
 560                                     GFP_KERNEL);
 561                if (!priv->map_buf_crc_tx)
 562                        return -ENOMEM;
 563        }
 564
 565        if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG)
 566                priv->map_reg = priv->map_crc;
 567
 568        if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_RX)
 569                priv->map_rx = priv->map_crc;
 570
 571        return 0;
 572}
 573
 574static void mcp251xfd_regmap_destroy_crc(struct mcp251xfd_priv *priv)
 575{
 576        if (priv->map_buf_crc_rx) {
 577                devm_kfree(&priv->spi->dev, priv->map_buf_crc_rx);
 578                priv->map_buf_crc_rx = NULL;
 579        }
 580        if (priv->map_buf_crc_tx) {
 581                devm_kfree(&priv->spi->dev, priv->map_buf_crc_tx);
 582                priv->map_buf_crc_tx = NULL;
 583        }
 584}
 585
 586int mcp251xfd_regmap_init(struct mcp251xfd_priv *priv)
 587{
 588        int err;
 589
 590        if (mcp251xfd_regmap_use_nocrc(priv)) {
 591                err = mcp251xfd_regmap_init_nocrc(priv);
 592
 593                if (err)
 594                        return err;
 595        } else {
 596                mcp251xfd_regmap_destroy_nocrc(priv);
 597        }
 598
 599        if (mcp251xfd_regmap_use_crc(priv)) {
 600                err = mcp251xfd_regmap_init_crc(priv);
 601
 602                if (err)
 603                        return err;
 604        } else {
 605                mcp251xfd_regmap_destroy_crc(priv);
 606        }
 607
 608        return 0;
 609}
 610