0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #include <linux/acpi.h>
0024 #include <linux/completion.h>
0025 #include <linux/init.h>
0026 #include <linux/interrupt.h>
0027 #include <linux/kernel.h>
0028 #include <linux/module.h>
0029 #include <linux/slab.h>
0030
0031 #include <linux/of_device.h>
0032 #include <linux/spi/spi.h>
0033 #include <linux/tpm.h>
0034
0035 #include "tpm.h"
0036 #include "tpm_tis_core.h"
0037 #include "tpm_tis_spi.h"
0038
0039 #define MAX_SPI_FRAMESIZE 64
0040
0041
0042
0043
0044
0045
0046
0047
0048 static int tpm_tis_spi_flow_control(struct tpm_tis_spi_phy *phy,
0049 struct spi_transfer *spi_xfer)
0050 {
0051 struct spi_message m;
0052 int ret, i;
0053
0054 if ((phy->iobuf[3] & 0x01) == 0) {
0055
0056 for (i = 0; i < TPM_RETRY; i++) {
0057 spi_xfer->len = 1;
0058 spi_message_init(&m);
0059 spi_message_add_tail(spi_xfer, &m);
0060 ret = spi_sync_locked(phy->spi_device, &m);
0061 if (ret < 0)
0062 return ret;
0063 if (phy->iobuf[0] & 0x01)
0064 break;
0065 }
0066
0067 if (i == TPM_RETRY)
0068 return -ETIMEDOUT;
0069 }
0070
0071 return 0;
0072 }
0073
0074 int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
0075 u8 *in, const u8 *out)
0076 {
0077 struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data);
0078 int ret = 0;
0079 struct spi_message m;
0080 struct spi_transfer spi_xfer;
0081 u8 transfer_len;
0082
0083 spi_bus_lock(phy->spi_device->master);
0084
0085 while (len) {
0086 transfer_len = min_t(u16, len, MAX_SPI_FRAMESIZE);
0087
0088 phy->iobuf[0] = (in ? 0x80 : 0) | (transfer_len - 1);
0089 phy->iobuf[1] = 0xd4;
0090 phy->iobuf[2] = addr >> 8;
0091 phy->iobuf[3] = addr;
0092
0093 memset(&spi_xfer, 0, sizeof(spi_xfer));
0094 spi_xfer.tx_buf = phy->iobuf;
0095 spi_xfer.rx_buf = phy->iobuf;
0096 spi_xfer.len = 4;
0097 spi_xfer.cs_change = 1;
0098
0099 spi_message_init(&m);
0100 spi_message_add_tail(&spi_xfer, &m);
0101 ret = spi_sync_locked(phy->spi_device, &m);
0102 if (ret < 0)
0103 goto exit;
0104
0105
0106 spi_xfer.tx_buf = NULL;
0107 ret = phy->flow_control(phy, &spi_xfer);
0108 if (ret < 0)
0109 goto exit;
0110
0111 spi_xfer.cs_change = 0;
0112 spi_xfer.len = transfer_len;
0113 spi_xfer.delay.value = 5;
0114 spi_xfer.delay.unit = SPI_DELAY_UNIT_USECS;
0115
0116 if (out) {
0117 spi_xfer.tx_buf = phy->iobuf;
0118 spi_xfer.rx_buf = NULL;
0119 memcpy(phy->iobuf, out, transfer_len);
0120 out += transfer_len;
0121 }
0122
0123 spi_message_init(&m);
0124 spi_message_add_tail(&spi_xfer, &m);
0125 reinit_completion(&phy->ready);
0126 ret = spi_sync_locked(phy->spi_device, &m);
0127 if (ret < 0)
0128 goto exit;
0129
0130 if (in) {
0131 memcpy(in, phy->iobuf, transfer_len);
0132 in += transfer_len;
0133 }
0134
0135 len -= transfer_len;
0136 }
0137
0138 exit:
0139 spi_bus_unlock(phy->spi_device->master);
0140 return ret;
0141 }
0142
0143 static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr,
0144 u16 len, u8 *result, enum tpm_tis_io_mode io_mode)
0145 {
0146 return tpm_tis_spi_transfer(data, addr, len, result, NULL);
0147 }
0148
0149 static int tpm_tis_spi_write_bytes(struct tpm_tis_data *data, u32 addr,
0150 u16 len, const u8 *value, enum tpm_tis_io_mode io_mode)
0151 {
0152 return tpm_tis_spi_transfer(data, addr, len, NULL, value);
0153 }
0154
0155 int tpm_tis_spi_init(struct spi_device *spi, struct tpm_tis_spi_phy *phy,
0156 int irq, const struct tpm_tis_phy_ops *phy_ops)
0157 {
0158 phy->iobuf = devm_kmalloc(&spi->dev, MAX_SPI_FRAMESIZE, GFP_KERNEL);
0159 if (!phy->iobuf)
0160 return -ENOMEM;
0161
0162 phy->spi_device = spi;
0163
0164 return tpm_tis_core_init(&spi->dev, &phy->priv, irq, phy_ops, NULL);
0165 }
0166
0167 static const struct tpm_tis_phy_ops tpm_spi_phy_ops = {
0168 .read_bytes = tpm_tis_spi_read_bytes,
0169 .write_bytes = tpm_tis_spi_write_bytes,
0170 };
0171
0172 static int tpm_tis_spi_probe(struct spi_device *dev)
0173 {
0174 struct tpm_tis_spi_phy *phy;
0175 int irq;
0176
0177 phy = devm_kzalloc(&dev->dev, sizeof(struct tpm_tis_spi_phy),
0178 GFP_KERNEL);
0179 if (!phy)
0180 return -ENOMEM;
0181
0182 phy->flow_control = tpm_tis_spi_flow_control;
0183
0184
0185 if (dev->irq > 0)
0186 irq = dev->irq;
0187 else
0188 irq = -1;
0189
0190 init_completion(&phy->ready);
0191 return tpm_tis_spi_init(dev, phy, irq, &tpm_spi_phy_ops);
0192 }
0193
0194 typedef int (*tpm_tis_spi_probe_func)(struct spi_device *);
0195
0196 static int tpm_tis_spi_driver_probe(struct spi_device *spi)
0197 {
0198 const struct spi_device_id *spi_dev_id = spi_get_device_id(spi);
0199 tpm_tis_spi_probe_func probe_func;
0200
0201 probe_func = of_device_get_match_data(&spi->dev);
0202 if (!probe_func) {
0203 if (spi_dev_id) {
0204 probe_func = (tpm_tis_spi_probe_func)spi_dev_id->driver_data;
0205 if (!probe_func)
0206 return -ENODEV;
0207 } else
0208 probe_func = tpm_tis_spi_probe;
0209 }
0210
0211 return probe_func(spi);
0212 }
0213
0214 static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_spi_resume);
0215
0216 static void tpm_tis_spi_remove(struct spi_device *dev)
0217 {
0218 struct tpm_chip *chip = spi_get_drvdata(dev);
0219
0220 tpm_chip_unregister(chip);
0221 tpm_tis_remove(chip);
0222 }
0223
0224 static const struct spi_device_id tpm_tis_spi_id[] = {
0225 { "st33htpm-spi", (unsigned long)tpm_tis_spi_probe },
0226 { "slb9670", (unsigned long)tpm_tis_spi_probe },
0227 { "tpm_tis_spi", (unsigned long)tpm_tis_spi_probe },
0228 { "tpm_tis-spi", (unsigned long)tpm_tis_spi_probe },
0229 { "cr50", (unsigned long)cr50_spi_probe },
0230 {}
0231 };
0232 MODULE_DEVICE_TABLE(spi, tpm_tis_spi_id);
0233
0234 static const struct of_device_id of_tis_spi_match[] = {
0235 { .compatible = "st,st33htpm-spi", .data = tpm_tis_spi_probe },
0236 { .compatible = "infineon,slb9670", .data = tpm_tis_spi_probe },
0237 { .compatible = "tcg,tpm_tis-spi", .data = tpm_tis_spi_probe },
0238 { .compatible = "google,cr50", .data = cr50_spi_probe },
0239 {}
0240 };
0241 MODULE_DEVICE_TABLE(of, of_tis_spi_match);
0242
0243 static const struct acpi_device_id acpi_tis_spi_match[] = {
0244 {"SMO0768", 0},
0245 {}
0246 };
0247 MODULE_DEVICE_TABLE(acpi, acpi_tis_spi_match);
0248
0249 static struct spi_driver tpm_tis_spi_driver = {
0250 .driver = {
0251 .name = "tpm_tis_spi",
0252 .pm = &tpm_tis_pm,
0253 .of_match_table = of_match_ptr(of_tis_spi_match),
0254 .acpi_match_table = ACPI_PTR(acpi_tis_spi_match),
0255 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
0256 },
0257 .probe = tpm_tis_spi_driver_probe,
0258 .remove = tpm_tis_spi_remove,
0259 .id_table = tpm_tis_spi_id,
0260 };
0261 module_spi_driver(tpm_tis_spi_driver);
0262
0263 MODULE_DESCRIPTION("TPM Driver for native SPI access");
0264 MODULE_LICENSE("GPL");