Commit c6f2a617 authored by Marc Kleine-Budde's avatar Marc Kleine-Budde

can: mcp251xfd: add support for mcp251863

The MCP251863 device is a CAN-FD controller (MCP2518FD) with an
integrated transceiver (ATA6563). This patch add support for the new
device.

Link: https://lore.kernel.org/all/20220419072805.2840340-3-mkl@pengutronix.de
Cc: Thomas Kopp <thomas.kopp@microchip.com>
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent 62111976
...@@ -37,6 +37,12 @@ static const struct mcp251xfd_devtype_data mcp251xfd_devtype_data_mcp2518fd = { ...@@ -37,6 +37,12 @@ static const struct mcp251xfd_devtype_data mcp251xfd_devtype_data_mcp2518fd = {
.model = MCP251XFD_MODEL_MCP2518FD, .model = MCP251XFD_MODEL_MCP2518FD,
}; };
static const struct mcp251xfd_devtype_data mcp251xfd_devtype_data_mcp251863 = {
.quirks = MCP251XFD_QUIRK_CRC_REG | MCP251XFD_QUIRK_CRC_RX |
MCP251XFD_QUIRK_CRC_TX | MCP251XFD_QUIRK_ECC,
.model = MCP251XFD_MODEL_MCP251863,
};
/* Autodetect model, start with CRC enabled. */ /* Autodetect model, start with CRC enabled. */
static const struct mcp251xfd_devtype_data mcp251xfd_devtype_data_mcp251xfd = { static const struct mcp251xfd_devtype_data mcp251xfd_devtype_data_mcp251xfd = {
.quirks = MCP251XFD_QUIRK_CRC_REG | MCP251XFD_QUIRK_CRC_RX | .quirks = MCP251XFD_QUIRK_CRC_REG | MCP251XFD_QUIRK_CRC_RX |
...@@ -75,6 +81,8 @@ static const char *__mcp251xfd_get_model_str(enum mcp251xfd_model model) ...@@ -75,6 +81,8 @@ static const char *__mcp251xfd_get_model_str(enum mcp251xfd_model model)
return "MCP2517FD"; return "MCP2517FD";
case MCP251XFD_MODEL_MCP2518FD: case MCP251XFD_MODEL_MCP2518FD:
return "MCP2518FD"; return "MCP2518FD";
case MCP251XFD_MODEL_MCP251863:
return "MCP251863";
case MCP251XFD_MODEL_MCP251XFD: case MCP251XFD_MODEL_MCP251XFD:
return "MCP251xFD"; return "MCP251xFD";
} }
...@@ -1259,7 +1267,8 @@ mcp251xfd_handle_eccif_recover(struct mcp251xfd_priv *priv, u8 nr) ...@@ -1259,7 +1267,8 @@ mcp251xfd_handle_eccif_recover(struct mcp251xfd_priv *priv, u8 nr)
* - for mcp2518fd: offset not 0 or 1 * - for mcp2518fd: offset not 0 or 1
*/ */
if (chip_tx_tail != tx_tail || if (chip_tx_tail != tx_tail ||
!(offset == 0 || (offset == 1 && mcp251xfd_is_2518(priv)))) { !(offset == 0 || (offset == 1 && (mcp251xfd_is_2518FD(priv) ||
mcp251xfd_is_251863(priv))))) {
netdev_err(priv->ndev, netdev_err(priv->ndev,
"ECC Error information inconsistent (addr=0x%04x, nr=%d, tx_tail=0x%08x(%d), chip_tx_tail=%d, offset=%d).\n", "ECC Error information inconsistent (addr=0x%04x, nr=%d, tx_tail=0x%08x(%d), chip_tx_tail=%d, offset=%d).\n",
addr, nr, tx_ring->tail, tx_tail, chip_tx_tail, addr, nr, tx_ring->tail, tx_tail, chip_tx_tail,
...@@ -1697,7 +1706,7 @@ static int mcp251xfd_register_chip_detect(struct mcp251xfd_priv *priv) ...@@ -1697,7 +1706,7 @@ static int mcp251xfd_register_chip_detect(struct mcp251xfd_priv *priv)
else else
devtype_data = &mcp251xfd_devtype_data_mcp2517fd; devtype_data = &mcp251xfd_devtype_data_mcp2517fd;
if (!mcp251xfd_is_251X(priv) && if (!mcp251xfd_is_251XFD(priv) &&
priv->devtype_data.model != devtype_data->model) { priv->devtype_data.model != devtype_data->model) {
netdev_info(ndev, netdev_info(ndev,
"Detected %s, but firmware specifies a %s. Fixing up.\n", "Detected %s, but firmware specifies a %s. Fixing up.\n",
...@@ -1929,6 +1938,9 @@ static const struct of_device_id mcp251xfd_of_match[] = { ...@@ -1929,6 +1938,9 @@ static const struct of_device_id mcp251xfd_of_match[] = {
}, { }, {
.compatible = "microchip,mcp2518fd", .compatible = "microchip,mcp2518fd",
.data = &mcp251xfd_devtype_data_mcp2518fd, .data = &mcp251xfd_devtype_data_mcp2518fd,
}, {
.compatible = "microchip,mcp251863",
.data = &mcp251xfd_devtype_data_mcp251863,
}, { }, {
.compatible = "microchip,mcp251xfd", .compatible = "microchip,mcp251xfd",
.data = &mcp251xfd_devtype_data_mcp251xfd, .data = &mcp251xfd_devtype_data_mcp251xfd,
...@@ -1945,6 +1957,9 @@ static const struct spi_device_id mcp251xfd_id_table[] = { ...@@ -1945,6 +1957,9 @@ static const struct spi_device_id mcp251xfd_id_table[] = {
}, { }, {
.name = "mcp2518fd", .name = "mcp2518fd",
.driver_data = (kernel_ulong_t)&mcp251xfd_devtype_data_mcp2518fd, .driver_data = (kernel_ulong_t)&mcp251xfd_devtype_data_mcp2518fd,
}, {
.name = "mcp251863",
.driver_data = (kernel_ulong_t)&mcp251xfd_devtype_data_mcp251863,
}, { }, {
.name = "mcp251xfd", .name = "mcp251xfd",
.driver_data = (kernel_ulong_t)&mcp251xfd_devtype_data_mcp251xfd, .driver_data = (kernel_ulong_t)&mcp251xfd_devtype_data_mcp251xfd,
......
...@@ -586,7 +586,8 @@ struct mcp251xfd_regs_status { ...@@ -586,7 +586,8 @@ struct mcp251xfd_regs_status {
enum mcp251xfd_model { enum mcp251xfd_model {
MCP251XFD_MODEL_MCP2517FD = 0x2517, MCP251XFD_MODEL_MCP2517FD = 0x2517,
MCP251XFD_MODEL_MCP2518FD = 0x2518, MCP251XFD_MODEL_MCP2518FD = 0x2518,
MCP251XFD_MODEL_MCP251XFD = 0xffff, /* autodetect model */ MCP251XFD_MODEL_MCP251863 = 0x251863,
MCP251XFD_MODEL_MCP251XFD = 0xffffffff, /* autodetect model */
}; };
struct mcp251xfd_devtype_data { struct mcp251xfd_devtype_data {
...@@ -659,12 +660,13 @@ struct mcp251xfd_priv { ...@@ -659,12 +660,13 @@ struct mcp251xfd_priv {
static inline bool \ static inline bool \
mcp251xfd_is_##_model(const struct mcp251xfd_priv *priv) \ mcp251xfd_is_##_model(const struct mcp251xfd_priv *priv) \
{ \ { \
return priv->devtype_data.model == MCP251XFD_MODEL_MCP##_model##FD; \ return priv->devtype_data.model == MCP251XFD_MODEL_MCP##_model; \
} }
MCP251XFD_IS(2517); MCP251XFD_IS(2517FD);
MCP251XFD_IS(2518); MCP251XFD_IS(2518FD);
MCP251XFD_IS(251X); MCP251XFD_IS(251863);
MCP251XFD_IS(251XFD);
static inline bool mcp251xfd_is_fd_mode(const struct mcp251xfd_priv *priv) static inline bool mcp251xfd_is_fd_mode(const struct mcp251xfd_priv *priv)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment