|
@@ -1,5 +1,5 @@
|
|
|
-/******************************************************************************
|
|
|
- * Nuvoton TPM I2C Device Driver Interface for WPCT301/NPCT501,
|
|
|
+ /******************************************************************************
|
|
|
+ * Nuvoton TPM I2C Device Driver Interface for WPCT301/NPCT501/NPCT6XX,
|
|
|
* based on the TCG TPM Interface Spec version 1.2.
|
|
|
* Specifications at www.trustedcomputinggroup.org
|
|
|
*
|
|
@@ -31,6 +31,7 @@
|
|
|
#include <linux/interrupt.h>
|
|
|
#include <linux/wait.h>
|
|
|
#include <linux/i2c.h>
|
|
|
+#include <linux/of_device.h>
|
|
|
#include "tpm.h"
|
|
|
|
|
|
/* I2C interface offsets */
|
|
@@ -52,7 +53,8 @@
|
|
|
#define TPM_I2C_RETRY_DELAY_SHORT 2 /* msec */
|
|
|
#define TPM_I2C_RETRY_DELAY_LONG 10 /* msec */
|
|
|
|
|
|
-#define I2C_DRIVER_NAME "tpm_i2c_nuvoton"
|
|
|
+#define OF_IS_TPM2 ((void *)1)
|
|
|
+#define I2C_IS_TPM2 1
|
|
|
|
|
|
struct priv_data {
|
|
|
int irq;
|
|
@@ -165,7 +167,7 @@ static int i2c_nuvoton_get_burstcount(struct i2c_client *client,
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * WPCT301/NPCT501 SINT# supports only dataAvail
|
|
|
+ * WPCT301/NPCT501/NPCT6XX SINT# supports only dataAvail
|
|
|
* any call to this function which is not waiting for dataAvail will
|
|
|
* set queue to NULL to avoid waiting for interrupt
|
|
|
*/
|
|
@@ -545,6 +547,16 @@ static int i2c_nuvoton_probe(struct i2c_client *client,
|
|
|
if (!priv)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
+ if (dev->of_node) {
|
|
|
+ const struct of_device_id *of_id;
|
|
|
+
|
|
|
+ of_id = of_match_device(dev->driver->of_match_table, dev);
|
|
|
+ if (of_id && of_id->data == OF_IS_TPM2)
|
|
|
+ chip->flags |= TPM_CHIP_FLAG_TPM2;
|
|
|
+ } else
|
|
|
+ if (id->driver_data == I2C_IS_TPM2)
|
|
|
+ chip->flags |= TPM_CHIP_FLAG_TPM2;
|
|
|
+
|
|
|
init_waitqueue_head(&priv->read_queue);
|
|
|
|
|
|
/* Default timeouts */
|
|
@@ -620,7 +632,8 @@ static int i2c_nuvoton_remove(struct i2c_client *client)
|
|
|
}
|
|
|
|
|
|
static const struct i2c_device_id i2c_nuvoton_id[] = {
|
|
|
- {I2C_DRIVER_NAME, 0},
|
|
|
+ {"tpm_i2c_nuvoton"},
|
|
|
+ {"tpm2_i2c_nuvoton", .driver_data = I2C_IS_TPM2},
|
|
|
{}
|
|
|
};
|
|
|
MODULE_DEVICE_TABLE(i2c, i2c_nuvoton_id);
|
|
@@ -629,6 +642,7 @@ MODULE_DEVICE_TABLE(i2c, i2c_nuvoton_id);
|
|
|
static const struct of_device_id i2c_nuvoton_of_match[] = {
|
|
|
{.compatible = "nuvoton,npct501"},
|
|
|
{.compatible = "winbond,wpct301"},
|
|
|
+ {.compatible = "nuvoton,npct601", .data = OF_IS_TPM2},
|
|
|
{},
|
|
|
};
|
|
|
MODULE_DEVICE_TABLE(of, i2c_nuvoton_of_match);
|
|
@@ -641,7 +655,7 @@ static struct i2c_driver i2c_nuvoton_driver = {
|
|
|
.probe = i2c_nuvoton_probe,
|
|
|
.remove = i2c_nuvoton_remove,
|
|
|
.driver = {
|
|
|
- .name = I2C_DRIVER_NAME,
|
|
|
+ .name = "tpm_i2c_nuvoton",
|
|
|
.pm = &i2c_nuvoton_pm_ops,
|
|
|
.of_match_table = of_match_ptr(i2c_nuvoton_of_match),
|
|
|
},
|