Lines Matching +full:flip +full:- +full:chip
1 // SPDX-License-Identifier: GPL-2.0
3 // mcp251xfd - Microchip MCP251xFD Family CAN controller driver
6 // Marc Kleine-Budde <kernel@pengutronix.de>
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()
78 struct mcp251xfd_map_buf_nocrc *buf_rx = priv->map_buf_nocrc_rx; in mcp251xfd_regmap_nocrc_update_bits()
79 struct mcp251xfd_map_buf_nocrc *buf_tx = priv->map_buf_nocrc_tx; in mcp251xfd_regmap_nocrc_update_bits()
84 BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16)); in mcp251xfd_regmap_nocrc_update_bits()
85 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16)); in mcp251xfd_regmap_nocrc_update_bits()
89 return -EINVAL; in mcp251xfd_regmap_nocrc_update_bits()
93 len = last_byte - first_byte + 1; in mcp251xfd_regmap_nocrc_update_bits()
102 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_HALF_DUPLEX) { in mcp251xfd_regmap_nocrc_update_bits()
104 xfer[0].len = sizeof(buf_tx->cmd); in mcp251xfd_regmap_nocrc_update_bits()
106 xfer[1].rx_buf = buf_rx->data; in mcp251xfd_regmap_nocrc_update_bits()
112 xfer[0].len = sizeof(buf_tx->cmd) + len; in mcp251xfd_regmap_nocrc_update_bits()
115 memset(buf_tx->data, 0x0, len); in mcp251xfd_regmap_nocrc_update_bits()
118 mcp251xfd_spi_cmd_read_nocrc(&buf_tx->cmd, reg + first_byte); in mcp251xfd_regmap_nocrc_update_bits()
123 memcpy(&orig_le32, buf_rx->data, len); in mcp251xfd_regmap_nocrc_update_bits()
132 mcp251xfd_spi_cmd_write_nocrc(&buf_tx->cmd, reg + first_byte); in mcp251xfd_regmap_nocrc_update_bits()
133 memcpy(buf_tx->data, &tmp_le32, len); in mcp251xfd_regmap_nocrc_update_bits()
135 return spi_write(spi, buf_tx, sizeof(buf_tx->cmd) + len); in mcp251xfd_regmap_nocrc_update_bits()
145 struct mcp251xfd_map_buf_nocrc *buf_rx = priv->map_buf_nocrc_rx; in mcp251xfd_regmap_nocrc_read()
146 struct mcp251xfd_map_buf_nocrc *buf_tx = priv->map_buf_nocrc_tx; in mcp251xfd_regmap_nocrc_read()
151 BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16)); in mcp251xfd_regmap_nocrc_read()
152 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16)); in mcp251xfd_regmap_nocrc_read()
155 reg_len != sizeof(buf_tx->cmd.cmd)) in mcp251xfd_regmap_nocrc_read()
156 return -EINVAL; in mcp251xfd_regmap_nocrc_read()
161 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_HALF_DUPLEX) { in mcp251xfd_regmap_nocrc_read()
163 xfer[0].len = sizeof(buf_tx->cmd); in mcp251xfd_regmap_nocrc_read()
171 xfer[0].len = sizeof(buf_tx->cmd) + val_len; in mcp251xfd_regmap_nocrc_read()
173 memcpy(&buf_tx->cmd, reg, sizeof(buf_tx->cmd)); in mcp251xfd_regmap_nocrc_read()
175 memset(buf_tx->data, 0x0, val_len); in mcp251xfd_regmap_nocrc_read()
182 if (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_HALF_DUPLEX)) in mcp251xfd_regmap_nocrc_read()
183 memcpy(val_buf, buf_rx->data, val_len); in mcp251xfd_regmap_nocrc_read()
195 struct mcp251xfd_map_buf_crc *buf_tx = priv->map_buf_crc_tx; in mcp251xfd_regmap_crc_gather_write()
199 .len = sizeof(buf_tx->cmd) + val_len + in mcp251xfd_regmap_crc_gather_write()
200 sizeof(buf_tx->crc), in mcp251xfd_regmap_crc_gather_write()
206 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16) + sizeof(u8)); in mcp251xfd_regmap_crc_gather_write()
209 reg_len != sizeof(buf_tx->cmd.cmd) + in mcp251xfd_regmap_crc_gather_write()
211 return -EINVAL; in mcp251xfd_regmap_crc_gather_write()
213 mcp251xfd_spi_cmd_write_crc(&buf_tx->cmd, reg, val_len); in mcp251xfd_regmap_crc_gather_write()
214 memcpy(buf_tx->data, val, val_len); in mcp251xfd_regmap_crc_gather_write()
216 crc = mcp251xfd_crc16_compute(buf_tx, sizeof(buf_tx->cmd) + val_len); in mcp251xfd_regmap_crc_gather_write()
217 put_unaligned_be16(crc, buf_tx->data + val_len); in mcp251xfd_regmap_crc_gather_write()
232 count - data_offset); in mcp251xfd_regmap_crc_write()
242 crc_received = get_unaligned_be16(buf_rx->data + data_len); in mcp251xfd_regmap_crc_read_check_crc()
243 crc_calculated = mcp251xfd_crc16_compute2(&buf_tx->cmd, in mcp251xfd_regmap_crc_read_check_crc()
244 sizeof(buf_tx->cmd), in mcp251xfd_regmap_crc_read_check_crc()
245 buf_rx->data, in mcp251xfd_regmap_crc_read_check_crc()
248 return -EBADMSG; in mcp251xfd_regmap_crc_read_check_crc()
258 const struct mcp251xfd_map_buf_crc *buf_rx = priv->map_buf_crc_rx; in mcp251xfd_regmap_crc_read_one()
259 const struct mcp251xfd_map_buf_crc *buf_tx = priv->map_buf_crc_tx; in mcp251xfd_regmap_crc_read_one()
262 BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16) + sizeof(u8)); in mcp251xfd_regmap_crc_read_one()
263 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16) + sizeof(u8)); in mcp251xfd_regmap_crc_read_one()
265 err = spi_sync(priv->spi, msg); in mcp251xfd_regmap_crc_read_one()
279 struct mcp251xfd_map_buf_crc *buf_rx = priv->map_buf_crc_rx; in mcp251xfd_regmap_crc_read()
280 struct mcp251xfd_map_buf_crc *buf_tx = priv->map_buf_crc_tx; in mcp251xfd_regmap_crc_read()
286 BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16) + sizeof(u8)); in mcp251xfd_regmap_crc_read()
287 BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16) + sizeof(u8)); in mcp251xfd_regmap_crc_read()
290 reg_len != sizeof(buf_tx->cmd.cmd) + in mcp251xfd_regmap_crc_read()
292 return -EINVAL; in mcp251xfd_regmap_crc_read()
297 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_HALF_DUPLEX) { in mcp251xfd_regmap_crc_read()
299 xfer[0].len = sizeof(buf_tx->cmd); in mcp251xfd_regmap_crc_read()
301 xfer[1].rx_buf = buf_rx->data; in mcp251xfd_regmap_crc_read()
302 xfer[1].len = val_len + sizeof(buf_tx->crc); in mcp251xfd_regmap_crc_read()
307 xfer[0].len = sizeof(buf_tx->cmd) + val_len + in mcp251xfd_regmap_crc_read()
308 sizeof(buf_tx->crc); in mcp251xfd_regmap_crc_read()
311 memset(buf_tx->data, 0x0, val_len + in mcp251xfd_regmap_crc_read()
312 sizeof(buf_tx->crc)); in mcp251xfd_regmap_crc_read()
315 mcp251xfd_spi_cmd_read_crc(&buf_tx->cmd, reg, val_len); in mcp251xfd_regmap_crc_read()
321 if (err != -EBADMSG) in mcp251xfd_regmap_crc_read()
335 * assume for now the CRC calculation in the chip in mcp251xfd_regmap_crc_read()
340 (buf_rx->data[0] == 0x0 || buf_rx->data[0] == 0x80)) { in mcp251xfd_regmap_crc_read()
341 /* Flip highest bit in lowest byte of le32 */ in mcp251xfd_regmap_crc_read()
342 buf_rx->data[0] ^= 0x80; in mcp251xfd_regmap_crc_read()
344 /* re-check CRC */ in mcp251xfd_regmap_crc_read()
350 * transferred data was OK, flip bit in mcp251xfd_regmap_crc_read()
353 buf_rx->data[0] ^= 0x80; in mcp251xfd_regmap_crc_read()
360 * The chip may be in deep sleep and this SPI transfer in mcp251xfd_regmap_crc_read()
361 * (i.e. the assertion of the CS) will wake the chip in mcp251xfd_regmap_crc_read()
365 * Or there isn't a chip at all, in this case the CRC in mcp251xfd_regmap_crc_read()
377 netdev_info(priv->ndev, in mcp251xfd_regmap_crc_read()
379 reg, val_len, (int)val_len, buf_rx->data, in mcp251xfd_regmap_crc_read()
380 get_unaligned_be16(buf_rx->data + val_len)); in mcp251xfd_regmap_crc_read()
384 netdev_err(priv->ndev, in mcp251xfd_regmap_crc_read()
386 reg, val_len, (int)val_len, buf_rx->data, in mcp251xfd_regmap_crc_read()
387 get_unaligned_be16(buf_rx->data + val_len)); in mcp251xfd_regmap_crc_read()
392 memcpy(val_buf, buf_rx->data, val_len); in mcp251xfd_regmap_crc_read()
460 return (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG)) || in mcp251xfd_regmap_use_nocrc()
461 (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_RX)); in mcp251xfd_regmap_use_nocrc()
467 return (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG) || in mcp251xfd_regmap_use_crc()
468 (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_RX); in mcp251xfd_regmap_use_crc()
474 if (!priv->map_nocrc) { in mcp251xfd_regmap_init_nocrc()
477 map = devm_regmap_init(&priv->spi->dev, &mcp251xfd_bus_nocrc, in mcp251xfd_regmap_init_nocrc()
478 priv->spi, &mcp251xfd_regmap_nocrc); in mcp251xfd_regmap_init_nocrc()
482 priv->map_nocrc = map; in mcp251xfd_regmap_init_nocrc()
485 if (!priv->map_buf_nocrc_rx) { in mcp251xfd_regmap_init_nocrc()
486 priv->map_buf_nocrc_rx = in mcp251xfd_regmap_init_nocrc()
487 devm_kzalloc(&priv->spi->dev, in mcp251xfd_regmap_init_nocrc()
488 sizeof(*priv->map_buf_nocrc_rx), in mcp251xfd_regmap_init_nocrc()
490 if (!priv->map_buf_nocrc_rx) in mcp251xfd_regmap_init_nocrc()
491 return -ENOMEM; in mcp251xfd_regmap_init_nocrc()
494 if (!priv->map_buf_nocrc_tx) { in mcp251xfd_regmap_init_nocrc()
495 priv->map_buf_nocrc_tx = in mcp251xfd_regmap_init_nocrc()
496 devm_kzalloc(&priv->spi->dev, in mcp251xfd_regmap_init_nocrc()
497 sizeof(*priv->map_buf_nocrc_tx), in mcp251xfd_regmap_init_nocrc()
499 if (!priv->map_buf_nocrc_tx) in mcp251xfd_regmap_init_nocrc()
500 return -ENOMEM; in mcp251xfd_regmap_init_nocrc()
503 if (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG)) in mcp251xfd_regmap_init_nocrc()
504 priv->map_reg = priv->map_nocrc; in mcp251xfd_regmap_init_nocrc()
506 if (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_RX)) in mcp251xfd_regmap_init_nocrc()
507 priv->map_rx = priv->map_nocrc; in mcp251xfd_regmap_init_nocrc()
514 if (priv->map_buf_nocrc_rx) { in mcp251xfd_regmap_destroy_nocrc()
515 devm_kfree(&priv->spi->dev, priv->map_buf_nocrc_rx); in mcp251xfd_regmap_destroy_nocrc()
516 priv->map_buf_nocrc_rx = NULL; in mcp251xfd_regmap_destroy_nocrc()
518 if (priv->map_buf_nocrc_tx) { in mcp251xfd_regmap_destroy_nocrc()
519 devm_kfree(&priv->spi->dev, priv->map_buf_nocrc_tx); in mcp251xfd_regmap_destroy_nocrc()
520 priv->map_buf_nocrc_tx = NULL; in mcp251xfd_regmap_destroy_nocrc()
527 if (!priv->map_crc) { in mcp251xfd_regmap_init_crc()
530 map = devm_regmap_init(&priv->spi->dev, &mcp251xfd_bus_crc, in mcp251xfd_regmap_init_crc()
531 priv->spi, &mcp251xfd_regmap_crc); in mcp251xfd_regmap_init_crc()
535 priv->map_crc = map; in mcp251xfd_regmap_init_crc()
538 if (!priv->map_buf_crc_rx) { in mcp251xfd_regmap_init_crc()
539 priv->map_buf_crc_rx = in mcp251xfd_regmap_init_crc()
540 devm_kzalloc(&priv->spi->dev, in mcp251xfd_regmap_init_crc()
541 sizeof(*priv->map_buf_crc_rx), in mcp251xfd_regmap_init_crc()
543 if (!priv->map_buf_crc_rx) in mcp251xfd_regmap_init_crc()
544 return -ENOMEM; in mcp251xfd_regmap_init_crc()
547 if (!priv->map_buf_crc_tx) { in mcp251xfd_regmap_init_crc()
548 priv->map_buf_crc_tx = in mcp251xfd_regmap_init_crc()
549 devm_kzalloc(&priv->spi->dev, in mcp251xfd_regmap_init_crc()
550 sizeof(*priv->map_buf_crc_tx), in mcp251xfd_regmap_init_crc()
552 if (!priv->map_buf_crc_tx) in mcp251xfd_regmap_init_crc()
553 return -ENOMEM; in mcp251xfd_regmap_init_crc()
556 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG) in mcp251xfd_regmap_init_crc()
557 priv->map_reg = priv->map_crc; in mcp251xfd_regmap_init_crc()
559 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_RX) in mcp251xfd_regmap_init_crc()
560 priv->map_rx = priv->map_crc; in mcp251xfd_regmap_init_crc()
567 if (priv->map_buf_crc_rx) { in mcp251xfd_regmap_destroy_crc()
568 devm_kfree(&priv->spi->dev, priv->map_buf_crc_rx); in mcp251xfd_regmap_destroy_crc()
569 priv->map_buf_crc_rx = NULL; in mcp251xfd_regmap_destroy_crc()
571 if (priv->map_buf_crc_tx) { in mcp251xfd_regmap_destroy_crc()
572 devm_kfree(&priv->spi->dev, priv->map_buf_crc_tx); in mcp251xfd_regmap_destroy_crc()
573 priv->map_buf_crc_tx = NULL; in mcp251xfd_regmap_destroy_crc()