Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: pse-pd: tps23881: Add support for TPS23881B

The TPS23881B uses different firmware than the TPS23881. Trying to load the
TPS23881 firmware on a TPS23881B device fails and must be omitted.

The TPS23881B ships with a more recent ROM firmware. Moreover, no updated
firmware has been released yet and so the firmware loading step must be
skipped. As of today, the TPS23881B is intended to use its ROM firmware.

Signed-off-by: Thomas Wismer <thomas.wismer@scs.ch>
Reviewed-by: Kory Maincent <kory.maincent@bootlin.com>
Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
Link: https://patch.msgid.link/20251029212312.108749-2-thomas@wismer.xyz
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Thomas Wismer and committed by
Jakub Kicinski
4d07797f a7aca10c

+54 -15
+54 -15
drivers/net/pse-pd/tps23881.c
··· 55 55 #define TPS23881_REG_TPON BIT(0) 56 56 #define TPS23881_REG_FWREV 0x41 57 57 #define TPS23881_REG_DEVID 0x43 58 - #define TPS23881_REG_DEVID_MASK 0xF0 59 - #define TPS23881_DEVICE_ID 0x02 60 58 #define TPS23881_REG_CHAN1_CLASS 0x4c 61 59 #define TPS23881_REG_SRAM_CTRL 0x60 62 60 #define TPS23881_REG_SRAM_DATA 0x61 ··· 1010 1012 .pi_get_pw_req = tps23881_pi_get_pw_req, 1011 1013 }; 1012 1014 1013 - static const char fw_parity_name[] = "ti/tps23881/tps23881-parity-14.bin"; 1014 - static const char fw_sram_name[] = "ti/tps23881/tps23881-sram-14.bin"; 1015 + struct tps23881_info { 1016 + u8 dev_id; /* device ID and silicon revision */ 1017 + const char *fw_parity_name; /* parity code firmware file name */ 1018 + const char *fw_sram_name; /* SRAM code firmware file name */ 1019 + }; 1020 + 1021 + enum tps23881_model { 1022 + TPS23881, 1023 + TPS23881B, 1024 + }; 1025 + 1026 + static const struct tps23881_info tps23881_info[] = { 1027 + [TPS23881] = { 1028 + .dev_id = 0x22, 1029 + .fw_parity_name = "ti/tps23881/tps23881-parity-14.bin", 1030 + .fw_sram_name = "ti/tps23881/tps23881-sram-14.bin", 1031 + }, 1032 + [TPS23881B] = { 1033 + .dev_id = 0x24, 1034 + /* skip SRAM load, ROM provides Clause 145 hardware-level support */ 1035 + }, 1036 + }; 1015 1037 1016 1038 struct tps23881_fw_conf { 1017 1039 u8 reg; ··· 1103 1085 return ret; 1104 1086 } 1105 1087 1106 - static int tps23881_flash_sram_fw(struct i2c_client *client) 1088 + static int tps23881_flash_sram_fw(struct i2c_client *client, 1089 + const struct tps23881_info *info) 1107 1090 { 1108 1091 int ret; 1109 1092 1110 - ret = tps23881_flash_sram_fw_part(client, fw_parity_name, 1093 + ret = tps23881_flash_sram_fw_part(client, info->fw_parity_name, 1111 1094 tps23881_fw_parity_conf); 1112 1095 if (ret) 1113 1096 return ret; 1114 1097 1115 - ret = tps23881_flash_sram_fw_part(client, fw_sram_name, 1098 + ret = tps23881_flash_sram_fw_part(client, info->fw_sram_name, 1116 1099 tps23881_fw_sram_conf); 1117 1100 if (ret) 1118 1101 return ret; ··· 1431 1412 static int tps23881_i2c_probe(struct i2c_client *client) 1432 1413 { 1433 1414 struct device *dev = &client->dev; 1415 + const struct tps23881_info *info; 1434 1416 struct tps23881_priv *priv; 1435 1417 struct gpio_desc *reset; 1436 1418 int ret; ··· 1441 1421 dev_err(dev, "i2c check functionality failed\n"); 1442 1422 return -ENXIO; 1443 1423 } 1424 + 1425 + info = i2c_get_match_data(client); 1426 + if (!info) 1427 + return -EINVAL; 1444 1428 1445 1429 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 1446 1430 if (!priv) ··· 1464 1440 * to Load TPS2388x SRAM and Parity Code over I2C" (Rev E)) 1465 1441 * indicates we should delay that programming by at least 50ms. So 1466 1442 * we'll wait the entire 50ms here to ensure we're safe to go to the 1467 - * SRAM loading proceedure. 1443 + * SRAM loading procedure. 1468 1444 */ 1469 1445 msleep(50); 1470 1446 } ··· 1473 1449 if (ret < 0) 1474 1450 return ret; 1475 1451 1476 - if (FIELD_GET(TPS23881_REG_DEVID_MASK, ret) != TPS23881_DEVICE_ID) { 1452 + if (ret != info->dev_id) { 1477 1453 dev_err(dev, "Wrong device ID\n"); 1478 1454 return -ENXIO; 1479 1455 } 1480 1456 1481 - ret = tps23881_flash_sram_fw(client); 1482 - if (ret < 0) 1483 - return ret; 1457 + if (info->fw_sram_name) { 1458 + ret = tps23881_flash_sram_fw(client, info); 1459 + if (ret < 0) 1460 + return ret; 1461 + } 1484 1462 1485 1463 ret = i2c_smbus_read_byte_data(client, TPS23881_REG_FWREV); 1486 1464 if (ret < 0) 1487 1465 return ret; 1488 1466 1489 - dev_info(&client->dev, "Firmware revision 0x%x\n", ret); 1467 + if (ret == 0xFF) { 1468 + dev_err(&client->dev, "Device entered safe mode\n"); 1469 + return -ENXIO; 1470 + } 1471 + dev_info(&client->dev, "Firmware revision 0x%x%s\n", ret, 1472 + ret == 0x00 ? " (ROM firmware)" : ""); 1490 1473 1491 1474 /* Set configuration B, 16 bit access on a single device address */ 1492 1475 ret = i2c_smbus_read_byte_data(client, TPS23881_REG_GEN_MASK); ··· 1529 1498 } 1530 1499 1531 1500 static const struct i2c_device_id tps23881_id[] = { 1532 - { "tps23881" }, 1501 + { "tps23881", .driver_data = (kernel_ulong_t)&tps23881_info[TPS23881] }, 1502 + { "tps23881b", .driver_data = (kernel_ulong_t)&tps23881_info[TPS23881B] }, 1533 1503 { } 1534 1504 }; 1535 1505 MODULE_DEVICE_TABLE(i2c, tps23881_id); 1536 1506 1537 1507 static const struct of_device_id tps23881_of_match[] = { 1538 - { .compatible = "ti,tps23881", }, 1508 + { 1509 + .compatible = "ti,tps23881", 1510 + .data = &tps23881_info[TPS23881] 1511 + }, 1512 + { 1513 + .compatible = "ti,tps23881b", 1514 + .data = &tps23881_info[TPS23881B] 1515 + }, 1539 1516 { }, 1540 1517 }; 1541 1518 MODULE_DEVICE_TABLE(of, tps23881_of_match);