tpm: disociate TPMv1.x specific and generic code

There are no changes in this commit but a new organization of the code
as follow.

* cmd/ directory:
        > move existing code from cmd/tpm.c in cmd/tpm-common.c
	> move specific code in cmd/tpm-v1.c
	> create a specific header file with generic definitions for
	  commands only called cmd/tpm-user-utils.h

* lib/ directory:
        > move existing code from lib/tpm.c in lib/tpm-common.c
	> move specific code in lib/tpm-v1.c
	> create a specific header file with generic definitions for
	  the library itself called lib/tpm-utils.h

* include/ directory:
        > move existing code from include/tpm.h in include/tpm-common.h
	> move specific code in include/tpm-v1.h

Code designated as 'common' is compiled if TPM are used. Code designated
as 'specific' is compiled only if the right specification has been
selected.

All files include tpm-common.h.
Files in cmd/ include tpm-user-utils.h.
Files in lib/ include tpm-utils.h.
Depending on the specification, files may include either (not both)
tpm-v1.h or tpm-v2.h.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
[trini: Fix a few more cases of tpm.h -> tpm-v1.h, some Kconfig logic]
Signed-off-by: Tom Rini <trini@konsulko.com>
diff --git a/board/gdsys/a38x/controlcenterdc.c b/board/gdsys/a38x/controlcenterdc.c
index 320bc10..824a08f 100644
--- a/board/gdsys/a38x/controlcenterdc.c
+++ b/board/gdsys/a38x/controlcenterdc.c
@@ -7,7 +7,7 @@
 #include <common.h>
 #include <dm.h>
 #include <miiphy.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
 #include <asm-generic/gpio.h>
diff --git a/board/gdsys/a38x/hre.c b/board/gdsys/a38x/hre.c
index 961316c..34c4df7 100644
--- a/board/gdsys/a38x/hre.c
+++ b/board/gdsys/a38x/hre.c
@@ -9,7 +9,7 @@
 #include <fs.h>
 #include <i2c.h>
 #include <mmc.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <u-boot/sha1.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
diff --git a/board/gdsys/a38x/keyprogram.c b/board/gdsys/a38x/keyprogram.c
index f6a2747..1fb5306 100644
--- a/board/gdsys/a38x/keyprogram.c
+++ b/board/gdsys/a38x/keyprogram.c
@@ -5,7 +5,7 @@
  */
 
 #include <common.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <malloc.h>
 #include <linux/ctype.h>
 #include <asm/unaligned.h>
diff --git a/board/gdsys/p1022/controlcenterd-id.c b/board/gdsys/p1022/controlcenterd-id.c
index 87edf92..7e082df 100644
--- a/board/gdsys/p1022/controlcenterd-id.c
+++ b/board/gdsys/p1022/controlcenterd-id.c
@@ -15,7 +15,7 @@
 #include <fs.h>
 #include <i2c.h>
 #include <mmc.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <u-boot/sha1.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
diff --git a/cmd/Makefile b/cmd/Makefile
index ca6ead8..6164f6e 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -120,7 +120,8 @@
 obj-$(CONFIG_CMD_TIME) += time.o
 obj-$(CONFIG_CMD_TRACE) += trace.o
 obj-$(CONFIG_HUSH_PARSER) += test.o
-obj-$(CONFIG_CMD_TPM_V1) += tpm.o
+obj-$(CONFIG_CMD_TPM) += tpm-common.o
+obj-$(CONFIG_CMD_TPM_V1) += tpm-v1.o
 obj-$(CONFIG_CMD_TPM_TEST) += tpm_test.o
 obj-$(CONFIG_CMD_CROS_EC) += cros_ec.o
 obj-$(CONFIG_CMD_TSI148) += tsi148.o
diff --git a/cmd/tpm-common.c b/cmd/tpm-common.c
new file mode 100644
index 0000000..6cf9fcc
--- /dev/null
+++ b/cmd/tpm-common.c
@@ -0,0 +1,288 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2013 The Chromium OS Authors.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <dm.h>
+#include <asm/unaligned.h>
+#include <linux/string.h>
+#include <tpm-common.h>
+#include "tpm-user-utils.h"
+
+/**
+ * Print a byte string in hexdecimal format, 16-bytes per line.
+ *
+ * @param data		byte string to be printed
+ * @param count		number of bytes to be printed
+ */
+void print_byte_string(u8 *data, size_t count)
+{
+	int i, print_newline = 0;
+
+	for (i = 0; i < count; i++) {
+		printf(" %02x", data[i]);
+		print_newline = (i % 16 == 15);
+		if (print_newline)
+			putc('\n');
+	}
+	/* Avoid duplicated newline at the end */
+	if (!print_newline)
+		putc('\n');
+}
+
+/**
+ * Convert a text string of hexdecimal values into a byte string.
+ *
+ * @param bytes		text string of hexdecimal values with no space
+ *			between them
+ * @param data		output buffer for byte string.  The caller has to make
+ *			sure it is large enough for storing the output.  If
+ *			NULL is passed, a large enough buffer will be allocated,
+ *			and the caller must free it.
+ * @param count_ptr	output variable for the length of byte string
+ * @return pointer to output buffer
+ */
+void *parse_byte_string(char *bytes, u8 *data, size_t *count_ptr)
+{
+	char byte[3];
+	size_t count, length;
+	int i;
+
+	if (!bytes)
+		return NULL;
+	length = strlen(bytes);
+	count = length / 2;
+
+	if (!data)
+		data = malloc(count);
+	if (!data)
+		return NULL;
+
+	byte[2] = '\0';
+	for (i = 0; i < length; i += 2) {
+		byte[0] = bytes[i];
+		byte[1] = bytes[i + 1];
+		data[i / 2] = (u8)simple_strtoul(byte, NULL, 16);
+	}
+
+	if (count_ptr)
+		*count_ptr = count;
+
+	return data;
+}
+
+/**
+ * report_return_code() - Report any error and return failure or success
+ *
+ * @param return_code	TPM command return code
+ * @return value of enum command_ret_t
+ */
+int report_return_code(int return_code)
+{
+	if (return_code) {
+		printf("Error: %d\n", return_code);
+		return CMD_RET_FAILURE;
+	} else {
+		return CMD_RET_SUCCESS;
+	}
+}
+
+/**
+ * Return number of values defined by a type string.
+ *
+ * @param type_str	type string
+ * @return number of values of type string
+ */
+int type_string_get_num_values(const char *type_str)
+{
+	return strlen(type_str);
+}
+
+/**
+ * Return total size of values defined by a type string.
+ *
+ * @param type_str	type string
+ * @return total size of values of type string, or 0 if type string
+ *  contains illegal type character.
+ */
+size_t type_string_get_space_size(const char *type_str)
+{
+	size_t size;
+
+	for (size = 0; *type_str; type_str++) {
+		switch (*type_str) {
+		case 'b':
+			size += 1;
+			break;
+		case 'w':
+			size += 2;
+			break;
+		case 'd':
+			size += 4;
+			break;
+		default:
+			return 0;
+		}
+	}
+
+	return size;
+}
+
+/**
+ * Allocate a buffer large enough to hold values defined by a type
+ * string.  The caller has to free the buffer.
+ *
+ * @param type_str	type string
+ * @param count		pointer for storing size of buffer
+ * @return pointer to buffer or NULL on error
+ */
+void *type_string_alloc(const char *type_str, u32 *count)
+{
+	void *data;
+	size_t size;
+
+	size = type_string_get_space_size(type_str);
+	if (!size)
+		return NULL;
+	data = malloc(size);
+	if (data)
+		*count = size;
+
+	return data;
+}
+
+/**
+ * Pack values defined by a type string into a buffer.  The buffer must have
+ * large enough space.
+ *
+ * @param type_str	type string
+ * @param values	text strings of values to be packed
+ * @param data		output buffer of values
+ * @return 0 on success, non-0 on error
+ */
+int type_string_pack(const char *type_str, char * const values[],
+		     u8 *data)
+{
+	size_t offset;
+	u32 value;
+
+	for (offset = 0; *type_str; type_str++, values++) {
+		value = simple_strtoul(values[0], NULL, 0);
+		switch (*type_str) {
+		case 'b':
+			data[offset] = value;
+			offset += 1;
+			break;
+		case 'w':
+			put_unaligned_be16(value, data + offset);
+			offset += 2;
+			break;
+		case 'd':
+			put_unaligned_be32(value, data + offset);
+			offset += 4;
+			break;
+		default:
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * Read values defined by a type string from a buffer, and write these values
+ * to environment variables.
+ *
+ * @param type_str	type string
+ * @param data		input buffer of values
+ * @param vars		names of environment variables
+ * @return 0 on success, non-0 on error
+ */
+int type_string_write_vars(const char *type_str, u8 *data,
+			   char * const vars[])
+{
+	size_t offset;
+	u32 value;
+
+	for (offset = 0; *type_str; type_str++, vars++) {
+		switch (*type_str) {
+		case 'b':
+			value = data[offset];
+			offset += 1;
+			break;
+		case 'w':
+			value = get_unaligned_be16(data + offset);
+			offset += 2;
+			break;
+		case 'd':
+			value = get_unaligned_be32(data + offset);
+			offset += 4;
+			break;
+		default:
+			return -1;
+		}
+		if (env_set_ulong(*vars, value))
+			return -1;
+	}
+
+	return 0;
+}
+
+int get_tpm(struct udevice **devp)
+{
+	int rc;
+
+	rc = uclass_first_device_err(UCLASS_TPM, devp);
+	if (rc) {
+		printf("Could not find TPM (ret=%d)\n", rc);
+		return CMD_RET_FAILURE;
+	}
+
+	return 0;
+}
+
+int do_tpm_info(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	struct udevice *dev;
+	char buf[80];
+	int rc;
+
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
+	rc = tpm_get_desc(dev, buf, sizeof(buf));
+	if (rc < 0) {
+		printf("Couldn't get TPM info (%d)\n", rc);
+		return CMD_RET_FAILURE;
+	}
+	printf("%s\n", buf);
+
+	return 0;
+}
+
+int do_tpm_init(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	if (argc != 1)
+		return CMD_RET_USAGE;
+
+	return report_return_code(tpm_init());
+}
+
+int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	cmd_tbl_t *tpm_commands, *cmd;
+	unsigned int size;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	tpm_commands = get_tpm_commands(&size);
+
+	cmd = find_cmd_tbl(argv[1], tpm_commands, size);
+	if (!cmd)
+		return CMD_RET_USAGE;
+
+	return cmd->cmd(cmdtp, flag, argc - 1, argv + 1);
+}
diff --git a/cmd/tpm-user-utils.h b/cmd/tpm-user-utils.h
new file mode 100644
index 0000000..8ce9861
--- /dev/null
+++ b/cmd/tpm-user-utils.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2013 The Chromium OS Authors.
+ * Coypright (c) 2013 Guntermann & Drunck GmbH
+ */
+
+#ifndef __TPM_USER_UTILS_H
+#define __TPM_USER_UTILS_H
+
+void print_byte_string(u8 *data, size_t count);
+void *parse_byte_string(char *bytes, u8 *data, size_t *count_ptr);
+int report_return_code(int return_code);
+int type_string_get_num_values(const char *type_str);
+size_t type_string_get_space_size(const char *type_str);
+void *type_string_alloc(const char *type_str, u32 *count);
+int type_string_pack(const char *type_str, char * const values[], u8 *data);
+int type_string_write_vars(const char *type_str, u8 *data, char * const vars[]);
+int get_tpm(struct udevice **devp);
+
+int do_tpm_init(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
+int do_tpm_info(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
+int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+
+#endif /* __TPM_USER_UTILS_H */
diff --git a/cmd/tpm.c b/cmd/tpm-v1.c
similarity index 76%
rename from cmd/tpm.c
rename to cmd/tpm-v1.c
index e0cd841..0874c4d 100644
--- a/cmd/tpm.c
+++ b/cmd/tpm-v1.c
@@ -4,238 +4,11 @@
  */
 
 #include <common.h>
-#include <command.h>
-#include <dm.h>
 #include <malloc.h>
-#include <tpm.h>
 #include <asm/unaligned.h>
-#include <linux/string.h>
-
-/* Useful constants */
-enum {
-	DIGEST_LENGTH		= 20,
-	/* max lengths, valid for RSA keys <= 2048 bits */
-	TPM_PUBKEY_MAX_LENGTH	= 288,
-};
-
-/**
- * Print a byte string in hexdecimal format, 16-bytes per line.
- *
- * @param data		byte string to be printed
- * @param count		number of bytes to be printed
- */
-static void print_byte_string(u8 *data, size_t count)
-{
-	int i, print_newline = 0;
-
-	for (i = 0; i < count; i++) {
-		printf(" %02x", data[i]);
-		print_newline = (i % 16 == 15);
-		if (print_newline)
-			putc('\n');
-	}
-	/* Avoid duplicated newline at the end */
-	if (!print_newline)
-		putc('\n');
-}
-
-/**
- * Convert a text string of hexdecimal values into a byte string.
- *
- * @param bytes		text string of hexdecimal values with no space
- *			between them
- * @param data		output buffer for byte string.  The caller has to make
- *			sure it is large enough for storing the output.  If
- *			NULL is passed, a large enough buffer will be allocated,
- *			and the caller must free it.
- * @param count_ptr	output variable for the length of byte string
- * @return pointer to output buffer
- */
-static void *parse_byte_string(char *bytes, u8 *data, size_t *count_ptr)
-{
-	char byte[3];
-	size_t count, length;
-	int i;
-
-	if (!bytes)
-		return NULL;
-	length = strlen(bytes);
-	count = length / 2;
-
-	if (!data)
-		data = malloc(count);
-	if (!data)
-		return NULL;
-
-	byte[2] = '\0';
-	for (i = 0; i < length; i += 2) {
-		byte[0] = bytes[i];
-		byte[1] = bytes[i + 1];
-		data[i / 2] = (u8)simple_strtoul(byte, NULL, 16);
-	}
-
-	if (count_ptr)
-		*count_ptr = count;
-
-	return data;
-}
-
-/**
- * report_return_code() - Report any error and return failure or success
- *
- * @param return_code	TPM command return code
- * @return value of enum command_ret_t
- */
-static int report_return_code(int return_code)
-{
-	if (return_code) {
-		printf("Error: %d\n", return_code);
-		return CMD_RET_FAILURE;
-	} else {
-		return CMD_RET_SUCCESS;
-	}
-}
-
-/**
- * Return number of values defined by a type string.
- *
- * @param type_str	type string
- * @return number of values of type string
- */
-static int type_string_get_num_values(const char *type_str)
-{
-	return strlen(type_str);
-}
-
-/**
- * Return total size of values defined by a type string.
- *
- * @param type_str	type string
- * @return total size of values of type string, or 0 if type string
- *  contains illegal type character.
- */
-static size_t type_string_get_space_size(const char *type_str)
-{
-	size_t size;
-
-	for (size = 0; *type_str; type_str++) {
-		switch (*type_str) {
-		case 'b':
-			size += 1;
-			break;
-		case 'w':
-			size += 2;
-			break;
-		case 'd':
-			size += 4;
-			break;
-		default:
-			return 0;
-		}
-	}
-
-	return size;
-}
-
-/**
- * Allocate a buffer large enough to hold values defined by a type
- * string.  The caller has to free the buffer.
- *
- * @param type_str	type string
- * @param count		pointer for storing size of buffer
- * @return pointer to buffer or NULL on error
- */
-static void *type_string_alloc(const char *type_str, u32 *count)
-{
-	void *data;
-	size_t size;
-
-	size = type_string_get_space_size(type_str);
-	if (!size)
-		return NULL;
-	data = malloc(size);
-	if (data)
-		*count = size;
-
-	return data;
-}
-
-/**
- * Pack values defined by a type string into a buffer.  The buffer must have
- * large enough space.
- *
- * @param type_str	type string
- * @param values	text strings of values to be packed
- * @param data		output buffer of values
- * @return 0 on success, non-0 on error
- */
-static int type_string_pack(const char *type_str, char * const values[],
-			    u8 *data)
-{
-	size_t offset;
-	u32 value;
-
-	for (offset = 0; *type_str; type_str++, values++) {
-		value = simple_strtoul(values[0], NULL, 0);
-		switch (*type_str) {
-		case 'b':
-			data[offset] = value;
-			offset += 1;
-			break;
-		case 'w':
-			put_unaligned_be16(value, data + offset);
-			offset += 2;
-			break;
-		case 'd':
-			put_unaligned_be32(value, data + offset);
-			offset += 4;
-			break;
-		default:
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-/**
- * Read values defined by a type string from a buffer, and write these values
- * to environment variables.
- *
- * @param type_str	type string
- * @param data		input buffer of values
- * @param vars		names of environment variables
- * @return 0 on success, non-0 on error
- */
-static int type_string_write_vars(const char *type_str, u8 *data,
-				  char * const vars[])
-{
-	size_t offset;
-	u32 value;
-
-	for (offset = 0; *type_str; type_str++, vars++) {
-		switch (*type_str) {
-		case 'b':
-			value = data[offset];
-			offset += 1;
-			break;
-		case 'w':
-			value = get_unaligned_be16(data + offset);
-			offset += 2;
-			break;
-		case 'd':
-			value = get_unaligned_be32(data + offset);
-			offset += 4;
-			break;
-		default:
-			return -1;
-		}
-		if (env_set_ulong(*vars, value))
-			return -1;
-	}
-
-	return 0;
-}
+#include <tpm-common.h>
+#include <tpm-v1.h>
+#include "tpm-user-utils.h"
 
 static int do_tpm_startup(cmd_tbl_t *cmdtp, int flag, int argc,
 			  char * const argv[])
@@ -426,54 +199,6 @@
 	return report_return_code(rc);
 }
 
-#define TPM_COMMAND_NO_ARG(cmd)				\
-static int do_##cmd(cmd_tbl_t *cmdtp, int flag,		\
-		    int argc, char * const argv[])	\
-{							\
-	if (argc != 1)					\
-		return CMD_RET_USAGE;			\
-	return report_return_code(cmd());		\
-}
-
-TPM_COMMAND_NO_ARG(tpm_init)
-TPM_COMMAND_NO_ARG(tpm_self_test_full)
-TPM_COMMAND_NO_ARG(tpm_continue_self_test)
-TPM_COMMAND_NO_ARG(tpm_force_clear)
-TPM_COMMAND_NO_ARG(tpm_physical_enable)
-TPM_COMMAND_NO_ARG(tpm_physical_disable)
-
-static int get_tpm(struct udevice **devp)
-{
-	int rc;
-
-	rc = uclass_first_device_err(UCLASS_TPM, devp);
-	if (rc) {
-		printf("Could not find TPM (ret=%d)\n", rc);
-		return CMD_RET_FAILURE;
-	}
-
-	return 0;
-}
-
-static int do_tpm_info(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
-{
-	struct udevice *dev;
-	char buf[80];
-	int rc;
-
-	rc = get_tpm(&dev);
-	if (rc)
-		return rc;
-	rc = tpm_get_desc(dev, buf, sizeof(buf));
-	if (rc < 0) {
-		printf("Couldn't get TPM info (%d)\n", rc);
-		return CMD_RET_FAILURE;
-	}
-	printf("%s\n", buf);
-
-	return 0;
-}
-
 static int do_tpm_raw_transfer(cmd_tbl_t *cmdtp, int flag, int argc,
 			       char * const argv[])
 {
@@ -812,10 +537,13 @@
 }
 #endif /* CONFIG_TPM_LIST_RESOURCES */
 
-#define MAKE_TPM_CMD_ENTRY(cmd) \
-	U_BOOT_CMD_MKENT(cmd, 0, 1, do_tpm_ ## cmd, "", "")
+TPM_COMMAND_NO_ARG(tpm_self_test_full)
+TPM_COMMAND_NO_ARG(tpm_continue_self_test)
+TPM_COMMAND_NO_ARG(tpm_force_clear)
+TPM_COMMAND_NO_ARG(tpm_physical_enable)
+TPM_COMMAND_NO_ARG(tpm_physical_disable)
 
-static cmd_tbl_t tpm_commands[] = {
+static cmd_tbl_t tpm1_commands[] = {
 	U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""),
 	U_BOOT_CMD_MKENT(init, 0, 1, do_tpm_init, "", ""),
 	U_BOOT_CMD_MKENT(startup, 0, 1,
@@ -880,21 +608,15 @@
 #endif /* CONFIG_TPM_LIST_RESOURCES */
 };
 
-static int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+cmd_tbl_t *get_tpm_commands(unsigned int *size)
 {
-	cmd_tbl_t *tpm_cmd;
-
-	if (argc < 2)
-		return CMD_RET_USAGE;
-	tpm_cmd = find_cmd_tbl(argv[1], tpm_commands, ARRAY_SIZE(tpm_commands));
-	if (!tpm_cmd)
-		return CMD_RET_USAGE;
+	*size = ARRAY_SIZE(tpm1_commands);
 
-	return tpm_cmd->cmd(cmdtp, flag, argc - 1, argv + 1);
+	return tpm1_commands;
 }
 
 U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm,
-"Issue a TPM command",
+"Issue a TPMv1.x command",
 "cmd args...\n"
 "    - Issue TPM command <cmd> with arguments <args...>.\n"
 "Admin Startup and State Commands:\n"
diff --git a/cmd/tpm_test.c b/cmd/tpm_test.c
index 2e7d133..35f3c96 100644
--- a/cmd/tpm_test.c
+++ b/cmd/tpm_test.c
@@ -6,7 +6,7 @@
 #include <common.h>
 #include <command.h>
 #include <environment.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 
 /* Prints error and returns on failure */
 #define TPM_CHECK(tpm_command) do { \
diff --git a/drivers/tpm/Kconfig b/drivers/tpm/Kconfig
index 53c3461..bc11f61 100644
--- a/drivers/tpm/Kconfig
+++ b/drivers/tpm/Kconfig
@@ -46,7 +46,7 @@
 
 config TPM_TIS_I2C_BURST_LIMITATION
 	bool "Enable I2C burst length limitation"
-	depends on TPM_V1 && TPM_TIS_INFINEON
+	depends on TPM_TIS_INFINEON
 	help
 	  Some broken TPMs have a limitation on the number of bytes they can
 	  receive in one message. Enable this option to allow you to set this
@@ -62,6 +62,7 @@
 config TPM_TIS_LPC
 	bool "Enable support for Infineon SLB9635/45 TPMs on LPC"
 	depends on TPM_V1 && X86
+	select TPM_DRIVER_SELECTED
 	help
 	  This driver supports Infineon TPM devices connected on the LPC bus.
 	  The usual tpm operations and the 'tpm' command can be used to talk
diff --git a/drivers/tpm/tpm-uclass.c b/drivers/tpm/tpm-uclass.c
index e715452..9488b09 100644
--- a/drivers/tpm/tpm-uclass.c
+++ b/drivers/tpm/tpm-uclass.c
@@ -6,8 +6,10 @@
 
 #include <common.h>
 #include <dm.h>
-#include <tpm.h>
 #include <linux/unaligned/be_byteshift.h>
+#if defined(CONFIG_TPM_V1)
+#include <tpm-v1.h>
+#endif
 #include "tpm_internal.h"
 
 int tpm_open(struct udevice *dev)
diff --git a/drivers/tpm/tpm_atmel_twi.c b/drivers/tpm/tpm_atmel_twi.c
index 8547580..2079ea9 100644
--- a/drivers/tpm/tpm_atmel_twi.c
+++ b/drivers/tpm/tpm_atmel_twi.c
@@ -7,7 +7,7 @@
 
 #include <common.h>
 #include <dm.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <i2c.h>
 #include <asm/unaligned.h>
 
diff --git a/drivers/tpm/tpm_tis_infineon.c b/drivers/tpm/tpm_tis_infineon.c
index 9b2a025..b5fe43e 100644
--- a/drivers/tpm/tpm_tis_infineon.c
+++ b/drivers/tpm/tpm_tis_infineon.c
@@ -23,7 +23,7 @@
 #include <dm.h>
 #include <fdtdec.h>
 #include <i2c.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <linux/errno.h>
 #include <linux/compiler.h>
 #include <linux/types.h>
diff --git a/drivers/tpm/tpm_tis_lpc.c b/drivers/tpm/tpm_tis_lpc.c
index 5729263..7664bb1 100644
--- a/drivers/tpm/tpm_tis_lpc.c
+++ b/drivers/tpm/tpm_tis_lpc.c
@@ -15,7 +15,7 @@
 #include <common.h>
 #include <dm.h>
 #include <mapmem.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <asm/io.h>
 
 #define PREFIX "lpc_tpm: "
diff --git a/drivers/tpm/tpm_tis_sandbox.c b/drivers/tpm/tpm_tis_sandbox.c
index 4415754..8816d55 100644
--- a/drivers/tpm/tpm_tis_sandbox.c
+++ b/drivers/tpm/tpm_tis_sandbox.c
@@ -5,7 +5,7 @@
 
 #include <common.h>
 #include <dm.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <asm/state.h>
 #include <asm/unaligned.h>
 #include <linux/crc8.h>
diff --git a/drivers/tpm/tpm_tis_st33zp24_i2c.c b/drivers/tpm/tpm_tis_st33zp24_i2c.c
index 9cf302c..0d38037 100644
--- a/drivers/tpm/tpm_tis_st33zp24_i2c.c
+++ b/drivers/tpm/tpm_tis_st33zp24_i2c.c
@@ -16,7 +16,7 @@
 #include <dm.h>
 #include <fdtdec.h>
 #include <i2c.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <errno.h>
 #include <linux/types.h>
 #include <asm/unaligned.h>
diff --git a/drivers/tpm/tpm_tis_st33zp24_spi.c b/drivers/tpm/tpm_tis_st33zp24_spi.c
index d5fde11..f6087e7 100644
--- a/drivers/tpm/tpm_tis_st33zp24_spi.c
+++ b/drivers/tpm/tpm_tis_st33zp24_spi.c
@@ -16,7 +16,7 @@
 #include <dm.h>
 #include <fdtdec.h>
 #include <spi.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <errno.h>
 #include <linux/types.h>
 #include <asm/unaligned.h>
diff --git a/include/tpm-common.h b/include/tpm-common.h
new file mode 100644
index 0000000..1ca5d28
--- /dev/null
+++ b/include/tpm-common.h
@@ -0,0 +1,210 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2013 The Chromium OS Authors.
+ * Coypright (c) 2013 Guntermann & Drunck GmbH
+ */
+
+#ifndef __TPM_COMMON_H
+#define __TPM_COMMON_H
+
+enum tpm_duration {
+	TPM_SHORT = 0,
+	TPM_MEDIUM = 1,
+	TPM_LONG = 2,
+	TPM_UNDEFINED,
+
+	TPM_DURATION_COUNT,
+};
+
+/*
+ * Here is a partial implementation of TPM commands.  Please consult TCG Main
+ * Specification for definitions of TPM commands.
+ */
+
+#define TPM_HEADER_SIZE		10
+
+/* Max buffer size supported by our tpm */
+#define TPM_DEV_BUFSIZE		1260
+
+/**
+ * struct tpm_chip_priv - Information about a TPM, stored by the uclass
+ *
+ * These values must be set up by the device's probe() method before
+ * communcation is attempted. If the device has an xfer() method, this is
+ * not needed. There is no need to set up @buf.
+ *
+ * @duration_ms:	Length of each duration type in milliseconds
+ * @retry_time_ms:	Time to wait before retrying receive
+ */
+struct tpm_chip_priv {
+	uint duration_ms[TPM_DURATION_COUNT];
+	uint retry_time_ms;
+	u8 buf[TPM_DEV_BUFSIZE + sizeof(u8)];  /* Max buffer size + addr */
+};
+
+/**
+ * struct tpm_ops - low-level TPM operations
+ *
+ * These are designed to avoid loops and delays in the driver itself. These
+ * should be handled in the uclass.
+ *
+ * In gneral you should implement everything except xfer(). Where you need
+ * complete control of the transfer, then xfer() can be provided and will
+ * override the other methods.
+ *
+ * This interface is for low-level TPM access. It does not understand the
+ * concept of localities or the various TPM messages. That interface is
+ * defined in the functions later on in this file, but they all translate
+ * to bytes which are sent and received.
+ */
+struct tpm_ops {
+	/**
+	 * open() - Request access to locality 0 for the caller
+	 *
+	 * After all commands have been completed the caller should call
+	 * close().
+	 *
+	 * @dev:	Device to close
+	 * @return 0 ok OK, -ve on error
+	 */
+	int (*open)(struct udevice *dev);
+
+	/**
+	 * close() - Close the current session
+	 *
+	 * Releasing the locked locality. Returns 0 on success, -ve 1 on
+	 * failure (in case lock removal did not succeed).
+	 *
+	 * @dev:	Device to close
+	 * @return 0 ok OK, -ve on error
+	 */
+	int (*close)(struct udevice *dev);
+
+	/**
+	 * get_desc() - Get a text description of the TPM
+	 *
+	 * @dev:	Device to check
+	 * @buf:	Buffer to put the string
+	 * @size:	Maximum size of buffer
+	 * @return length of string, or -ENOSPC it no space
+	 */
+	int (*get_desc)(struct udevice *dev, char *buf, int size);
+
+	/**
+	 * send() - send data to the TPM
+	 *
+	 * @dev:	Device to talk to
+	 * @sendbuf:	Buffer of the data to send
+	 * @send_size:	Size of the data to send
+	 *
+	 * Returns 0 on success or -ve on failure.
+	 */
+	int (*send)(struct udevice *dev, const u8 *sendbuf, size_t send_size);
+
+	/**
+	 * recv() - receive a response from the TPM
+	 *
+	 * @dev:	Device to talk to
+	 * @recvbuf:	Buffer to save the response to
+	 * @max_size:	Maximum number of bytes to receive
+	 *
+	 * Returns number of bytes received on success, -EAGAIN if the TPM
+	 * response is not ready, -EINTR if cancelled, or other -ve value on
+	 * failure.
+	 */
+	int (*recv)(struct udevice *dev, u8 *recvbuf, size_t max_size);
+
+	/**
+	 * cleanup() - clean up after an operation in progress
+	 *
+	 * This is called if receiving times out. The TPM may need to abort
+	 * the current transaction if it did not complete, and make itself
+	 * ready for another.
+	 *
+	 * @dev:	Device to talk to
+	 */
+	int (*cleanup)(struct udevice *dev);
+
+	/**
+	 * xfer() - send data to the TPM and get response
+	 *
+	 * This method is optional. If it exists it is used in preference
+	 * to send(), recv() and cleanup(). It should handle all aspects of
+	 * TPM communication for a single transfer.
+	 *
+	 * @dev:	Device to talk to
+	 * @sendbuf:	Buffer of the data to send
+	 * @send_size:	Size of the data to send
+	 * @recvbuf:	Buffer to save the response to
+	 * @recv_size:	Pointer to the size of the response buffer
+	 *
+	 * Returns 0 on success (and places the number of response bytes at
+	 * recv_size) or -ve on failure.
+	 */
+	int (*xfer)(struct udevice *dev, const u8 *sendbuf, size_t send_size,
+		    u8 *recvbuf, size_t *recv_size);
+};
+
+#define tpm_get_ops(dev)        ((struct tpm_ops *)device_get_ops(dev))
+
+#define MAKE_TPM_CMD_ENTRY(cmd) \
+	U_BOOT_CMD_MKENT(cmd, 0, 1, do_tpm_ ## cmd, "", "")
+
+#define TPM_COMMAND_NO_ARG(cmd)				\
+int do_##cmd(cmd_tbl_t *cmdtp, int flag,		\
+	     int argc, char * const argv[])		\
+{							\
+	if (argc != 1)					\
+		return CMD_RET_USAGE;			\
+	return report_return_code(cmd());		\
+}
+
+/**
+ * tpm_get_desc() - Get a text description of the TPM
+ *
+ * @dev:	Device to check
+ * @buf:	Buffer to put the string
+ * @size:	Maximum size of buffer
+ * @return length of string, or -ENOSPC it no space
+ */
+int tpm_get_desc(struct udevice *dev, char *buf, int size);
+
+/**
+ * tpm_xfer() - send data to the TPM and get response
+ *
+ * This first uses the device's send() method to send the bytes. Then it calls
+ * recv() to get the reply. If recv() returns -EAGAIN then it will delay a
+ * short time and then call recv() again.
+ *
+ * Regardless of whether recv() completes successfully, it will then call
+ * cleanup() to finish the transaction.
+ *
+ * Note that the outgoing data is inspected to determine command type
+ * (ordinal) and a timeout is used for that command type.
+ *
+ * @sendbuf - buffer of the data to send
+ * @send_size size of the data to send
+ * @recvbuf - memory to save the response to
+ * @recv_len - pointer to the size of the response buffer
+ *
+ * Returns 0 on success (and places the number of response bytes at
+ * recv_len) or -ve on failure.
+ */
+int tpm_xfer(struct udevice *dev, const u8 *sendbuf, size_t send_size,
+	     u8 *recvbuf, size_t *recv_size);
+
+/**
+ * Initialize TPM device.  It must be called before any TPM commands.
+ *
+ * @return 0 on success, non-0 on error.
+ */
+int tpm_init(void);
+
+/**
+ * Retrieve the array containing all the commands.
+ *
+ * @return a cmd_tbl_t array.
+ */
+cmd_tbl_t *get_tpm_commands(unsigned int *size);
+
+#endif /* __TPM_COMMON_H */
diff --git a/include/tpm.h b/include/tpm-v1.h
similarity index 70%
rename from include/tpm.h
rename to include/tpm-v1.h
index 23d925e..6b4941e 100644
--- a/include/tpm.h
+++ b/include/tpm-v1.h
@@ -4,23 +4,22 @@
  * Coypright (c) 2013 Guntermann & Drunck GmbH
  */
 
-#ifndef __TPM_H
-#define __TPM_H
+#ifndef __TPM_V1_H
+#define __TPM_V1_H
 
-/*
- * Here is a partial implementation of TPM commands.  Please consult TCG Main
- * Specification for definitions of TPM commands.
- */
-
-#define TPM_HEADER_SIZE		10
+#include <tpm-common.h>
 
-enum tpm_duration {
-	TPM_SHORT = 0,
-	TPM_MEDIUM = 1,
-	TPM_LONG = 2,
-	TPM_UNDEFINED,
-
-	TPM_DURATION_COUNT,
+/* Useful constants */
+enum {
+	TPM_REQUEST_HEADER_LENGTH	= 10,
+	TPM_RESPONSE_HEADER_LENGTH	= 10,
+	PCR_DIGEST_LENGTH		= 20,
+	DIGEST_LENGTH			= 20,
+	TPM_REQUEST_AUTH_LENGTH		= 45,
+	TPM_RESPONSE_AUTH_LENGTH	= 41,
+	/* some max lengths, valid for RSA keys <= 2048 bits */
+	TPM_KEY12_MAX_LENGTH		= 618,
+	TPM_PUBKEY_MAX_LENGTH		= 288,
 };
 
 enum tpm_startup_type {
@@ -232,190 +231,7 @@
 	u8	disable_full_da_logic_info;
 } __packed;
 
-/* Max buffer size supported by our tpm */
-#define TPM_DEV_BUFSIZE		1260
-
-/**
- * struct tpm_chip_priv - Information about a TPM, stored by the uclass
- *
- * These values must be set up by the device's probe() method before
- * communcation is attempted. If the device has an xfer() method, this is
- * not needed. There is no need to set up @buf.
- *
- * @duration_ms:	Length of each duration type in milliseconds
- * @retry_time_ms:	Time to wait before retrying receive
- */
-struct tpm_chip_priv {
-	uint duration_ms[TPM_DURATION_COUNT];
-	uint retry_time_ms;
-	u8 buf[TPM_DEV_BUFSIZE + sizeof(u8)];  /* Max buffer size + addr */
-};
-
-/**
- * struct tpm_ops - low-level TPM operations
- *
- * These are designed to avoid loops and delays in the driver itself. These
- * should be handled in the uclass.
- *
- * In gneral you should implement everything except xfer(). Where you need
- * complete control of the transfer, then xfer() can be provided and will
- * override the other methods.
- *
- * This interface is for low-level TPM access. It does not understand the
- * concept of localities or the various TPM messages. That interface is
- * defined in the functions later on in this file, but they all translate
- * to bytes which are sent and received.
- */
-struct tpm_ops {
-	/**
-	 * open() - Request access to locality 0 for the caller
-	 *
-	 * After all commands have been completed the caller should call
-	 * close().
-	 *
-	 * @dev:	Device to close
-	 * @return 0 ok OK, -ve on error
-	 */
-	int (*open)(struct udevice *dev);
-
-	/**
-	 * close() - Close the current session
-	 *
-	 * Releasing the locked locality. Returns 0 on success, -ve 1 on
-	 * failure (in case lock removal did not succeed).
-	 *
-	 * @dev:	Device to close
-	 * @return 0 ok OK, -ve on error
-	 */
-	int (*close)(struct udevice *dev);
-
-	/**
-	 * get_desc() - Get a text description of the TPM
-	 *
-	 * @dev:	Device to check
-	 * @buf:	Buffer to put the string
-	 * @size:	Maximum size of buffer
-	 * @return length of string, or -ENOSPC it no space
-	 */
-	int (*get_desc)(struct udevice *dev, char *buf, int size);
-
-	/**
-	 * send() - send data to the TPM
-	 *
-	 * @dev:	Device to talk to
-	 * @sendbuf:	Buffer of the data to send
-	 * @send_size:	Size of the data to send
-	 *
-	 * Returns 0 on success or -ve on failure.
-	 */
-	int (*send)(struct udevice *dev, const u8 *sendbuf, size_t send_size);
-
-	/**
-	 * recv() - receive a response from the TPM
-	 *
-	 * @dev:	Device to talk to
-	 * @recvbuf:	Buffer to save the response to
-	 * @max_size:	Maximum number of bytes to receive
-	 *
-	 * Returns number of bytes received on success, -EAGAIN if the TPM
-	 * response is not ready, -EINTR if cancelled, or other -ve value on
-	 * failure.
-	 */
-	int (*recv)(struct udevice *dev, u8 *recvbuf, size_t max_size);
-
-	/**
-	 * cleanup() - clean up after an operation in progress
-	 *
-	 * This is called if receiving times out. The TPM may need to abort
-	 * the current transaction if it did not complete, and make itself
-	 * ready for another.
-	 *
-	 * @dev:	Device to talk to
-	 */
-	int (*cleanup)(struct udevice *dev);
-
-	/**
-	 * xfer() - send data to the TPM and get response
-	 *
-	 * This method is optional. If it exists it is used in preference
-	 * to send(), recv() and cleanup(). It should handle all aspects of
-	 * TPM communication for a single transfer.
-	 *
-	 * @dev:	Device to talk to
-	 * @sendbuf:	Buffer of the data to send
-	 * @send_size:	Size of the data to send
-	 * @recvbuf:	Buffer to save the response to
-	 * @recv_size:	Pointer to the size of the response buffer
-	 *
-	 * Returns 0 on success (and places the number of response bytes at
-	 * recv_size) or -ve on failure.
-	 */
-	int (*xfer)(struct udevice *dev, const u8 *sendbuf, size_t send_size,
-		    u8 *recvbuf, size_t *recv_size);
-};
-
-#define tpm_get_ops(dev)        ((struct tpm_ops *)device_get_ops(dev))
-
 /**
- * tpm_open() - Request access to locality 0 for the caller
- *
- * After all commands have been completed the caller is supposed to
- * call tpm_close().
- *
- * Returns 0 on success, -ve on failure.
- */
-int tpm_open(struct udevice *dev);
-
-/**
- * tpm_close() - Close the current session
- *
- * Releasing the locked locality. Returns 0 on success, -ve 1 on
- * failure (in case lock removal did not succeed).
- */
-int tpm_close(struct udevice *dev);
-
-/**
- * tpm_get_desc() - Get a text description of the TPM
- *
- * @dev:	Device to check
- * @buf:	Buffer to put the string
- * @size:	Maximum size of buffer
- * @return length of string, or -ENOSPC it no space
- */
-int tpm_get_desc(struct udevice *dev, char *buf, int size);
-
-/**
- * tpm_xfer() - send data to the TPM and get response
- *
- * This first uses the device's send() method to send the bytes. Then it calls
- * recv() to get the reply. If recv() returns -EAGAIN then it will delay a
- * short time and then call recv() again.
- *
- * Regardless of whether recv() completes successfully, it will then call
- * cleanup() to finish the transaction.
- *
- * Note that the outgoing data is inspected to determine command type
- * (ordinal) and a timeout is used for that command type.
- *
- * @sendbuf - buffer of the data to send
- * @send_size size of the data to send
- * @recvbuf - memory to save the response to
- * @recv_len - pointer to the size of the response buffer
- *
- * Returns 0 on success (and places the number of response bytes at
- * recv_len) or -ve on failure.
- */
-int tpm_xfer(struct udevice *dev, const u8 *sendbuf, size_t send_size,
-	     u8 *recvbuf, size_t *recv_size);
-
-/**
- * Initialize TPM device.  It must be called before any TPM commands.
- *
- * @return 0 on success, non-0 on error.
- */
-int tpm_init(void);
-
-/**
  * Issue a TPM_Startup command.
  *
  * @param mode		TPM startup mode
@@ -661,4 +477,4 @@
  */
 u32 tpm_get_random(void *data, u32 count);
 
-#endif /* __TPM_H */
+#endif /* __TPM_V1_H */
diff --git a/lib/Makefile b/lib/Makefile
index 2a56b3b..72504e7 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -39,7 +39,8 @@
 obj-y += qsort.o
 obj-y += rc4.o
 obj-$(CONFIG_SUPPORT_EMMC_RPMB) += sha256.o
-obj-$(CONFIG_TPM_V1) += tpm.o
+obj-$(CONFIG_TPM) += tpm-common.o
+obj-$(CONFIG_TPM_V1) += tpm-v1.o
 obj-$(CONFIG_RBTREE)	+= rbtree.o
 obj-$(CONFIG_BITREVERSE) += bitrev.o
 obj-y += list_sort.o
diff --git a/lib/tpm-common.c b/lib/tpm-common.c
new file mode 100644
index 0000000..4c2b939
--- /dev/null
+++ b/lib/tpm-common.c
@@ -0,0 +1,188 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2013 The Chromium OS Authors.
+ * Coypright (c) 2013 Guntermann & Drunck GmbH
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/unaligned.h>
+#include <tpm-common.h>
+#include "tpm-utils.h"
+
+int pack_byte_string(u8 *str, size_t size, const char *format, ...)
+{
+	va_list args;
+	size_t offset = 0, length = 0;
+	u8 *data = NULL;
+	u32 value = 0;
+
+	va_start(args, format);
+	for (; *format; format++) {
+		switch (*format) {
+		case 'b':
+			offset = va_arg(args, size_t);
+			value = va_arg(args, int);
+			length = 1;
+			break;
+		case 'w':
+			offset = va_arg(args, size_t);
+			value = va_arg(args, int);
+			length = 2;
+			break;
+		case 'd':
+			offset = va_arg(args, size_t);
+			value = va_arg(args, u32);
+			length = 4;
+			break;
+		case 's':
+			offset = va_arg(args, size_t);
+			data = va_arg(args, u8 *);
+			length = va_arg(args, u32);
+			break;
+		default:
+			debug("Couldn't recognize format string\n");
+			va_end(args);
+			return -1;
+		}
+
+		if (offset + length > size) {
+			va_end(args);
+			return -1;
+		}
+
+		switch (*format) {
+		case 'b':
+			str[offset] = value;
+			break;
+		case 'w':
+			put_unaligned_be16(value, str + offset);
+			break;
+		case 'd':
+			put_unaligned_be32(value, str + offset);
+			break;
+		case 's':
+			memcpy(str + offset, data, length);
+			break;
+		}
+	}
+	va_end(args);
+
+	return 0;
+}
+
+int unpack_byte_string(const u8 *str, size_t size, const char *format, ...)
+{
+	va_list args;
+	size_t offset = 0, length = 0;
+	u8 *ptr8 = NULL;
+	u16 *ptr16 = NULL;
+	u32 *ptr32 = NULL;
+
+	va_start(args, format);
+	for (; *format; format++) {
+		switch (*format) {
+		case 'b':
+			offset = va_arg(args, size_t);
+			ptr8 = va_arg(args, u8 *);
+			length = 1;
+			break;
+		case 'w':
+			offset = va_arg(args, size_t);
+			ptr16 = va_arg(args, u16 *);
+			length = 2;
+			break;
+		case 'd':
+			offset = va_arg(args, size_t);
+			ptr32 = va_arg(args, u32 *);
+			length = 4;
+			break;
+		case 's':
+			offset = va_arg(args, size_t);
+			ptr8 = va_arg(args, u8 *);
+			length = va_arg(args, u32);
+			break;
+		default:
+			va_end(args);
+			debug("Couldn't recognize format string\n");
+			return -1;
+		}
+
+		if (offset + length > size) {
+			va_end(args);
+			return -1;
+		}
+
+		switch (*format) {
+		case 'b':
+			*ptr8 = str[offset];
+			break;
+		case 'w':
+			*ptr16 = get_unaligned_be16(str + offset);
+			break;
+		case 'd':
+			*ptr32 = get_unaligned_be32(str + offset);
+			break;
+		case 's':
+			memcpy(ptr8, str + offset, length);
+			break;
+		}
+	}
+	va_end(args);
+
+	return 0;
+}
+
+u32 tpm_command_size(const void *command)
+{
+	const size_t command_size_offset = 2;
+
+	return get_unaligned_be32(command + command_size_offset);
+}
+
+u32 tpm_return_code(const void *response)
+{
+	const size_t return_code_offset = 6;
+
+	return get_unaligned_be32(response + return_code_offset);
+}
+
+u32 tpm_sendrecv_command(const void *command, void *response, size_t *size_ptr)
+{
+	struct udevice *dev;
+	int err, ret;
+	u8 response_buffer[COMMAND_BUFFER_SIZE];
+	size_t response_length;
+
+	if (response) {
+		response_length = *size_ptr;
+	} else {
+		response = response_buffer;
+		response_length = sizeof(response_buffer);
+	}
+
+	ret = uclass_first_device_err(UCLASS_TPM, &dev);
+	if (ret)
+		return ret;
+	err = tpm_xfer(dev, command, tpm_command_size(command),
+		       response, &response_length);
+
+	if (err < 0)
+		return TPM_LIB_ERROR;
+	if (size_ptr)
+		*size_ptr = response_length;
+
+	return tpm_return_code(response);
+}
+
+int tpm_init(void)
+{
+	struct udevice *dev;
+	int err;
+
+	err = uclass_first_device_err(UCLASS_TPM, &dev);
+	if (err)
+		return err;
+
+	return tpm_open(dev);
+}
diff --git a/lib/tpm-utils.h b/lib/tpm-utils.h
new file mode 100644
index 0000000..bc98d1e
--- /dev/null
+++ b/lib/tpm-utils.h
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2013 The Chromium OS Authors.
+ * Coypright (c) 2013 Guntermann & Drunck GmbH
+ */
+
+#ifndef __TPM_UTILS_H
+#define __TPM_UTILS_H
+
+#define COMMAND_BUFFER_SIZE 256
+
+/* Internal error of TPM command library */
+#define TPM_LIB_ERROR ((u32)~0u)
+
+/**
+ * tpm_open() - Request access to locality 0 for the caller
+ *
+ * After all commands have been completed the caller is supposed to
+ * call tpm_close().
+ *
+ * Returns 0 on success, -ve on failure.
+ */
+int tpm_open(struct udevice *dev);
+
+/**
+ * tpm_close() - Close the current session
+ *
+ * Releasing the locked locality. Returns 0 on success, -ve 1 on
+ * failure (in case lock removal did not succeed).
+ */
+int tpm_close(struct udevice *dev);
+
+/**
+ * Pack data into a byte string.  The data types are specified in
+ * the format string: 'b' means unsigned byte, 'w' unsigned word,
+ * 'd' unsigned double word, and 's' byte string.  The data are a
+ * series of offsets and values (for type byte string there are also
+ * lengths).  The data values are packed into the byte string
+ * sequentially, and so a latter value could over-write a former
+ * value.
+ *
+ * @param str		output string
+ * @param size		size of output string
+ * @param format	format string
+ * @param ...		data points
+ * @return 0 on success, non-0 on error
+ */
+int pack_byte_string(u8 *str, size_t size, const char *format, ...);
+
+/**
+ * Unpack data from a byte string.  The data types are specified in
+ * the format string: 'b' means unsigned byte, 'w' unsigned word,
+ * 'd' unsigned double word, and 's' byte string.  The data are a
+ * series of offsets and pointers (for type byte string there are also
+ * lengths).
+ *
+ * @param str		output string
+ * @param size		size of output string
+ * @param format	format string
+ * @param ...		data points
+ * @return 0 on success, non-0 on error
+ */
+int unpack_byte_string(const u8 *str, size_t size, const char *format, ...);
+
+/**
+ * Get TPM command size.
+ *
+ * @param command	byte string of TPM command
+ * @return command size of the TPM command
+ */
+u32 tpm_command_size(const void *command);
+
+/**
+ * Get TPM response return code, which is one of TPM_RESULT values.
+ *
+ * @param response	byte string of TPM response
+ * @return return code of the TPM response
+ */
+u32 tpm_return_code(const void *response);
+
+/**
+ * Send a TPM command and return response's return code, and optionally
+ * return response to caller.
+ *
+ * @param command	byte string of TPM command
+ * @param response	output buffer for TPM response, or NULL if the
+ *			caller does not care about it
+ * @param size_ptr	output buffer size (input parameter) and TPM
+ *			response length (output parameter); this parameter
+ *			is a bidirectional
+ * @return return code of the TPM response
+ */
+u32 tpm_sendrecv_command(const void *command, void *response, size_t *size_ptr);
+
+#endif /* __TPM_UTILS_H */
diff --git a/lib/tpm.c b/lib/tpm-v1.c
similarity index 81%
rename from lib/tpm.c
rename to lib/tpm-v1.c
index 899528e..7aecb24 100644
--- a/lib/tpm.c
+++ b/lib/tpm-v1.c
@@ -6,26 +6,11 @@
 
 #include <common.h>
 #include <dm.h>
-#include <tpm.h>
 #include <asm/unaligned.h>
 #include <u-boot/sha1.h>
-
-/* Internal error of TPM command library */
-#define TPM_LIB_ERROR	((u32)~0u)
-
-/* Useful constants */
-enum {
-	COMMAND_BUFFER_SIZE		= 256,
-	TPM_REQUEST_HEADER_LENGTH	= 10,
-	TPM_RESPONSE_HEADER_LENGTH	= 10,
-	PCR_DIGEST_LENGTH		= 20,
-	DIGEST_LENGTH			= 20,
-	TPM_REQUEST_AUTH_LENGTH		= 45,
-	TPM_RESPONSE_AUTH_LENGTH	= 41,
-	/* some max lengths, valid for RSA keys <= 2048 bits */
-	TPM_KEY12_MAX_LENGTH		= 618,
-	TPM_PUBKEY_MAX_LENGTH		= 288,
-};
+#include <tpm-common.h>
+#include <tpm-v1.h>
+#include "tpm-utils.h"
 
 #ifdef CONFIG_TPM_AUTH_SESSIONS
 
@@ -44,235 +29,6 @@
 
 #endif /* CONFIG_TPM_AUTH_SESSIONS */
 
-/**
- * Pack data into a byte string.  The data types are specified in
- * the format string: 'b' means unsigned byte, 'w' unsigned word,
- * 'd' unsigned double word, and 's' byte string.  The data are a
- * series of offsets and values (for type byte string there are also
- * lengths).  The data values are packed into the byte string
- * sequentially, and so a latter value could over-write a former
- * value.
- *
- * @param str		output string
- * @param size		size of output string
- * @param format	format string
- * @param ...		data points
- * @return 0 on success, non-0 on error
- */
-int pack_byte_string(u8 *str, size_t size, const char *format, ...)
-{
-	va_list args;
-	size_t offset = 0, length = 0;
-	u8 *data = NULL;
-	u32 value = 0;
-
-	va_start(args, format);
-	for (; *format; format++) {
-		switch (*format) {
-		case 'b':
-			offset = va_arg(args, size_t);
-			value = va_arg(args, int);
-			length = 1;
-			break;
-		case 'w':
-			offset = va_arg(args, size_t);
-			value = va_arg(args, int);
-			length = 2;
-			break;
-		case 'd':
-			offset = va_arg(args, size_t);
-			value = va_arg(args, u32);
-			length = 4;
-			break;
-		case 's':
-			offset = va_arg(args, size_t);
-			data = va_arg(args, u8 *);
-			length = va_arg(args, u32);
-			break;
-		default:
-			debug("Couldn't recognize format string\n");
-			va_end(args);
-			return -1;
-		}
-
-		if (offset + length > size) {
-			va_end(args);
-			return -1;
-		}
-
-		switch (*format) {
-		case 'b':
-			str[offset] = value;
-			break;
-		case 'w':
-			put_unaligned_be16(value, str + offset);
-			break;
-		case 'd':
-			put_unaligned_be32(value, str + offset);
-			break;
-		case 's':
-			memcpy(str + offset, data, length);
-			break;
-		}
-	}
-	va_end(args);
-
-	return 0;
-}
-
-/**
- * Unpack data from a byte string.  The data types are specified in
- * the format string: 'b' means unsigned byte, 'w' unsigned word,
- * 'd' unsigned double word, and 's' byte string.  The data are a
- * series of offsets and pointers (for type byte string there are also
- * lengths).
- *
- * @param str		output string
- * @param size		size of output string
- * @param format	format string
- * @param ...		data points
- * @return 0 on success, non-0 on error
- */
-int unpack_byte_string(const u8 *str, size_t size, const char *format, ...)
-{
-	va_list args;
-	size_t offset = 0, length = 0;
-	u8 *ptr8 = NULL;
-	u16 *ptr16 = NULL;
-	u32 *ptr32 = NULL;
-
-	va_start(args, format);
-	for (; *format; format++) {
-		switch (*format) {
-		case 'b':
-			offset = va_arg(args, size_t);
-			ptr8 = va_arg(args, u8 *);
-			length = 1;
-			break;
-		case 'w':
-			offset = va_arg(args, size_t);
-			ptr16 = va_arg(args, u16 *);
-			length = 2;
-			break;
-		case 'd':
-			offset = va_arg(args, size_t);
-			ptr32 = va_arg(args, u32 *);
-			length = 4;
-			break;
-		case 's':
-			offset = va_arg(args, size_t);
-			ptr8 = va_arg(args, u8 *);
-			length = va_arg(args, u32);
-			break;
-		default:
-			va_end(args);
-			debug("Couldn't recognize format string\n");
-			return -1;
-		}
-
-		if (offset + length > size) {
-			va_end(args);
-			return -1;
-		}
-
-		switch (*format) {
-		case 'b':
-			*ptr8 = str[offset];
-			break;
-		case 'w':
-			*ptr16 = get_unaligned_be16(str + offset);
-			break;
-		case 'd':
-			*ptr32 = get_unaligned_be32(str + offset);
-			break;
-		case 's':
-			memcpy(ptr8, str + offset, length);
-			break;
-		}
-	}
-	va_end(args);
-
-	return 0;
-}
-
-/**
- * Get TPM command size.
- *
- * @param command	byte string of TPM command
- * @return command size of the TPM command
- */
-static u32 tpm_command_size(const void *command)
-{
-	const size_t command_size_offset = 2;
-
-	return get_unaligned_be32(command + command_size_offset);
-}
-
-/**
- * Get TPM response return code, which is one of TPM_RESULT values.
- *
- * @param response	byte string of TPM response
- * @return return code of the TPM response
- */
-static u32 tpm_return_code(const void *response)
-{
-	const size_t return_code_offset = 6;
-
-	return get_unaligned_be32(response + return_code_offset);
-}
-
-/**
- * Send a TPM command and return response's return code, and optionally
- * return response to caller.
- *
- * @param command	byte string of TPM command
- * @param response	output buffer for TPM response, or NULL if the
- *			caller does not care about it
- * @param size_ptr	output buffer size (input parameter) and TPM
- *			response length (output parameter); this parameter
- *			is a bidirectional
- * @return return code of the TPM response
- */
-static u32 tpm_sendrecv_command(const void *command, void *response,
-				size_t *size_ptr)
-{
-	struct udevice *dev;
-	int err, ret;
-	u8 response_buffer[COMMAND_BUFFER_SIZE];
-	size_t response_length;
-
-	if (response) {
-		response_length = *size_ptr;
-	} else {
-		response = response_buffer;
-		response_length = sizeof(response_buffer);
-	}
-
-	ret = uclass_first_device_err(UCLASS_TPM, &dev);
-	if (ret)
-		return ret;
-	err = tpm_xfer(dev, command, tpm_command_size(command),
-		       response, &response_length);
-
-	if (err < 0)
-		return TPM_LIB_ERROR;
-	if (size_ptr)
-		*size_ptr = response_length;
-
-	return tpm_return_code(response);
-}
-
-int tpm_init(void)
-{
-	int err;
-	struct udevice *dev;
-
-	err = uclass_first_device_err(UCLASS_TPM, &dev);
-	if (err)
-		return err;
-	return tpm_open(dev);
-}
-
 u32 tpm_startup(enum tpm_startup_type mode)
 {
 	const u8 command[12] = {