1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * STMicroelectronics TPM SPI Linux driver for TPM ST33ZP24 4 * Copyright (C) 2009 - 2016 STMicroelectronics 5 */ 6 7 #include <linux/module.h> 8 #include <linux/spi/spi.h> 9 #include <linux/of.h> 10 #include <linux/acpi.h> 11 #include <linux/tpm.h> 12 13 #include "../tpm.h" 14 #include "st33zp24.h" 15 16 #define TPM_DATA_FIFO 0x24 17 #define TPM_INTF_CAPABILITY 0x14 18 19 #define TPM_DUMMY_BYTE 0x00 20 21 #define MAX_SPI_LATENCY 15 22 #define LOCALITY0 0 23 24 #define ST33ZP24_OK 0x5A 25 #define ST33ZP24_UNDEFINED_ERR 0x80 26 #define ST33ZP24_BADLOCALITY 0x81 27 #define ST33ZP24_TISREGISTER_UNKNOWN 0x82 28 #define ST33ZP24_LOCALITY_NOT_ACTIVATED 0x83 29 #define ST33ZP24_HASH_END_BEFORE_HASH_START 0x84 30 #define ST33ZP24_BAD_COMMAND_ORDER 0x85 31 #define ST33ZP24_INCORECT_RECEIVED_LENGTH 0x86 32 #define ST33ZP24_TPM_FIFO_OVERFLOW 0x89 33 #define ST33ZP24_UNEXPECTED_READ_FIFO 0x8A 34 #define ST33ZP24_UNEXPECTED_WRITE_FIFO 0x8B 35 #define ST33ZP24_CMDRDY_SET_WHEN_PROCESSING_HASH_END 0x90 36 #define ST33ZP24_DUMMY_BYTES 0x00 37 38 /* 39 * TPM command can be up to 2048 byte, A TPM response can be up to 40 * 1024 byte. 41 * Between command and response, there are latency byte (up to 15 42 * usually on st33zp24 2 are enough). 43 * 44 * Overall when sending a command and expecting an answer we need if 45 * worst case: 46 * 2048 (for the TPM command) + 1024 (for the TPM answer). We need 47 * some latency byte before the answer is available (max 15). 48 * We have 2048 + 1024 + 15. 49 */ 50 #define ST33ZP24_SPI_BUFFER_SIZE (ST33ZP24_BUFSIZE + (ST33ZP24_BUFSIZE / 2) +\ 51 MAX_SPI_LATENCY) 52 53 54 struct st33zp24_spi_phy { 55 struct spi_device *spi_device; 56 57 u8 tx_buf[ST33ZP24_SPI_BUFFER_SIZE]; 58 u8 rx_buf[ST33ZP24_SPI_BUFFER_SIZE]; 59 60 int latency; 61 }; 62 63 static int st33zp24_status_to_errno(u8 code) 64 { 65 switch (code) { 66 case ST33ZP24_OK: 67 return 0; 68 case ST33ZP24_UNDEFINED_ERR: 69 case ST33ZP24_BADLOCALITY: 70 case ST33ZP24_TISREGISTER_UNKNOWN: 71 case ST33ZP24_LOCALITY_NOT_ACTIVATED: 72 case ST33ZP24_HASH_END_BEFORE_HASH_START: 73 case ST33ZP24_BAD_COMMAND_ORDER: 74 case ST33ZP24_UNEXPECTED_READ_FIFO: 75 case ST33ZP24_UNEXPECTED_WRITE_FIFO: 76 case ST33ZP24_CMDRDY_SET_WHEN_PROCESSING_HASH_END: 77 return -EPROTO; 78 case ST33ZP24_INCORECT_RECEIVED_LENGTH: 79 case ST33ZP24_TPM_FIFO_OVERFLOW: 80 return -EMSGSIZE; 81 case ST33ZP24_DUMMY_BYTES: 82 return -ENOSYS; 83 } 84 return code; 85 } 86 87 /* 88 * st33zp24_spi_send 89 * Send byte to the TIS register according to the ST33ZP24 SPI protocol. 90 * @param: phy_id, the phy description 91 * @param: tpm_register, the tpm tis register where the data should be written 92 * @param: tpm_data, the tpm_data to write inside the tpm_register 93 * @param: tpm_size, The length of the data 94 * @return: should be zero if success else a negative error code. 95 */ 96 static int st33zp24_spi_send(void *phy_id, u8 tpm_register, u8 *tpm_data, 97 int tpm_size) 98 { 99 int total_length = 0, ret = 0; 100 struct st33zp24_spi_phy *phy = phy_id; 101 struct spi_device *dev = phy->spi_device; 102 struct spi_transfer spi_xfer = { 103 .tx_buf = phy->tx_buf, 104 .rx_buf = phy->rx_buf, 105 }; 106 107 /* Pre-Header */ 108 phy->tx_buf[total_length++] = TPM_WRITE_DIRECTION | LOCALITY0; 109 phy->tx_buf[total_length++] = tpm_register; 110 111 if (tpm_size > 0 && tpm_register == TPM_DATA_FIFO) { 112 phy->tx_buf[total_length++] = tpm_size >> 8; 113 phy->tx_buf[total_length++] = tpm_size; 114 } 115 116 memcpy(&phy->tx_buf[total_length], tpm_data, tpm_size); 117 total_length += tpm_size; 118 119 memset(&phy->tx_buf[total_length], TPM_DUMMY_BYTE, phy->latency); 120 121 spi_xfer.len = total_length + phy->latency; 122 123 ret = spi_sync_transfer(dev, &spi_xfer, 1); 124 if (ret == 0) 125 ret = phy->rx_buf[total_length + phy->latency - 1]; 126 127 return st33zp24_status_to_errno(ret); 128 } /* st33zp24_spi_send() */ 129 130 /* 131 * st33zp24_spi_read8_recv 132 * Recv byte from the TIS register according to the ST33ZP24 SPI protocol. 133 * @param: phy_id, the phy description 134 * @param: tpm_register, the tpm tis register where the data should be read 135 * @param: tpm_data, the TPM response 136 * @param: tpm_size, tpm TPM response size to read. 137 * @return: should be zero if success else a negative error code. 138 */ 139 static int st33zp24_spi_read8_reg(void *phy_id, u8 tpm_register, u8 *tpm_data, 140 int tpm_size) 141 { 142 int total_length = 0, ret; 143 struct st33zp24_spi_phy *phy = phy_id; 144 struct spi_device *dev = phy->spi_device; 145 struct spi_transfer spi_xfer = { 146 .tx_buf = phy->tx_buf, 147 .rx_buf = phy->rx_buf, 148 }; 149 150 /* Pre-Header */ 151 phy->tx_buf[total_length++] = LOCALITY0; 152 phy->tx_buf[total_length++] = tpm_register; 153 154 memset(&phy->tx_buf[total_length], TPM_DUMMY_BYTE, 155 phy->latency + tpm_size); 156 157 spi_xfer.len = total_length + phy->latency + tpm_size; 158 159 /* header + status byte + size of the data + status byte */ 160 ret = spi_sync_transfer(dev, &spi_xfer, 1); 161 if (tpm_size > 0 && ret == 0) { 162 ret = phy->rx_buf[total_length + phy->latency - 1]; 163 164 memcpy(tpm_data, phy->rx_buf + total_length + phy->latency, 165 tpm_size); 166 } 167 168 return ret; 169 } /* st33zp24_spi_read8_reg() */ 170 171 /* 172 * st33zp24_spi_recv 173 * Recv byte from the TIS register according to the ST33ZP24 SPI protocol. 174 * @param: phy_id, the phy description 175 * @param: tpm_register, the tpm tis register where the data should be read 176 * @param: tpm_data, the TPM response 177 * @param: tpm_size, tpm TPM response size to read. 178 * @return: number of byte read successfully: should be one if success. 179 */ 180 static int st33zp24_spi_recv(void *phy_id, u8 tpm_register, u8 *tpm_data, 181 int tpm_size) 182 { 183 int ret; 184 185 ret = st33zp24_spi_read8_reg(phy_id, tpm_register, tpm_data, tpm_size); 186 if (!st33zp24_status_to_errno(ret)) 187 return tpm_size; 188 return ret; 189 } /* st33zp24_spi_recv() */ 190 191 static int st33zp24_spi_evaluate_latency(void *phy_id) 192 { 193 struct st33zp24_spi_phy *phy = phy_id; 194 int latency = 1, status = 0; 195 u8 data = 0; 196 197 while (!status && latency < MAX_SPI_LATENCY) { 198 phy->latency = latency; 199 status = st33zp24_spi_read8_reg(phy_id, TPM_INTF_CAPABILITY, 200 &data, 1); 201 latency++; 202 } 203 if (status < 0) 204 return status; 205 if (latency == MAX_SPI_LATENCY) 206 return -ENODEV; 207 208 return latency - 1; 209 } /* evaluate_latency() */ 210 211 static const struct st33zp24_phy_ops spi_phy_ops = { 212 .send = st33zp24_spi_send, 213 .recv = st33zp24_spi_recv, 214 }; 215 216 /* 217 * st33zp24_spi_probe initialize the TPM device 218 * @param: dev, the spi_device description (TPM SPI description). 219 * @return: 0 in case of success. 220 * or a negative value describing the error. 221 */ 222 static int st33zp24_spi_probe(struct spi_device *dev) 223 { 224 struct st33zp24_spi_phy *phy; 225 226 phy = devm_kzalloc(&dev->dev, sizeof(struct st33zp24_spi_phy), 227 GFP_KERNEL); 228 if (!phy) 229 return -ENOMEM; 230 231 phy->spi_device = dev; 232 233 phy->latency = st33zp24_spi_evaluate_latency(phy); 234 if (phy->latency <= 0) 235 return -ENODEV; 236 237 return st33zp24_probe(phy, &spi_phy_ops, &dev->dev, dev->irq); 238 } 239 240 /* 241 * st33zp24_spi_remove remove the TPM device 242 * @param: client, the spi_device description (TPM SPI description). 243 * @return: 0 in case of success. 244 */ 245 static void st33zp24_spi_remove(struct spi_device *dev) 246 { 247 struct tpm_chip *chip = spi_get_drvdata(dev); 248 249 st33zp24_remove(chip); 250 } 251 252 static const struct spi_device_id st33zp24_spi_id[] = { 253 {TPM_ST33_SPI, 0}, 254 {} 255 }; 256 MODULE_DEVICE_TABLE(spi, st33zp24_spi_id); 257 258 static const struct of_device_id of_st33zp24_spi_match[] __maybe_unused = { 259 { .compatible = "st,st33zp24-spi", }, 260 {} 261 }; 262 MODULE_DEVICE_TABLE(of, of_st33zp24_spi_match); 263 264 static const struct acpi_device_id st33zp24_spi_acpi_match[] __maybe_unused = { 265 {"SMO3324"}, 266 {} 267 }; 268 MODULE_DEVICE_TABLE(acpi, st33zp24_spi_acpi_match); 269 270 static SIMPLE_DEV_PM_OPS(st33zp24_spi_ops, st33zp24_pm_suspend, 271 st33zp24_pm_resume); 272 273 static struct spi_driver st33zp24_spi_driver = { 274 .driver = { 275 .name = "st33zp24-spi", 276 .pm = &st33zp24_spi_ops, 277 .of_match_table = of_match_ptr(of_st33zp24_spi_match), 278 .acpi_match_table = ACPI_PTR(st33zp24_spi_acpi_match), 279 }, 280 .probe = st33zp24_spi_probe, 281 .remove = st33zp24_spi_remove, 282 .id_table = st33zp24_spi_id, 283 }; 284 285 module_spi_driver(st33zp24_spi_driver); 286 287 MODULE_AUTHOR("TPM support <TPMsupport@list.st.com>"); 288 MODULE_DESCRIPTION("STM TPM 1.2 SPI ST33 Driver"); 289 MODULE_VERSION("1.3.0"); 290 MODULE_LICENSE("GPL"); 291