Lines Matching +full:spi +full:- +full:crc

1 // SPDX-License-Identifier: GPL-2.0
3 // mcp251xfd - Microchip MCP251xFD Family CAN controller driver
6 // Marc Kleine-Budde <kernel@pengutronix.de>
18 struct spi_device *spi = context; in mcp251xfd_regmap_nocrc_write() local
20 return spi_write(spi, data, count); in mcp251xfd_regmap_nocrc_write()
28 struct spi_device *spi = context; in mcp251xfd_regmap_nocrc_gather_write() local
29 struct mcp251xfd_priv *priv = spi_get_drvdata(spi); in mcp251xfd_regmap_nocrc_gather_write()
30 struct mcp251xfd_map_buf_nocrc *buf_tx = priv->map_buf_nocrc_tx; in mcp251xfd_regmap_nocrc_gather_write()
34 .len = sizeof(buf_tx->cmd) + val_len, in mcp251xfd_regmap_nocrc_gather_write()
38 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16)); in mcp251xfd_regmap_nocrc_gather_write()
41 reg_len != sizeof(buf_tx->cmd.cmd)) in mcp251xfd_regmap_nocrc_gather_write()
42 return -EINVAL; in mcp251xfd_regmap_nocrc_gather_write()
44 memcpy(&buf_tx->cmd, reg, sizeof(buf_tx->cmd)); in mcp251xfd_regmap_nocrc_gather_write()
45 memcpy(buf_tx->data, val, val_len); in mcp251xfd_regmap_nocrc_gather_write()
47 return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer)); in mcp251xfd_regmap_nocrc_gather_write()
70 if (reg == MCP251XFD_REG_FIFOCON(ring->fifo_nr)) in mcp251xfd_update_bits_read_reg()
72 if (reg == MCP251XFD_REG_FIFOSTA(ring->fifo_nr)) in mcp251xfd_update_bits_read_reg()
86 struct spi_device *spi = context; in mcp251xfd_regmap_nocrc_update_bits() local
87 struct mcp251xfd_priv *priv = spi_get_drvdata(spi); in mcp251xfd_regmap_nocrc_update_bits()
88 struct mcp251xfd_map_buf_nocrc *buf_rx = priv->map_buf_nocrc_rx; in mcp251xfd_regmap_nocrc_update_bits()
89 struct mcp251xfd_map_buf_nocrc *buf_tx = priv->map_buf_nocrc_tx; in mcp251xfd_regmap_nocrc_update_bits()
94 BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16)); in mcp251xfd_regmap_nocrc_update_bits()
95 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16)); in mcp251xfd_regmap_nocrc_update_bits()
99 return -EINVAL; in mcp251xfd_regmap_nocrc_update_bits()
103 len = last_byte - first_byte + 1; in mcp251xfd_regmap_nocrc_update_bits()
112 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_HALF_DUPLEX) { in mcp251xfd_regmap_nocrc_update_bits()
114 xfer[0].len = sizeof(buf_tx->cmd); in mcp251xfd_regmap_nocrc_update_bits()
116 xfer[1].rx_buf = buf_rx->data; in mcp251xfd_regmap_nocrc_update_bits()
122 xfer[0].len = sizeof(buf_tx->cmd) + len; in mcp251xfd_regmap_nocrc_update_bits()
125 memset(buf_tx->data, 0x0, len); in mcp251xfd_regmap_nocrc_update_bits()
128 mcp251xfd_spi_cmd_read_nocrc(&buf_tx->cmd, reg + first_byte); in mcp251xfd_regmap_nocrc_update_bits()
129 err = spi_sync(spi, &msg); in mcp251xfd_regmap_nocrc_update_bits()
133 memcpy(&orig_le32, buf_rx->data, len); in mcp251xfd_regmap_nocrc_update_bits()
142 mcp251xfd_spi_cmd_write_nocrc(&buf_tx->cmd, reg + first_byte); in mcp251xfd_regmap_nocrc_update_bits()
143 memcpy(buf_tx->data, &tmp_le32, len); in mcp251xfd_regmap_nocrc_update_bits()
145 return spi_write(spi, buf_tx, sizeof(buf_tx->cmd) + len); in mcp251xfd_regmap_nocrc_update_bits()
153 struct spi_device *spi = context; in mcp251xfd_regmap_nocrc_read() local
154 struct mcp251xfd_priv *priv = spi_get_drvdata(spi); in mcp251xfd_regmap_nocrc_read()
155 struct mcp251xfd_map_buf_nocrc *buf_rx = priv->map_buf_nocrc_rx; in mcp251xfd_regmap_nocrc_read()
156 struct mcp251xfd_map_buf_nocrc *buf_tx = priv->map_buf_nocrc_tx; in mcp251xfd_regmap_nocrc_read()
161 BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16)); in mcp251xfd_regmap_nocrc_read()
162 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16)); in mcp251xfd_regmap_nocrc_read()
165 reg_len != sizeof(buf_tx->cmd.cmd)) in mcp251xfd_regmap_nocrc_read()
166 return -EINVAL; in mcp251xfd_regmap_nocrc_read()
171 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_HALF_DUPLEX) { in mcp251xfd_regmap_nocrc_read()
173 xfer[0].len = sizeof(buf_tx->cmd); in mcp251xfd_regmap_nocrc_read()
181 xfer[0].len = sizeof(buf_tx->cmd) + val_len; in mcp251xfd_regmap_nocrc_read()
183 memcpy(&buf_tx->cmd, reg, sizeof(buf_tx->cmd)); in mcp251xfd_regmap_nocrc_read()
185 memset(buf_tx->data, 0x0, val_len); in mcp251xfd_regmap_nocrc_read()
188 err = spi_sync(spi, &msg); in mcp251xfd_regmap_nocrc_read()
192 if (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_HALF_DUPLEX)) in mcp251xfd_regmap_nocrc_read()
193 memcpy(val_buf, buf_rx->data, val_len); in mcp251xfd_regmap_nocrc_read()
203 struct spi_device *spi = context; in mcp251xfd_regmap_crc_gather_write() local
204 struct mcp251xfd_priv *priv = spi_get_drvdata(spi); in mcp251xfd_regmap_crc_gather_write()
205 struct mcp251xfd_map_buf_crc *buf_tx = priv->map_buf_crc_tx; in mcp251xfd_regmap_crc_gather_write()
209 .len = sizeof(buf_tx->cmd) + val_len + in mcp251xfd_regmap_crc_gather_write()
210 sizeof(buf_tx->crc), in mcp251xfd_regmap_crc_gather_write()
214 u16 crc; in mcp251xfd_regmap_crc_gather_write() local
216 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16) + sizeof(u8)); in mcp251xfd_regmap_crc_gather_write()
219 reg_len != sizeof(buf_tx->cmd.cmd) + in mcp251xfd_regmap_crc_gather_write()
221 return -EINVAL; in mcp251xfd_regmap_crc_gather_write()
223 mcp251xfd_spi_cmd_write_crc(&buf_tx->cmd, reg, val_len); in mcp251xfd_regmap_crc_gather_write()
224 memcpy(buf_tx->data, val, val_len); in mcp251xfd_regmap_crc_gather_write()
226 crc = mcp251xfd_crc16_compute(buf_tx, sizeof(buf_tx->cmd) + val_len); in mcp251xfd_regmap_crc_gather_write()
227 put_unaligned_be16(crc, buf_tx->data + val_len); in mcp251xfd_regmap_crc_gather_write()
229 return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer)); in mcp251xfd_regmap_crc_gather_write()
242 count - data_offset); in mcp251xfd_regmap_crc_write()
252 crc_received = get_unaligned_be16(buf_rx->data + data_len); in mcp251xfd_regmap_crc_read_check_crc()
253 crc_calculated = mcp251xfd_crc16_compute2(&buf_tx->cmd, in mcp251xfd_regmap_crc_read_check_crc()
254 sizeof(buf_tx->cmd), in mcp251xfd_regmap_crc_read_check_crc()
255 buf_rx->data, in mcp251xfd_regmap_crc_read_check_crc()
258 return -EBADMSG; in mcp251xfd_regmap_crc_read_check_crc()
267 const struct mcp251xfd_map_buf_crc *buf_rx = priv->map_buf_crc_rx; in mcp251xfd_regmap_crc_read_one()
268 const struct mcp251xfd_map_buf_crc *buf_tx = priv->map_buf_crc_tx; in mcp251xfd_regmap_crc_read_one()
271 BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16) + sizeof(u8)); in mcp251xfd_regmap_crc_read_one()
272 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16) + sizeof(u8)); in mcp251xfd_regmap_crc_read_one()
274 err = spi_sync(priv->spi, msg); in mcp251xfd_regmap_crc_read_one()
286 struct spi_device *spi = context; in mcp251xfd_regmap_crc_read() local
287 struct mcp251xfd_priv *priv = spi_get_drvdata(spi); in mcp251xfd_regmap_crc_read()
288 struct mcp251xfd_map_buf_crc *buf_rx = priv->map_buf_crc_rx; in mcp251xfd_regmap_crc_read()
289 struct mcp251xfd_map_buf_crc *buf_tx = priv->map_buf_crc_tx; in mcp251xfd_regmap_crc_read()
295 BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16) + sizeof(u8)); in mcp251xfd_regmap_crc_read()
296 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16) + sizeof(u8)); in mcp251xfd_regmap_crc_read()
299 reg_len != sizeof(buf_tx->cmd.cmd) + in mcp251xfd_regmap_crc_read()
301 return -EINVAL; in mcp251xfd_regmap_crc_read()
306 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_HALF_DUPLEX) { in mcp251xfd_regmap_crc_read()
308 xfer[0].len = sizeof(buf_tx->cmd); in mcp251xfd_regmap_crc_read()
310 xfer[1].rx_buf = buf_rx->data; in mcp251xfd_regmap_crc_read()
311 xfer[1].len = val_len + sizeof(buf_tx->crc); in mcp251xfd_regmap_crc_read()
316 xfer[0].len = sizeof(buf_tx->cmd) + val_len + in mcp251xfd_regmap_crc_read()
317 sizeof(buf_tx->crc); in mcp251xfd_regmap_crc_read()
320 memset(buf_tx->data, 0x0, val_len + in mcp251xfd_regmap_crc_read()
321 sizeof(buf_tx->crc)); in mcp251xfd_regmap_crc_read()
324 mcp251xfd_spi_cmd_read_crc(&buf_tx->cmd, reg, val_len); in mcp251xfd_regmap_crc_read()
330 if (err != -EBADMSG) in mcp251xfd_regmap_crc_read()
338 * lowest byte (which is transferred first on the SPI in mcp251xfd_regmap_crc_read()
340 * calculated CRC doesn't always match the transferred in mcp251xfd_regmap_crc_read()
345 * the transferred CRC matches the calculated one. We in mcp251xfd_regmap_crc_read()
346 * assume for now the CRC operates on the correct in mcp251xfd_regmap_crc_read()
350 ((buf_rx->data[0] & 0xf8) == 0x0 || in mcp251xfd_regmap_crc_read()
351 (buf_rx->data[0] & 0xf8) == 0x80)) { in mcp251xfd_regmap_crc_read()
353 buf_rx->data[0] ^= 0x80; in mcp251xfd_regmap_crc_read()
355 /* re-check CRC */ in mcp251xfd_regmap_crc_read()
360 /* If CRC is now correct, assume in mcp251xfd_regmap_crc_read()
369 * The chip may be in deep sleep and this SPI transfer in mcp251xfd_regmap_crc_read()
371 * up. This takes about 3ms. The CRC of this transfer in mcp251xfd_regmap_crc_read()
374 * Or there isn't a chip at all, in this case the CRC in mcp251xfd_regmap_crc_read()
377 * In both cases ignore the CRC and copy the read data in mcp251xfd_regmap_crc_read()
386 netdev_info(priv->ndev, in mcp251xfd_regmap_crc_read()
387 "CRC read error at address 0x%04x (length=%zd, data=%*ph, CRC=0x%04x) retrying.\n", in mcp251xfd_regmap_crc_read()
388 reg, val_len, (int)val_len, buf_rx->data, in mcp251xfd_regmap_crc_read()
389 get_unaligned_be16(buf_rx->data + val_len)); in mcp251xfd_regmap_crc_read()
393 netdev_err(priv->ndev, in mcp251xfd_regmap_crc_read()
394 "CRC read error at address 0x%04x (length=%zd, data=%*ph, CRC=0x%04x).\n", in mcp251xfd_regmap_crc_read()
395 reg, val_len, (int)val_len, buf_rx->data, in mcp251xfd_regmap_crc_read()
396 get_unaligned_be16(buf_rx->data + val_len)); in mcp251xfd_regmap_crc_read()
401 memcpy(val_buf, buf_rx->data, val_len); in mcp251xfd_regmap_crc_read()
445 .name = "crc",
469 return (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG)) || in mcp251xfd_regmap_use_nocrc()
470 (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_RX)); in mcp251xfd_regmap_use_nocrc()
476 return (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG) || in mcp251xfd_regmap_use_crc()
477 (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_RX); in mcp251xfd_regmap_use_crc()
483 if (!priv->map_nocrc) { in mcp251xfd_regmap_init_nocrc()
486 map = devm_regmap_init(&priv->spi->dev, &mcp251xfd_bus_nocrc, in mcp251xfd_regmap_init_nocrc()
487 priv->spi, &mcp251xfd_regmap_nocrc); in mcp251xfd_regmap_init_nocrc()
491 priv->map_nocrc = map; in mcp251xfd_regmap_init_nocrc()
494 if (!priv->map_buf_nocrc_rx) { in mcp251xfd_regmap_init_nocrc()
495 priv->map_buf_nocrc_rx = in mcp251xfd_regmap_init_nocrc()
496 devm_kzalloc(&priv->spi->dev, in mcp251xfd_regmap_init_nocrc()
497 sizeof(*priv->map_buf_nocrc_rx), in mcp251xfd_regmap_init_nocrc()
499 if (!priv->map_buf_nocrc_rx) in mcp251xfd_regmap_init_nocrc()
500 return -ENOMEM; in mcp251xfd_regmap_init_nocrc()
503 if (!priv->map_buf_nocrc_tx) { in mcp251xfd_regmap_init_nocrc()
504 priv->map_buf_nocrc_tx = in mcp251xfd_regmap_init_nocrc()
505 devm_kzalloc(&priv->spi->dev, in mcp251xfd_regmap_init_nocrc()
506 sizeof(*priv->map_buf_nocrc_tx), in mcp251xfd_regmap_init_nocrc()
508 if (!priv->map_buf_nocrc_tx) in mcp251xfd_regmap_init_nocrc()
509 return -ENOMEM; in mcp251xfd_regmap_init_nocrc()
512 if (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG)) in mcp251xfd_regmap_init_nocrc()
513 priv->map_reg = priv->map_nocrc; in mcp251xfd_regmap_init_nocrc()
515 if (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_RX)) in mcp251xfd_regmap_init_nocrc()
516 priv->map_rx = priv->map_nocrc; in mcp251xfd_regmap_init_nocrc()
523 if (priv->map_buf_nocrc_rx) { in mcp251xfd_regmap_destroy_nocrc()
524 devm_kfree(&priv->spi->dev, priv->map_buf_nocrc_rx); in mcp251xfd_regmap_destroy_nocrc()
525 priv->map_buf_nocrc_rx = NULL; in mcp251xfd_regmap_destroy_nocrc()
527 if (priv->map_buf_nocrc_tx) { in mcp251xfd_regmap_destroy_nocrc()
528 devm_kfree(&priv->spi->dev, priv->map_buf_nocrc_tx); in mcp251xfd_regmap_destroy_nocrc()
529 priv->map_buf_nocrc_tx = NULL; in mcp251xfd_regmap_destroy_nocrc()
536 if (!priv->map_crc) { in mcp251xfd_regmap_init_crc()
539 map = devm_regmap_init(&priv->spi->dev, &mcp251xfd_bus_crc, in mcp251xfd_regmap_init_crc()
540 priv->spi, &mcp251xfd_regmap_crc); in mcp251xfd_regmap_init_crc()
544 priv->map_crc = map; in mcp251xfd_regmap_init_crc()
547 if (!priv->map_buf_crc_rx) { in mcp251xfd_regmap_init_crc()
548 priv->map_buf_crc_rx = in mcp251xfd_regmap_init_crc()
549 devm_kzalloc(&priv->spi->dev, in mcp251xfd_regmap_init_crc()
550 sizeof(*priv->map_buf_crc_rx), in mcp251xfd_regmap_init_crc()
552 if (!priv->map_buf_crc_rx) in mcp251xfd_regmap_init_crc()
553 return -ENOMEM; in mcp251xfd_regmap_init_crc()
556 if (!priv->map_buf_crc_tx) { in mcp251xfd_regmap_init_crc()
557 priv->map_buf_crc_tx = in mcp251xfd_regmap_init_crc()
558 devm_kzalloc(&priv->spi->dev, in mcp251xfd_regmap_init_crc()
559 sizeof(*priv->map_buf_crc_tx), in mcp251xfd_regmap_init_crc()
561 if (!priv->map_buf_crc_tx) in mcp251xfd_regmap_init_crc()
562 return -ENOMEM; in mcp251xfd_regmap_init_crc()
565 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG) in mcp251xfd_regmap_init_crc()
566 priv->map_reg = priv->map_crc; in mcp251xfd_regmap_init_crc()
568 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_RX) in mcp251xfd_regmap_init_crc()
569 priv->map_rx = priv->map_crc; in mcp251xfd_regmap_init_crc()
576 if (priv->map_buf_crc_rx) { in mcp251xfd_regmap_destroy_crc()
577 devm_kfree(&priv->spi->dev, priv->map_buf_crc_rx); in mcp251xfd_regmap_destroy_crc()
578 priv->map_buf_crc_rx = NULL; in mcp251xfd_regmap_destroy_crc()
580 if (priv->map_buf_crc_tx) { in mcp251xfd_regmap_destroy_crc()
581 devm_kfree(&priv->spi->dev, priv->map_buf_crc_tx); in mcp251xfd_regmap_destroy_crc()
582 priv->map_buf_crc_tx = NULL; in mcp251xfd_regmap_destroy_crc()