diff mbox series

[v2,1/2] libstb/tpm_i2c_nuvoton: use struct of constants instead of hardcoded macro constants

Message ID 20241008175015.2425122-1-erichte@linux.ibm.com
State New
Headers show
Series [v2,1/2] libstb/tpm_i2c_nuvoton: use struct of constants instead of hardcoded macro constants | expand

Commit Message

Eric Richter Oct. 8, 2024, 5:50 p.m. UTC
This driver was originally developed with only the npct650 chip in mind,
which was developed before there was a TCG standard for a TPM on the i2c
bus. Therefore, many constants were hardcoded using macros for the
specific expected offsets and vendor information for this particular
chip.

To allow support for other potential Nuvoton (or maybe other i2c) chips,
this patch factors out the constants into a struct so that other chips
may be added, and the correct set of constants can be selected at
runtime.

Signed-off-by: Eric Richter <erichte@linux.ibm.com>
---

This is a small fix to only this patch. The "npct601" compatible value
should only be set if the current compatible is "npct650". Other TPMs will
not need this correction.

v2:
 - Only adjust the compatible for the npct650 chip

 libstb/drivers/tpm_i2c_nuvoton.c | 63 +++++++++++++++++++++-----------
 libstb/drivers/tpm_i2c_nuvoton.h |  2 +-
 libstb/tpm_chip.c                |  2 +-
 3 files changed, 44 insertions(+), 23 deletions(-)
diff mbox series

Patch

diff --git a/libstb/drivers/tpm_i2c_nuvoton.c b/libstb/drivers/tpm_i2c_nuvoton.c
index 0aa9711db..a4612941c 100644
--- a/libstb/drivers/tpm_i2c_nuvoton.c
+++ b/libstb/drivers/tpm_i2c_nuvoton.c
@@ -16,13 +16,6 @@ 
 
 #define DRIVER_NAME "i2c_tpm_nuvoton"
 
-/* I2C interface offsets */
-#define TPM_STS			0x00
-#define TPM_BURST_COUNT		0x01
-#define TPM_DATA_FIFO_W		0x20
-#define TPM_DATA_FIFO_R		0x40
-#define TPM_VID_DID		0x60
-
 /* Bit masks for the TPM STATUS register */
 #define TPM_STS_VALID		0x80
 #define TPM_STS_COMMAND_READY	0x40
@@ -34,15 +27,36 @@ 
 /* TPM Driver values */
 #define MAX_STSVALID_POLLS 	5
 #define TPM_TIMEOUT_INTERVAL	10
-#define TPM_NUVOTON_VID		0x5010FE00
 #define TPM_VENDOR_ID_MASK	0xFFFFFF00
 
+
+struct tpm_info {
+	uint32_t vendor_id;
+	uint8_t sts;
+	uint8_t burst_count;
+	uint8_t data_fifo_w;
+	uint8_t data_fifo_r;
+	uint8_t vid_did;
+};
+
+
+static struct tpm_info tpm_nuvoton_650_info = {
+	.vendor_id = 0x5010FE00,
+	.sts = 0x00,
+	.burst_count = 0x01,
+	.data_fifo_w = 0x20,
+	.data_fifo_r = 0x40,
+	.vid_did = 0x60,
+};
+
+
 static struct tpm_dev *tpm_device = NULL;
+static struct tpm_info *tpm_info = NULL;
 
 static int tpm_status_write_byte(uint8_t byte)
 {
 	uint8_t value = byte;
-	return tpm_i2c_request_send(tpm_device, SMBUS_WRITE, TPM_STS, 1, &value,
+	return tpm_i2c_request_send(tpm_device, SMBUS_WRITE, tpm_info->sts, 1, &value,
 				    sizeof(value));
 }
 
@@ -68,7 +82,7 @@  static int tpm_wait_for_command_ready(void)
 
 	do {
 		now = mftb();
-		rc = tpm_status_read_byte(TPM_STS, &status);
+		rc = tpm_status_read_byte(tpm_info->sts, &status);
 		if (rc < 0) {
 			/**
 			 * @fwts-label TPMReadCmdReady
@@ -138,7 +152,7 @@  static int tpm_wait_for_fifo_status(uint8_t mask, uint8_t expected)
 	uint8_t status;
 
 	for(retries = 0; retries <= MAX_STSVALID_POLLS; retries++) {
-		rc = tpm_status_read_byte(TPM_STS, &status);
+		rc = tpm_status_read_byte(tpm_info->sts, &status);
 		if (rc < 0) {
 			/**
 			 * @fwts-label TPMReadFifoStatus
@@ -170,7 +184,7 @@  static int tpm_wait_for_data_avail(void)
 
 	do {
 		now = mftb();
-		rc = tpm_status_read_byte(TPM_STS, &status);
+		rc = tpm_status_read_byte(tpm_info->sts, &status);
 		if (rc < 0) {
 			/**
 			 * @fwts-label TPMReadDataAvail
@@ -218,7 +232,7 @@  static int tpm_read_burst_count(void)
 	do {
 		now = mftb();
 		/* In i2C, burstCount is 1 byte */
-		rc = tpm_status_read_byte(TPM_BURST_COUNT, &burst_count);
+		rc = tpm_status_read_byte(tpm_info->burst_count, &burst_count);
 		if (rc == 0 && burst_count > 0) {
 			DBG("---- burst_count=%d, delay=%lu/%d\n", burst_count,
 			    tb_to_msecs(now-start), TPM_TIMEOUT_D);
@@ -272,7 +286,7 @@  static int tpm_write_fifo(uint8_t* buf, size_t buflen)
 			  (buflen - 1 - count) : burst_count);
 
 		rc = tpm_i2c_request_send(tpm_device,
-					  SMBUS_WRITE, TPM_DATA_FIFO_W,
+					  SMBUS_WRITE, tpm_info->data_fifo_w,
 					  1, &buf[count], bytes);
 		count += bytes;
 		DBG("%s FIFO: %zd bytes written, count=%zd, rc=%d\n",
@@ -315,7 +329,7 @@  static int tpm_write_fifo(uint8_t* buf, size_t buflen)
 
 	rc = tpm_i2c_request_send(tpm_device,
 				  SMBUS_WRITE,
-				  TPM_DATA_FIFO_W, 1,
+				  tpm_info->data_fifo_w, 1,
 				  &buf[count], 1);
 	count++;
 	DBG("%s FIFO: last byte written, count=%zd, rc=%d\n",
@@ -381,7 +395,7 @@  static int tpm_read_fifo(uint8_t* buf, size_t* buflen)
 		}
 		rc = tpm_i2c_request_send(tpm_device,
 					  SMBUS_READ,
-					  TPM_DATA_FIFO_R, 1,
+					  tpm_info->data_fifo_r, 1,
 					  &buf[count], burst_count);
 		count += burst_count;
 		DBG("%s FIFO: %d bytes read, count=%zd, rc=%d\n",
@@ -541,7 +555,7 @@  static int nuvoton_tpm_quirk(void *data, struct i2c_request *req, int *rc)
 	return 0;
 }
 
-void tpm_i2c_nuvoton_probe(void)
+static void tpm_i2c_nuvoton_probe(const char compat[], struct tpm_info *info)
 {
 	struct tpm_dev *tpm_device = NULL;
 	struct dt_node *node = NULL;
@@ -549,9 +563,10 @@  void tpm_i2c_nuvoton_probe(void)
 	const char *name;
 	uint32_t vendor = 0;
 
-	dt_for_each_compatible(dt_root, node, "nuvoton,npct650") {
+	dt_for_each_compatible(dt_root, node, compat) {
 		if (!dt_node_is_enabled(node))
 			continue;
+		tpm_info = info;
 		tpm_device = (struct tpm_dev*) malloc(sizeof(struct tpm_dev));
 		assert(tpm_device);
 		/*
@@ -585,12 +600,12 @@  void tpm_i2c_nuvoton_probe(void)
 			goto disable;
 		}
 		/* ensure there's really the TPM we expect at that address */
-		if (tpm_i2c_request_send(tpm_device, SMBUS_READ, TPM_VID_DID,
+		if (tpm_i2c_request_send(tpm_device, SMBUS_READ, tpm_info->vid_did,
 					 1, &vendor, sizeof(vendor))) {
 			prlog(PR_ERR, "NUVOTON: i2c device inaccessible\n");
 			goto disable;
 		}
-		if ((vendor & TPM_VENDOR_ID_MASK) != TPM_NUVOTON_VID) {
+		if ((vendor & TPM_VENDOR_ID_MASK) != tpm_info->vendor_id) {
 			prlog(PR_ERR, "NUVOTON: expected vendor id mismatch\n");
 			goto disable;
 		}
@@ -613,7 +628,7 @@  void tpm_i2c_nuvoton_probe(void)
 		 * Tweak for linux. It doesn't have a driver compatible
 		 * with "nuvoton,npct650"
 		 */
-		if (!dt_node_is_compatible(node, "nuvoton,npct601")) {
+		if (dt_node_is_compatible(node, "nuvoton,npct650")) {
 			dt_check_del_prop(node, "compatible");
 			dt_add_property_strings(node, "compatible",
 						"nuvoton,npct650", "nuvoton,npct601");
@@ -625,3 +640,9 @@  disable:
 	prlog(PR_NOTICE, "TPM: tpm node %p disabled\n", node);
 	free(tpm_device);
 }
+
+
+void tpm_i2c_nuvoton_650_probe(void)
+{
+	tpm_i2c_nuvoton_probe("nuvoton,npct650", &tpm_nuvoton_650_info);
+}
diff --git a/libstb/drivers/tpm_i2c_nuvoton.h b/libstb/drivers/tpm_i2c_nuvoton.h
index 53cf1e1da..c8b11744e 100644
--- a/libstb/drivers/tpm_i2c_nuvoton.h
+++ b/libstb/drivers/tpm_i2c_nuvoton.h
@@ -4,6 +4,6 @@ 
 #ifndef __TPM_I2C_NUVOTON_H
 #define __TPM_I2C_NUVOTON_H
 
-extern void tpm_i2c_nuvoton_probe(void);
+extern void tpm_i2c_nuvoton_650_probe(void);
 
 #endif /* __TPM_I2C_NUVOTON_H */
diff --git a/libstb/tpm_chip.c b/libstb/tpm_chip.c
index 22d2d3bb2..44fa8cbca 100644
--- a/libstb/tpm_chip.c
+++ b/libstb/tpm_chip.c
@@ -189,7 +189,7 @@  int tpm_init(void)
 	list_head_init(&tpm_list);
 
 	/* tpm drivers supported */
-	tpm_i2c_nuvoton_probe();
+	tpm_i2c_nuvoton_650_probe();
 
 	if (list_empty(&tpm_list)) {
 		prlog(PR_INFO, "no compatible tpm device found!\n");