spi.c (11621B)
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/gpio.h> 10#include <linux/gpio/consumer.h> 11#include <linux/of_irq.h> 12#include <linux/of_gpio.h> 13#include <linux/acpi.h> 14#include <linux/tpm.h> 15#include <linux/platform_data/st33zp24.h> 16 17#include "../tpm.h" 18#include "st33zp24.h" 19 20#define TPM_DATA_FIFO 0x24 21#define TPM_INTF_CAPABILITY 0x14 22 23#define TPM_DUMMY_BYTE 0x00 24 25#define MAX_SPI_LATENCY 15 26#define LOCALITY0 0 27 28#define ST33ZP24_OK 0x5A 29#define ST33ZP24_UNDEFINED_ERR 0x80 30#define ST33ZP24_BADLOCALITY 0x81 31#define ST33ZP24_TISREGISTER_UNKNOWN 0x82 32#define ST33ZP24_LOCALITY_NOT_ACTIVATED 0x83 33#define ST33ZP24_HASH_END_BEFORE_HASH_START 0x84 34#define ST33ZP24_BAD_COMMAND_ORDER 0x85 35#define ST33ZP24_INCORECT_RECEIVED_LENGTH 0x86 36#define ST33ZP24_TPM_FIFO_OVERFLOW 0x89 37#define ST33ZP24_UNEXPECTED_READ_FIFO 0x8A 38#define ST33ZP24_UNEXPECTED_WRITE_FIFO 0x8B 39#define ST33ZP24_CMDRDY_SET_WHEN_PROCESSING_HASH_END 0x90 40#define ST33ZP24_DUMMY_BYTES 0x00 41 42/* 43 * TPM command can be up to 2048 byte, A TPM response can be up to 44 * 1024 byte. 45 * Between command and response, there are latency byte (up to 15 46 * usually on st33zp24 2 are enough). 47 * 48 * Overall when sending a command and expecting an answer we need if 49 * worst case: 50 * 2048 (for the TPM command) + 1024 (for the TPM answer). We need 51 * some latency byte before the answer is available (max 15). 52 * We have 2048 + 1024 + 15. 53 */ 54#define ST33ZP24_SPI_BUFFER_SIZE (ST33ZP24_BUFSIZE + (ST33ZP24_BUFSIZE / 2) +\ 55 MAX_SPI_LATENCY) 56 57 58struct st33zp24_spi_phy { 59 struct spi_device *spi_device; 60 61 u8 tx_buf[ST33ZP24_SPI_BUFFER_SIZE]; 62 u8 rx_buf[ST33ZP24_SPI_BUFFER_SIZE]; 63 64 int io_lpcpd; 65 int latency; 66}; 67 68static int st33zp24_status_to_errno(u8 code) 69{ 70 switch (code) { 71 case ST33ZP24_OK: 72 return 0; 73 case ST33ZP24_UNDEFINED_ERR: 74 case ST33ZP24_BADLOCALITY: 75 case ST33ZP24_TISREGISTER_UNKNOWN: 76 case ST33ZP24_LOCALITY_NOT_ACTIVATED: 77 case ST33ZP24_HASH_END_BEFORE_HASH_START: 78 case ST33ZP24_BAD_COMMAND_ORDER: 79 case ST33ZP24_UNEXPECTED_READ_FIFO: 80 case ST33ZP24_UNEXPECTED_WRITE_FIFO: 81 case ST33ZP24_CMDRDY_SET_WHEN_PROCESSING_HASH_END: 82 return -EPROTO; 83 case ST33ZP24_INCORECT_RECEIVED_LENGTH: 84 case ST33ZP24_TPM_FIFO_OVERFLOW: 85 return -EMSGSIZE; 86 case ST33ZP24_DUMMY_BYTES: 87 return -ENOSYS; 88 } 89 return code; 90} 91 92/* 93 * st33zp24_spi_send 94 * Send byte to the TIS register according to the ST33ZP24 SPI protocol. 95 * @param: phy_id, the phy description 96 * @param: tpm_register, the tpm tis register where the data should be written 97 * @param: tpm_data, the tpm_data to write inside the tpm_register 98 * @param: tpm_size, The length of the data 99 * @return: should be zero if success else a negative error code. 100 */ 101static int st33zp24_spi_send(void *phy_id, u8 tpm_register, u8 *tpm_data, 102 int tpm_size) 103{ 104 int total_length = 0, ret = 0; 105 struct st33zp24_spi_phy *phy = phy_id; 106 struct spi_device *dev = phy->spi_device; 107 struct spi_transfer spi_xfer = { 108 .tx_buf = phy->tx_buf, 109 .rx_buf = phy->rx_buf, 110 }; 111 112 /* Pre-Header */ 113 phy->tx_buf[total_length++] = TPM_WRITE_DIRECTION | LOCALITY0; 114 phy->tx_buf[total_length++] = tpm_register; 115 116 if (tpm_size > 0 && tpm_register == TPM_DATA_FIFO) { 117 phy->tx_buf[total_length++] = tpm_size >> 8; 118 phy->tx_buf[total_length++] = tpm_size; 119 } 120 121 memcpy(&phy->tx_buf[total_length], tpm_data, tpm_size); 122 total_length += tpm_size; 123 124 memset(&phy->tx_buf[total_length], TPM_DUMMY_BYTE, phy->latency); 125 126 spi_xfer.len = total_length + phy->latency; 127 128 ret = spi_sync_transfer(dev, &spi_xfer, 1); 129 if (ret == 0) 130 ret = phy->rx_buf[total_length + phy->latency - 1]; 131 132 return st33zp24_status_to_errno(ret); 133} /* st33zp24_spi_send() */ 134 135/* 136 * st33zp24_spi_read8_recv 137 * Recv byte from the TIS register according to the ST33ZP24 SPI protocol. 138 * @param: phy_id, the phy description 139 * @param: tpm_register, the tpm tis register where the data should be read 140 * @param: tpm_data, the TPM response 141 * @param: tpm_size, tpm TPM response size to read. 142 * @return: should be zero if success else a negative error code. 143 */ 144static int st33zp24_spi_read8_reg(void *phy_id, u8 tpm_register, u8 *tpm_data, 145 int tpm_size) 146{ 147 int total_length = 0, ret; 148 struct st33zp24_spi_phy *phy = phy_id; 149 struct spi_device *dev = phy->spi_device; 150 struct spi_transfer spi_xfer = { 151 .tx_buf = phy->tx_buf, 152 .rx_buf = phy->rx_buf, 153 }; 154 155 /* Pre-Header */ 156 phy->tx_buf[total_length++] = LOCALITY0; 157 phy->tx_buf[total_length++] = tpm_register; 158 159 memset(&phy->tx_buf[total_length], TPM_DUMMY_BYTE, 160 phy->latency + tpm_size); 161 162 spi_xfer.len = total_length + phy->latency + tpm_size; 163 164 /* header + status byte + size of the data + status byte */ 165 ret = spi_sync_transfer(dev, &spi_xfer, 1); 166 if (tpm_size > 0 && ret == 0) { 167 ret = phy->rx_buf[total_length + phy->latency - 1]; 168 169 memcpy(tpm_data, phy->rx_buf + total_length + phy->latency, 170 tpm_size); 171 } 172 173 return ret; 174} /* st33zp24_spi_read8_reg() */ 175 176/* 177 * st33zp24_spi_recv 178 * Recv byte from the TIS register according to the ST33ZP24 SPI protocol. 179 * @param: phy_id, the phy description 180 * @param: tpm_register, the tpm tis register where the data should be read 181 * @param: tpm_data, the TPM response 182 * @param: tpm_size, tpm TPM response size to read. 183 * @return: number of byte read successfully: should be one if success. 184 */ 185static int st33zp24_spi_recv(void *phy_id, u8 tpm_register, u8 *tpm_data, 186 int tpm_size) 187{ 188 int ret; 189 190 ret = st33zp24_spi_read8_reg(phy_id, tpm_register, tpm_data, tpm_size); 191 if (!st33zp24_status_to_errno(ret)) 192 return tpm_size; 193 return ret; 194} /* st33zp24_spi_recv() */ 195 196static int st33zp24_spi_evaluate_latency(void *phy_id) 197{ 198 struct st33zp24_spi_phy *phy = phy_id; 199 int latency = 1, status = 0; 200 u8 data = 0; 201 202 while (!status && latency < MAX_SPI_LATENCY) { 203 phy->latency = latency; 204 status = st33zp24_spi_read8_reg(phy_id, TPM_INTF_CAPABILITY, 205 &data, 1); 206 latency++; 207 } 208 if (status < 0) 209 return status; 210 if (latency == MAX_SPI_LATENCY) 211 return -ENODEV; 212 213 return latency - 1; 214} /* evaluate_latency() */ 215 216static const struct st33zp24_phy_ops spi_phy_ops = { 217 .send = st33zp24_spi_send, 218 .recv = st33zp24_spi_recv, 219}; 220 221static const struct acpi_gpio_params lpcpd_gpios = { 1, 0, false }; 222 223static const struct acpi_gpio_mapping acpi_st33zp24_gpios[] = { 224 { "lpcpd-gpios", &lpcpd_gpios, 1 }, 225 {}, 226}; 227 228static int st33zp24_spi_acpi_request_resources(struct spi_device *spi_dev) 229{ 230 struct tpm_chip *chip = spi_get_drvdata(spi_dev); 231 struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev); 232 struct st33zp24_spi_phy *phy = tpm_dev->phy_id; 233 struct gpio_desc *gpiod_lpcpd; 234 struct device *dev = &spi_dev->dev; 235 int ret; 236 237 ret = devm_acpi_dev_add_driver_gpios(dev, acpi_st33zp24_gpios); 238 if (ret) 239 return ret; 240 241 /* Get LPCPD GPIO from ACPI */ 242 gpiod_lpcpd = devm_gpiod_get(dev, "lpcpd", GPIOD_OUT_HIGH); 243 if (IS_ERR(gpiod_lpcpd)) { 244 dev_err(dev, "Failed to retrieve lpcpd-gpios from acpi.\n"); 245 phy->io_lpcpd = -1; 246 /* 247 * lpcpd pin is not specified. This is not an issue as 248 * power management can be also managed by TPM specific 249 * commands. So leave with a success status code. 250 */ 251 return 0; 252 } 253 254 phy->io_lpcpd = desc_to_gpio(gpiod_lpcpd); 255 256 return 0; 257} 258 259static int st33zp24_spi_of_request_resources(struct spi_device *spi_dev) 260{ 261 struct tpm_chip *chip = spi_get_drvdata(spi_dev); 262 struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev); 263 struct st33zp24_spi_phy *phy = tpm_dev->phy_id; 264 struct device_node *pp; 265 int gpio; 266 int ret; 267 268 pp = spi_dev->dev.of_node; 269 if (!pp) { 270 dev_err(&spi_dev->dev, "No platform data\n"); 271 return -ENODEV; 272 } 273 274 /* Get GPIO from device tree */ 275 gpio = of_get_named_gpio(pp, "lpcpd-gpios", 0); 276 if (gpio < 0) { 277 dev_err(&spi_dev->dev, 278 "Failed to retrieve lpcpd-gpios from dts.\n"); 279 phy->io_lpcpd = -1; 280 /* 281 * lpcpd pin is not specified. This is not an issue as 282 * power management can be also managed by TPM specific 283 * commands. So leave with a success status code. 284 */ 285 return 0; 286 } 287 /* GPIO request and configuration */ 288 ret = devm_gpio_request_one(&spi_dev->dev, gpio, 289 GPIOF_OUT_INIT_HIGH, "TPM IO LPCPD"); 290 if (ret) { 291 dev_err(&spi_dev->dev, "Failed to request lpcpd pin\n"); 292 return -ENODEV; 293 } 294 phy->io_lpcpd = gpio; 295 296 return 0; 297} 298 299static int st33zp24_spi_request_resources(struct spi_device *dev) 300{ 301 struct tpm_chip *chip = spi_get_drvdata(dev); 302 struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev); 303 struct st33zp24_spi_phy *phy = tpm_dev->phy_id; 304 struct st33zp24_platform_data *pdata; 305 int ret; 306 307 pdata = dev->dev.platform_data; 308 if (!pdata) { 309 dev_err(&dev->dev, "No platform data\n"); 310 return -ENODEV; 311 } 312 313 /* store for late use */ 314 phy->io_lpcpd = pdata->io_lpcpd; 315 316 if (gpio_is_valid(pdata->io_lpcpd)) { 317 ret = devm_gpio_request_one(&dev->dev, 318 pdata->io_lpcpd, GPIOF_OUT_INIT_HIGH, 319 "TPM IO_LPCPD"); 320 if (ret) { 321 dev_err(&dev->dev, "%s : reset gpio_request failed\n", 322 __FILE__); 323 return ret; 324 } 325 } 326 327 return 0; 328} 329 330/* 331 * st33zp24_spi_probe initialize the TPM device 332 * @param: dev, the spi_device description (TPM SPI description). 333 * @return: 0 in case of success. 334 * or a negative value describing the error. 335 */ 336static int st33zp24_spi_probe(struct spi_device *dev) 337{ 338 int ret; 339 struct st33zp24_platform_data *pdata; 340 struct st33zp24_spi_phy *phy; 341 342 /* Check SPI platform functionnalities */ 343 if (!dev) { 344 pr_info("%s: dev is NULL. Device is not accessible.\n", 345 __func__); 346 return -ENODEV; 347 } 348 349 phy = devm_kzalloc(&dev->dev, sizeof(struct st33zp24_spi_phy), 350 GFP_KERNEL); 351 if (!phy) 352 return -ENOMEM; 353 354 phy->spi_device = dev; 355 356 pdata = dev->dev.platform_data; 357 if (!pdata && dev->dev.of_node) { 358 ret = st33zp24_spi_of_request_resources(dev); 359 if (ret) 360 return ret; 361 } else if (pdata) { 362 ret = st33zp24_spi_request_resources(dev); 363 if (ret) 364 return ret; 365 } else if (ACPI_HANDLE(&dev->dev)) { 366 ret = st33zp24_spi_acpi_request_resources(dev); 367 if (ret) 368 return ret; 369 } 370 371 phy->latency = st33zp24_spi_evaluate_latency(phy); 372 if (phy->latency <= 0) 373 return -ENODEV; 374 375 return st33zp24_probe(phy, &spi_phy_ops, &dev->dev, dev->irq, 376 phy->io_lpcpd); 377} 378 379/* 380 * st33zp24_spi_remove remove the TPM device 381 * @param: client, the spi_device description (TPM SPI description). 382 * @return: 0 in case of success. 383 */ 384static void st33zp24_spi_remove(struct spi_device *dev) 385{ 386 struct tpm_chip *chip = spi_get_drvdata(dev); 387 388 st33zp24_remove(chip); 389} 390 391static const struct spi_device_id st33zp24_spi_id[] = { 392 {TPM_ST33_SPI, 0}, 393 {} 394}; 395MODULE_DEVICE_TABLE(spi, st33zp24_spi_id); 396 397static const struct of_device_id of_st33zp24_spi_match[] = { 398 { .compatible = "st,st33zp24-spi", }, 399 {} 400}; 401MODULE_DEVICE_TABLE(of, of_st33zp24_spi_match); 402 403static const struct acpi_device_id st33zp24_spi_acpi_match[] = { 404 {"SMO3324"}, 405 {} 406}; 407MODULE_DEVICE_TABLE(acpi, st33zp24_spi_acpi_match); 408 409static SIMPLE_DEV_PM_OPS(st33zp24_spi_ops, st33zp24_pm_suspend, 410 st33zp24_pm_resume); 411 412static struct spi_driver st33zp24_spi_driver = { 413 .driver = { 414 .name = TPM_ST33_SPI, 415 .pm = &st33zp24_spi_ops, 416 .of_match_table = of_match_ptr(of_st33zp24_spi_match), 417 .acpi_match_table = ACPI_PTR(st33zp24_spi_acpi_match), 418 }, 419 .probe = st33zp24_spi_probe, 420 .remove = st33zp24_spi_remove, 421 .id_table = st33zp24_spi_id, 422}; 423 424module_spi_driver(st33zp24_spi_driver); 425 426MODULE_AUTHOR("TPM support (TPMsupport@list.st.com)"); 427MODULE_DESCRIPTION("STM TPM 1.2 SPI ST33 Driver"); 428MODULE_VERSION("1.3.0"); 429MODULE_LICENSE("GPL");