1aad628c1SPeter Huewe /* 2aad628c1SPeter Huewe * Copyright (C) 2012 Infineon Technologies 3aad628c1SPeter Huewe * 4aad628c1SPeter Huewe * Authors: 5aad628c1SPeter Huewe * Peter Huewe <peter.huewe@infineon.com> 6aad628c1SPeter Huewe * 7aad628c1SPeter Huewe * Device driver for TCG/TCPA TPM (trusted platform module). 8aad628c1SPeter Huewe * Specifications at www.trustedcomputinggroup.org 9aad628c1SPeter Huewe * 10aad628c1SPeter Huewe * This device driver implements the TPM interface as defined in 11aad628c1SPeter Huewe * the TCG TPM Interface Spec version 1.2, revision 1.0 and the 12aad628c1SPeter Huewe * Infineon I2C Protocol Stack Specification v0.20. 13aad628c1SPeter Huewe * 14aad628c1SPeter Huewe * It is based on the original tpm_tis device driver from Leendert van 15aad628c1SPeter Huewe * Dorn and Kyleen Hall. 16aad628c1SPeter Huewe * 17aad628c1SPeter Huewe * This program is free software; you can redistribute it and/or 18aad628c1SPeter Huewe * modify it under the terms of the GNU General Public License as 19aad628c1SPeter Huewe * published by the Free Software Foundation, version 2 of the 20aad628c1SPeter Huewe * License. 21aad628c1SPeter Huewe * 22aad628c1SPeter Huewe * 23aad628c1SPeter Huewe */ 24aad628c1SPeter Huewe #include <linux/init.h> 25aad628c1SPeter Huewe #include <linux/i2c.h> 26aad628c1SPeter Huewe #include <linux/module.h> 27aad628c1SPeter Huewe #include <linux/moduleparam.h> 28aad628c1SPeter Huewe #include <linux/wait.h> 29aad628c1SPeter Huewe #include "tpm.h" 30aad628c1SPeter Huewe 31aad628c1SPeter Huewe /* max. buffer size supported by our TPM */ 32aad628c1SPeter Huewe #define TPM_BUFSIZE 1260 33aad628c1SPeter Huewe 34aad628c1SPeter Huewe /* max. number of iterations after I2C NAK */ 35aad628c1SPeter Huewe #define MAX_COUNT 3 36aad628c1SPeter Huewe 37aad628c1SPeter Huewe #define SLEEP_DURATION_LOW 55 38aad628c1SPeter Huewe #define SLEEP_DURATION_HI 65 39aad628c1SPeter Huewe 40aad628c1SPeter Huewe /* max. number of iterations after I2C NAK for 'long' commands 41aad628c1SPeter Huewe * we need this especially for sending TPM_READY, since the cleanup after the 42aad628c1SPeter Huewe * transtion to the ready state may take some time, but it is unpredictable 43aad628c1SPeter Huewe * how long it will take. 44aad628c1SPeter Huewe */ 45aad628c1SPeter Huewe #define MAX_COUNT_LONG 50 46aad628c1SPeter Huewe 47aad628c1SPeter Huewe #define SLEEP_DURATION_LONG_LOW 200 48aad628c1SPeter Huewe #define SLEEP_DURATION_LONG_HI 220 49aad628c1SPeter Huewe 50aad628c1SPeter Huewe /* After sending TPM_READY to 'reset' the TPM we have to sleep even longer */ 51aad628c1SPeter Huewe #define SLEEP_DURATION_RESET_LOW 2400 52aad628c1SPeter Huewe #define SLEEP_DURATION_RESET_HI 2600 53aad628c1SPeter Huewe 54aad628c1SPeter Huewe /* we want to use usleep_range instead of msleep for the 5ms TPM_TIMEOUT */ 55aad628c1SPeter Huewe #define TPM_TIMEOUT_US_LOW (TPM_TIMEOUT * 1000) 56aad628c1SPeter Huewe #define TPM_TIMEOUT_US_HI (TPM_TIMEOUT_US_LOW + 2000) 57aad628c1SPeter Huewe 58aad628c1SPeter Huewe /* expected value for DIDVID register */ 59aad628c1SPeter Huewe #define TPM_TIS_I2C_DID_VID 0x000b15d1L 60aad628c1SPeter Huewe 61aad628c1SPeter Huewe /* Structure to store I2C TPM specific stuff */ 62aad628c1SPeter Huewe struct tpm_inf_dev { 63aad628c1SPeter Huewe struct i2c_client *client; 64aad628c1SPeter Huewe u8 buf[TPM_BUFSIZE + sizeof(u8)]; /* max. buffer size + addr */ 65aad628c1SPeter Huewe struct tpm_chip *chip; 66aad628c1SPeter Huewe }; 67aad628c1SPeter Huewe 68aad628c1SPeter Huewe static struct tpm_inf_dev tpm_dev; 69aad628c1SPeter Huewe static struct i2c_driver tpm_tis_i2c_driver; 70aad628c1SPeter Huewe 71aad628c1SPeter Huewe /* 72aad628c1SPeter Huewe * iic_tpm_read() - read from TPM register 73aad628c1SPeter Huewe * @addr: register address to read from 74aad628c1SPeter Huewe * @buffer: provided by caller 75aad628c1SPeter Huewe * @len: number of bytes to read 76aad628c1SPeter Huewe * 77aad628c1SPeter Huewe * Read len bytes from TPM register and put them into 78aad628c1SPeter Huewe * buffer (little-endian format, i.e. first byte is put into buffer[0]). 79aad628c1SPeter Huewe * 80aad628c1SPeter Huewe * NOTE: TPM is big-endian for multi-byte values. Multi-byte 81aad628c1SPeter Huewe * values have to be swapped. 82aad628c1SPeter Huewe * 83aad628c1SPeter Huewe * NOTE: We can't unfortunately use the combined read/write functions 84aad628c1SPeter Huewe * provided by the i2c core as the TPM currently does not support the 85aad628c1SPeter Huewe * repeated start condition and due to it's special requirements. 86aad628c1SPeter Huewe * The i2c_smbus* functions do not work for this chip. 87aad628c1SPeter Huewe * 88aad628c1SPeter Huewe * Return -EIO on error, 0 on success. 89aad628c1SPeter Huewe */ 90aad628c1SPeter Huewe static int iic_tpm_read(u8 addr, u8 *buffer, size_t len) 91aad628c1SPeter Huewe { 92aad628c1SPeter Huewe 93aad628c1SPeter Huewe struct i2c_msg msg1 = { tpm_dev.client->addr, 0, 1, &addr }; 94aad628c1SPeter Huewe struct i2c_msg msg2 = { tpm_dev.client->addr, I2C_M_RD, len, buffer }; 95aad628c1SPeter Huewe 96aad628c1SPeter Huewe int rc; 97aad628c1SPeter Huewe int count; 98aad628c1SPeter Huewe 99aad628c1SPeter Huewe /* Lock the adapter for the duration of the whole sequence. */ 100aad628c1SPeter Huewe if (!tpm_dev.client->adapter->algo->master_xfer) 101aad628c1SPeter Huewe return -EOPNOTSUPP; 102aad628c1SPeter Huewe i2c_lock_adapter(tpm_dev.client->adapter); 103aad628c1SPeter Huewe 104aad628c1SPeter Huewe for (count = 0; count < MAX_COUNT; count++) { 105aad628c1SPeter Huewe rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1); 106aad628c1SPeter Huewe if (rc > 0) 107aad628c1SPeter Huewe break; /* break here to skip sleep */ 108aad628c1SPeter Huewe 109aad628c1SPeter Huewe usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI); 110aad628c1SPeter Huewe } 111aad628c1SPeter Huewe 112aad628c1SPeter Huewe if (rc <= 0) 113aad628c1SPeter Huewe goto out; 114aad628c1SPeter Huewe 115aad628c1SPeter Huewe /* After the TPM has successfully received the register address it needs 116aad628c1SPeter Huewe * some time, thus we're sleeping here again, before retrieving the data 117aad628c1SPeter Huewe */ 118aad628c1SPeter Huewe for (count = 0; count < MAX_COUNT; count++) { 119aad628c1SPeter Huewe usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI); 120aad628c1SPeter Huewe rc = __i2c_transfer(tpm_dev.client->adapter, &msg2, 1); 121aad628c1SPeter Huewe if (rc > 0) 122aad628c1SPeter Huewe break; 123aad628c1SPeter Huewe 124aad628c1SPeter Huewe } 125aad628c1SPeter Huewe 126aad628c1SPeter Huewe out: 127aad628c1SPeter Huewe i2c_unlock_adapter(tpm_dev.client->adapter); 128aad628c1SPeter Huewe if (rc <= 0) 129aad628c1SPeter Huewe return -EIO; 130aad628c1SPeter Huewe 131aad628c1SPeter Huewe return 0; 132aad628c1SPeter Huewe } 133aad628c1SPeter Huewe 134aad628c1SPeter Huewe static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len, 135aad628c1SPeter Huewe unsigned int sleep_low, 136aad628c1SPeter Huewe unsigned int sleep_hi, u8 max_count) 137aad628c1SPeter Huewe { 138aad628c1SPeter Huewe int rc = -EIO; 139aad628c1SPeter Huewe int count; 140aad628c1SPeter Huewe 141aad628c1SPeter Huewe struct i2c_msg msg1 = { tpm_dev.client->addr, 0, len + 1, tpm_dev.buf }; 142aad628c1SPeter Huewe 143aad628c1SPeter Huewe if (len > TPM_BUFSIZE) 144aad628c1SPeter Huewe return -EINVAL; 145aad628c1SPeter Huewe 146aad628c1SPeter Huewe if (!tpm_dev.client->adapter->algo->master_xfer) 147aad628c1SPeter Huewe return -EOPNOTSUPP; 148aad628c1SPeter Huewe i2c_lock_adapter(tpm_dev.client->adapter); 149aad628c1SPeter Huewe 150aad628c1SPeter Huewe /* prepend the 'register address' to the buffer */ 151aad628c1SPeter Huewe tpm_dev.buf[0] = addr; 152aad628c1SPeter Huewe memcpy(&(tpm_dev.buf[1]), buffer, len); 153aad628c1SPeter Huewe 154aad628c1SPeter Huewe /* 155aad628c1SPeter Huewe * NOTE: We have to use these special mechanisms here and unfortunately 156aad628c1SPeter Huewe * cannot rely on the standard behavior of i2c_transfer. 157aad628c1SPeter Huewe */ 158aad628c1SPeter Huewe for (count = 0; count < max_count; count++) { 159aad628c1SPeter Huewe rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1); 160aad628c1SPeter Huewe if (rc > 0) 161aad628c1SPeter Huewe break; 162aad628c1SPeter Huewe 163aad628c1SPeter Huewe usleep_range(sleep_low, sleep_hi); 164aad628c1SPeter Huewe } 165aad628c1SPeter Huewe 166aad628c1SPeter Huewe i2c_unlock_adapter(tpm_dev.client->adapter); 167aad628c1SPeter Huewe if (rc <= 0) 168aad628c1SPeter Huewe return -EIO; 169aad628c1SPeter Huewe 170aad628c1SPeter Huewe return 0; 171aad628c1SPeter Huewe } 172aad628c1SPeter Huewe 173aad628c1SPeter Huewe /* 174aad628c1SPeter Huewe * iic_tpm_write() - write to TPM register 175aad628c1SPeter Huewe * @addr: register address to write to 176aad628c1SPeter Huewe * @buffer: containing data to be written 177aad628c1SPeter Huewe * @len: number of bytes to write 178aad628c1SPeter Huewe * 179aad628c1SPeter Huewe * Write len bytes from provided buffer to TPM register (little 180aad628c1SPeter Huewe * endian format, i.e. buffer[0] is written as first byte). 181aad628c1SPeter Huewe * 182aad628c1SPeter Huewe * NOTE: TPM is big-endian for multi-byte values. Multi-byte 183aad628c1SPeter Huewe * values have to be swapped. 184aad628c1SPeter Huewe * 185aad628c1SPeter Huewe * NOTE: use this function instead of the iic_tpm_write_generic function. 186aad628c1SPeter Huewe * 187aad628c1SPeter Huewe * Return -EIO on error, 0 on success 188aad628c1SPeter Huewe */ 189aad628c1SPeter Huewe static int iic_tpm_write(u8 addr, u8 *buffer, size_t len) 190aad628c1SPeter Huewe { 191aad628c1SPeter Huewe return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION_LOW, 192aad628c1SPeter Huewe SLEEP_DURATION_HI, MAX_COUNT); 193aad628c1SPeter Huewe } 194aad628c1SPeter Huewe 195aad628c1SPeter Huewe /* 196aad628c1SPeter Huewe * This function is needed especially for the cleanup situation after 197aad628c1SPeter Huewe * sending TPM_READY 198aad628c1SPeter Huewe * */ 199aad628c1SPeter Huewe static int iic_tpm_write_long(u8 addr, u8 *buffer, size_t len) 200aad628c1SPeter Huewe { 201aad628c1SPeter Huewe return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION_LONG_LOW, 202aad628c1SPeter Huewe SLEEP_DURATION_LONG_HI, MAX_COUNT_LONG); 203aad628c1SPeter Huewe } 204aad628c1SPeter Huewe 205aad628c1SPeter Huewe enum tis_access { 206aad628c1SPeter Huewe TPM_ACCESS_VALID = 0x80, 207aad628c1SPeter Huewe TPM_ACCESS_ACTIVE_LOCALITY = 0x20, 208aad628c1SPeter Huewe TPM_ACCESS_REQUEST_PENDING = 0x04, 209aad628c1SPeter Huewe TPM_ACCESS_REQUEST_USE = 0x02, 210aad628c1SPeter Huewe }; 211aad628c1SPeter Huewe 212aad628c1SPeter Huewe enum tis_status { 213aad628c1SPeter Huewe TPM_STS_VALID = 0x80, 214aad628c1SPeter Huewe TPM_STS_COMMAND_READY = 0x40, 215aad628c1SPeter Huewe TPM_STS_GO = 0x20, 216aad628c1SPeter Huewe TPM_STS_DATA_AVAIL = 0x10, 217aad628c1SPeter Huewe TPM_STS_DATA_EXPECT = 0x08, 218aad628c1SPeter Huewe }; 219aad628c1SPeter Huewe 220aad628c1SPeter Huewe enum tis_defaults { 221aad628c1SPeter Huewe TIS_SHORT_TIMEOUT = 750, /* ms */ 222aad628c1SPeter Huewe TIS_LONG_TIMEOUT = 2000, /* 2 sec */ 223aad628c1SPeter Huewe }; 224aad628c1SPeter Huewe 225aad628c1SPeter Huewe #define TPM_ACCESS(l) (0x0000 | ((l) << 4)) 226aad628c1SPeter Huewe #define TPM_STS(l) (0x0001 | ((l) << 4)) 227aad628c1SPeter Huewe #define TPM_DATA_FIFO(l) (0x0005 | ((l) << 4)) 228aad628c1SPeter Huewe #define TPM_DID_VID(l) (0x0006 | ((l) << 4)) 229aad628c1SPeter Huewe 230aad628c1SPeter Huewe static int check_locality(struct tpm_chip *chip, int loc) 231aad628c1SPeter Huewe { 232aad628c1SPeter Huewe u8 buf; 233aad628c1SPeter Huewe int rc; 234aad628c1SPeter Huewe 235aad628c1SPeter Huewe rc = iic_tpm_read(TPM_ACCESS(loc), &buf, 1); 236aad628c1SPeter Huewe if (rc < 0) 237aad628c1SPeter Huewe return rc; 238aad628c1SPeter Huewe 239aad628c1SPeter Huewe if ((buf & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) == 240aad628c1SPeter Huewe (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) { 241aad628c1SPeter Huewe chip->vendor.locality = loc; 242aad628c1SPeter Huewe return loc; 243aad628c1SPeter Huewe } 244aad628c1SPeter Huewe 245aad628c1SPeter Huewe return -EIO; 246aad628c1SPeter Huewe } 247aad628c1SPeter Huewe 248aad628c1SPeter Huewe /* implementation similar to tpm_tis */ 249aad628c1SPeter Huewe static void release_locality(struct tpm_chip *chip, int loc, int force) 250aad628c1SPeter Huewe { 251aad628c1SPeter Huewe u8 buf; 252aad628c1SPeter Huewe if (iic_tpm_read(TPM_ACCESS(loc), &buf, 1) < 0) 253aad628c1SPeter Huewe return; 254aad628c1SPeter Huewe 255aad628c1SPeter Huewe if (force || (buf & (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) == 256aad628c1SPeter Huewe (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) { 257aad628c1SPeter Huewe buf = TPM_ACCESS_ACTIVE_LOCALITY; 258aad628c1SPeter Huewe iic_tpm_write(TPM_ACCESS(loc), &buf, 1); 259aad628c1SPeter Huewe } 260aad628c1SPeter Huewe } 261aad628c1SPeter Huewe 262aad628c1SPeter Huewe static int request_locality(struct tpm_chip *chip, int loc) 263aad628c1SPeter Huewe { 264aad628c1SPeter Huewe unsigned long stop; 265aad628c1SPeter Huewe u8 buf = TPM_ACCESS_REQUEST_USE; 266aad628c1SPeter Huewe 267aad628c1SPeter Huewe if (check_locality(chip, loc) >= 0) 268aad628c1SPeter Huewe return loc; 269aad628c1SPeter Huewe 270aad628c1SPeter Huewe iic_tpm_write(TPM_ACCESS(loc), &buf, 1); 271aad628c1SPeter Huewe 272aad628c1SPeter Huewe /* wait for burstcount */ 273aad628c1SPeter Huewe stop = jiffies + chip->vendor.timeout_a; 274aad628c1SPeter Huewe do { 275aad628c1SPeter Huewe if (check_locality(chip, loc) >= 0) 276aad628c1SPeter Huewe return loc; 277aad628c1SPeter Huewe usleep_range(TPM_TIMEOUT_US_LOW, TPM_TIMEOUT_US_HI); 278aad628c1SPeter Huewe } while (time_before(jiffies, stop)); 279aad628c1SPeter Huewe 280aad628c1SPeter Huewe return -ETIME; 281aad628c1SPeter Huewe } 282aad628c1SPeter Huewe 283aad628c1SPeter Huewe static u8 tpm_tis_i2c_status(struct tpm_chip *chip) 284aad628c1SPeter Huewe { 285aad628c1SPeter Huewe /* NOTE: since I2C read may fail, return 0 in this case --> time-out */ 286aad628c1SPeter Huewe u8 buf; 287aad628c1SPeter Huewe if (iic_tpm_read(TPM_STS(chip->vendor.locality), &buf, 1) < 0) 288aad628c1SPeter Huewe return 0; 289aad628c1SPeter Huewe else 290aad628c1SPeter Huewe return buf; 291aad628c1SPeter Huewe } 292aad628c1SPeter Huewe 293aad628c1SPeter Huewe static void tpm_tis_i2c_ready(struct tpm_chip *chip) 294aad628c1SPeter Huewe { 295aad628c1SPeter Huewe /* this causes the current command to be aborted */ 296aad628c1SPeter Huewe u8 buf = TPM_STS_COMMAND_READY; 297aad628c1SPeter Huewe iic_tpm_write_long(TPM_STS(chip->vendor.locality), &buf, 1); 298aad628c1SPeter Huewe } 299aad628c1SPeter Huewe 300aad628c1SPeter Huewe static ssize_t get_burstcount(struct tpm_chip *chip) 301aad628c1SPeter Huewe { 302aad628c1SPeter Huewe unsigned long stop; 303aad628c1SPeter Huewe ssize_t burstcnt; 304aad628c1SPeter Huewe u8 buf[3]; 305aad628c1SPeter Huewe 306aad628c1SPeter Huewe /* wait for burstcount */ 307aad628c1SPeter Huewe /* which timeout value, spec has 2 answers (c & d) */ 308aad628c1SPeter Huewe stop = jiffies + chip->vendor.timeout_d; 309aad628c1SPeter Huewe do { 310aad628c1SPeter Huewe /* Note: STS is little endian */ 311aad628c1SPeter Huewe if (iic_tpm_read(TPM_STS(chip->vendor.locality)+1, buf, 3) < 0) 312aad628c1SPeter Huewe burstcnt = 0; 313aad628c1SPeter Huewe else 314aad628c1SPeter Huewe burstcnt = (buf[2] << 16) + (buf[1] << 8) + buf[0]; 315aad628c1SPeter Huewe 316aad628c1SPeter Huewe if (burstcnt) 317aad628c1SPeter Huewe return burstcnt; 318aad628c1SPeter Huewe 319aad628c1SPeter Huewe usleep_range(TPM_TIMEOUT_US_LOW, TPM_TIMEOUT_US_HI); 320aad628c1SPeter Huewe } while (time_before(jiffies, stop)); 321aad628c1SPeter Huewe return -EBUSY; 322aad628c1SPeter Huewe } 323aad628c1SPeter Huewe 324aad628c1SPeter Huewe static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout, 325aad628c1SPeter Huewe int *status) 326aad628c1SPeter Huewe { 327aad628c1SPeter Huewe unsigned long stop; 328aad628c1SPeter Huewe 329aad628c1SPeter Huewe /* check current status */ 330aad628c1SPeter Huewe *status = tpm_tis_i2c_status(chip); 331aad628c1SPeter Huewe if ((*status & mask) == mask) 332aad628c1SPeter Huewe return 0; 333aad628c1SPeter Huewe 334aad628c1SPeter Huewe stop = jiffies + timeout; 335aad628c1SPeter Huewe do { 336aad628c1SPeter Huewe /* since we just checked the status, give the TPM some time */ 337aad628c1SPeter Huewe usleep_range(TPM_TIMEOUT_US_LOW, TPM_TIMEOUT_US_HI); 338aad628c1SPeter Huewe *status = tpm_tis_i2c_status(chip); 339aad628c1SPeter Huewe if ((*status & mask) == mask) 340aad628c1SPeter Huewe return 0; 341aad628c1SPeter Huewe 342aad628c1SPeter Huewe } while (time_before(jiffies, stop)); 343aad628c1SPeter Huewe 344aad628c1SPeter Huewe return -ETIME; 345aad628c1SPeter Huewe } 346aad628c1SPeter Huewe 347aad628c1SPeter Huewe static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count) 348aad628c1SPeter Huewe { 349aad628c1SPeter Huewe size_t size = 0; 350aad628c1SPeter Huewe ssize_t burstcnt; 351aad628c1SPeter Huewe u8 retries = 0; 352aad628c1SPeter Huewe int rc; 353aad628c1SPeter Huewe 354aad628c1SPeter Huewe while (size < count) { 355aad628c1SPeter Huewe burstcnt = get_burstcount(chip); 356aad628c1SPeter Huewe 357aad628c1SPeter Huewe /* burstcnt < 0 = TPM is busy */ 358aad628c1SPeter Huewe if (burstcnt < 0) 359aad628c1SPeter Huewe return burstcnt; 360aad628c1SPeter Huewe 361aad628c1SPeter Huewe /* limit received data to max. left */ 362aad628c1SPeter Huewe if (burstcnt > (count - size)) 363aad628c1SPeter Huewe burstcnt = count - size; 364aad628c1SPeter Huewe 365aad628c1SPeter Huewe rc = iic_tpm_read(TPM_DATA_FIFO(chip->vendor.locality), 366aad628c1SPeter Huewe &(buf[size]), burstcnt); 367aad628c1SPeter Huewe if (rc == 0) 368aad628c1SPeter Huewe size += burstcnt; 369aad628c1SPeter Huewe else if (rc < 0) 370aad628c1SPeter Huewe retries++; 371aad628c1SPeter Huewe 372aad628c1SPeter Huewe /* avoid endless loop in case of broken HW */ 373aad628c1SPeter Huewe if (retries > MAX_COUNT_LONG) 374aad628c1SPeter Huewe return -EIO; 375aad628c1SPeter Huewe 376aad628c1SPeter Huewe } 377aad628c1SPeter Huewe return size; 378aad628c1SPeter Huewe } 379aad628c1SPeter Huewe 380aad628c1SPeter Huewe static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count) 381aad628c1SPeter Huewe { 382aad628c1SPeter Huewe int size = 0; 383aad628c1SPeter Huewe int expected, status; 384aad628c1SPeter Huewe 385aad628c1SPeter Huewe if (count < TPM_HEADER_SIZE) { 386aad628c1SPeter Huewe size = -EIO; 387aad628c1SPeter Huewe goto out; 388aad628c1SPeter Huewe } 389aad628c1SPeter Huewe 390aad628c1SPeter Huewe /* read first 10 bytes, including tag, paramsize, and result */ 391aad628c1SPeter Huewe size = recv_data(chip, buf, TPM_HEADER_SIZE); 392aad628c1SPeter Huewe if (size < TPM_HEADER_SIZE) { 393aad628c1SPeter Huewe dev_err(chip->dev, "Unable to read header\n"); 394aad628c1SPeter Huewe goto out; 395aad628c1SPeter Huewe } 396aad628c1SPeter Huewe 397aad628c1SPeter Huewe expected = be32_to_cpu(*(__be32 *)(buf + 2)); 398aad628c1SPeter Huewe if ((size_t) expected > count) { 399aad628c1SPeter Huewe size = -EIO; 400aad628c1SPeter Huewe goto out; 401aad628c1SPeter Huewe } 402aad628c1SPeter Huewe 403aad628c1SPeter Huewe size += recv_data(chip, &buf[TPM_HEADER_SIZE], 404aad628c1SPeter Huewe expected - TPM_HEADER_SIZE); 405aad628c1SPeter Huewe if (size < expected) { 406aad628c1SPeter Huewe dev_err(chip->dev, "Unable to read remainder of result\n"); 407aad628c1SPeter Huewe size = -ETIME; 408aad628c1SPeter Huewe goto out; 409aad628c1SPeter Huewe } 410aad628c1SPeter Huewe 411aad628c1SPeter Huewe wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status); 412aad628c1SPeter Huewe if (status & TPM_STS_DATA_AVAIL) { /* retry? */ 413aad628c1SPeter Huewe dev_err(chip->dev, "Error left over data\n"); 414aad628c1SPeter Huewe size = -EIO; 415aad628c1SPeter Huewe goto out; 416aad628c1SPeter Huewe } 417aad628c1SPeter Huewe 418aad628c1SPeter Huewe out: 419aad628c1SPeter Huewe tpm_tis_i2c_ready(chip); 420aad628c1SPeter Huewe /* The TPM needs some time to clean up here, 421aad628c1SPeter Huewe * so we sleep rather than keeping the bus busy 422aad628c1SPeter Huewe */ 423aad628c1SPeter Huewe usleep_range(SLEEP_DURATION_RESET_LOW, SLEEP_DURATION_RESET_HI); 424aad628c1SPeter Huewe release_locality(chip, chip->vendor.locality, 0); 425aad628c1SPeter Huewe return size; 426aad628c1SPeter Huewe } 427aad628c1SPeter Huewe 428aad628c1SPeter Huewe static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len) 429aad628c1SPeter Huewe { 430aad628c1SPeter Huewe int rc, status; 431aad628c1SPeter Huewe ssize_t burstcnt; 432aad628c1SPeter Huewe size_t count = 0; 433aad628c1SPeter Huewe u8 retries = 0; 434aad628c1SPeter Huewe u8 sts = TPM_STS_GO; 435aad628c1SPeter Huewe 436aad628c1SPeter Huewe if (len > TPM_BUFSIZE) 437aad628c1SPeter Huewe return -E2BIG; /* command is too long for our tpm, sorry */ 438aad628c1SPeter Huewe 439aad628c1SPeter Huewe if (request_locality(chip, 0) < 0) 440aad628c1SPeter Huewe return -EBUSY; 441aad628c1SPeter Huewe 442aad628c1SPeter Huewe status = tpm_tis_i2c_status(chip); 443aad628c1SPeter Huewe if ((status & TPM_STS_COMMAND_READY) == 0) { 444aad628c1SPeter Huewe tpm_tis_i2c_ready(chip); 445aad628c1SPeter Huewe if (wait_for_stat 446aad628c1SPeter Huewe (chip, TPM_STS_COMMAND_READY, 447aad628c1SPeter Huewe chip->vendor.timeout_b, &status) < 0) { 448aad628c1SPeter Huewe rc = -ETIME; 449aad628c1SPeter Huewe goto out_err; 450aad628c1SPeter Huewe } 451aad628c1SPeter Huewe } 452aad628c1SPeter Huewe 453aad628c1SPeter Huewe while (count < len - 1) { 454aad628c1SPeter Huewe burstcnt = get_burstcount(chip); 455aad628c1SPeter Huewe 456aad628c1SPeter Huewe /* burstcnt < 0 = TPM is busy */ 457aad628c1SPeter Huewe if (burstcnt < 0) 458aad628c1SPeter Huewe return burstcnt; 459aad628c1SPeter Huewe 460aad628c1SPeter Huewe if (burstcnt > (len - 1 - count)) 461aad628c1SPeter Huewe burstcnt = len - 1 - count; 462aad628c1SPeter Huewe 463aad628c1SPeter Huewe rc = iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality), 464aad628c1SPeter Huewe &(buf[count]), burstcnt); 465aad628c1SPeter Huewe if (rc == 0) 466aad628c1SPeter Huewe count += burstcnt; 467aad628c1SPeter Huewe else if (rc < 0) 468aad628c1SPeter Huewe retries++; 469aad628c1SPeter Huewe 470aad628c1SPeter Huewe /* avoid endless loop in case of broken HW */ 471aad628c1SPeter Huewe if (retries > MAX_COUNT_LONG) { 472aad628c1SPeter Huewe rc = -EIO; 473aad628c1SPeter Huewe goto out_err; 474aad628c1SPeter Huewe } 475aad628c1SPeter Huewe 476aad628c1SPeter Huewe wait_for_stat(chip, TPM_STS_VALID, 477aad628c1SPeter Huewe chip->vendor.timeout_c, &status); 478aad628c1SPeter Huewe 479aad628c1SPeter Huewe if ((status & TPM_STS_DATA_EXPECT) == 0) { 480aad628c1SPeter Huewe rc = -EIO; 481aad628c1SPeter Huewe goto out_err; 482aad628c1SPeter Huewe } 483aad628c1SPeter Huewe 484aad628c1SPeter Huewe } 485aad628c1SPeter Huewe 486aad628c1SPeter Huewe /* write last byte */ 487aad628c1SPeter Huewe iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality), &(buf[count]), 1); 488aad628c1SPeter Huewe wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status); 489aad628c1SPeter Huewe if ((status & TPM_STS_DATA_EXPECT) != 0) { 490aad628c1SPeter Huewe rc = -EIO; 491aad628c1SPeter Huewe goto out_err; 492aad628c1SPeter Huewe } 493aad628c1SPeter Huewe 494aad628c1SPeter Huewe /* go and do it */ 495aad628c1SPeter Huewe iic_tpm_write(TPM_STS(chip->vendor.locality), &sts, 1); 496aad628c1SPeter Huewe 497aad628c1SPeter Huewe return len; 498aad628c1SPeter Huewe out_err: 499aad628c1SPeter Huewe tpm_tis_i2c_ready(chip); 500aad628c1SPeter Huewe /* The TPM needs some time to clean up here, 501aad628c1SPeter Huewe * so we sleep rather than keeping the bus busy 502aad628c1SPeter Huewe */ 503aad628c1SPeter Huewe usleep_range(SLEEP_DURATION_RESET_LOW, SLEEP_DURATION_RESET_HI); 504aad628c1SPeter Huewe release_locality(chip, chip->vendor.locality, 0); 505aad628c1SPeter Huewe return rc; 506aad628c1SPeter Huewe } 507aad628c1SPeter Huewe 508aad628c1SPeter Huewe static const struct file_operations tis_ops = { 509aad628c1SPeter Huewe .owner = THIS_MODULE, 510aad628c1SPeter Huewe .llseek = no_llseek, 511aad628c1SPeter Huewe .open = tpm_open, 512aad628c1SPeter Huewe .read = tpm_read, 513aad628c1SPeter Huewe .write = tpm_write, 514aad628c1SPeter Huewe .release = tpm_release, 515aad628c1SPeter Huewe }; 516aad628c1SPeter Huewe 517aad628c1SPeter Huewe static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); 518aad628c1SPeter Huewe static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); 519aad628c1SPeter Huewe static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); 520aad628c1SPeter Huewe static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); 521aad628c1SPeter Huewe static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); 522aad628c1SPeter Huewe static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); 523aad628c1SPeter Huewe static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL); 524aad628c1SPeter Huewe static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); 525aad628c1SPeter Huewe static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); 526aad628c1SPeter Huewe static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); 527aad628c1SPeter Huewe 528aad628c1SPeter Huewe static struct attribute *tis_attrs[] = { 529aad628c1SPeter Huewe &dev_attr_pubek.attr, 530aad628c1SPeter Huewe &dev_attr_pcrs.attr, 531aad628c1SPeter Huewe &dev_attr_enabled.attr, 532aad628c1SPeter Huewe &dev_attr_active.attr, 533aad628c1SPeter Huewe &dev_attr_owned.attr, 534aad628c1SPeter Huewe &dev_attr_temp_deactivated.attr, 535aad628c1SPeter Huewe &dev_attr_caps.attr, 536aad628c1SPeter Huewe &dev_attr_cancel.attr, 537aad628c1SPeter Huewe &dev_attr_durations.attr, 538aad628c1SPeter Huewe &dev_attr_timeouts.attr, 539aad628c1SPeter Huewe NULL, 540aad628c1SPeter Huewe }; 541aad628c1SPeter Huewe 542aad628c1SPeter Huewe static struct attribute_group tis_attr_grp = { 543aad628c1SPeter Huewe .attrs = tis_attrs 544aad628c1SPeter Huewe }; 545aad628c1SPeter Huewe 546aad628c1SPeter Huewe static struct tpm_vendor_specific tpm_tis_i2c = { 547aad628c1SPeter Huewe .status = tpm_tis_i2c_status, 548aad628c1SPeter Huewe .recv = tpm_tis_i2c_recv, 549aad628c1SPeter Huewe .send = tpm_tis_i2c_send, 550aad628c1SPeter Huewe .cancel = tpm_tis_i2c_ready, 551aad628c1SPeter Huewe .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, 552aad628c1SPeter Huewe .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, 553aad628c1SPeter Huewe .req_canceled = TPM_STS_COMMAND_READY, 554aad628c1SPeter Huewe .attr_group = &tis_attr_grp, 555aad628c1SPeter Huewe .miscdev.fops = &tis_ops, 556aad628c1SPeter Huewe }; 557aad628c1SPeter Huewe 558aad628c1SPeter Huewe static int __devinit tpm_tis_i2c_init(struct device *dev) 559aad628c1SPeter Huewe { 560aad628c1SPeter Huewe u32 vendor; 561aad628c1SPeter Huewe int rc = 0; 562aad628c1SPeter Huewe struct tpm_chip *chip; 563aad628c1SPeter Huewe 564aad628c1SPeter Huewe chip = tpm_register_hardware(dev, &tpm_tis_i2c); 565aad628c1SPeter Huewe if (!chip) { 566aad628c1SPeter Huewe rc = -ENODEV; 567aad628c1SPeter Huewe goto out_err; 568aad628c1SPeter Huewe } 569aad628c1SPeter Huewe 570aad628c1SPeter Huewe /* Disable interrupts */ 571aad628c1SPeter Huewe chip->vendor.irq = 0; 572aad628c1SPeter Huewe 573aad628c1SPeter Huewe /* Default timeouts */ 574aad628c1SPeter Huewe chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT); 575aad628c1SPeter Huewe chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT); 576aad628c1SPeter Huewe chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT); 577aad628c1SPeter Huewe chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT); 578aad628c1SPeter Huewe 579aad628c1SPeter Huewe if (request_locality(chip, 0) != 0) { 580aad628c1SPeter Huewe rc = -ENODEV; 581aad628c1SPeter Huewe goto out_vendor; 582aad628c1SPeter Huewe } 583aad628c1SPeter Huewe 584aad628c1SPeter Huewe /* read four bytes from DID_VID register */ 585aad628c1SPeter Huewe if (iic_tpm_read(TPM_DID_VID(0), (u8 *)&vendor, 4) < 0) { 586aad628c1SPeter Huewe rc = -EIO; 587aad628c1SPeter Huewe goto out_release; 588aad628c1SPeter Huewe } 589aad628c1SPeter Huewe 590aad628c1SPeter Huewe /* create DID_VID register value, after swapping to little-endian */ 591aad628c1SPeter Huewe vendor = be32_to_cpu((__be32) vendor); 592aad628c1SPeter Huewe 593aad628c1SPeter Huewe if (vendor != TPM_TIS_I2C_DID_VID) { 594aad628c1SPeter Huewe rc = -ENODEV; 595aad628c1SPeter Huewe goto out_release; 596aad628c1SPeter Huewe } 597aad628c1SPeter Huewe 598aad628c1SPeter Huewe dev_info(dev, "1.2 TPM (device-id 0x%X)\n", vendor >> 16); 599aad628c1SPeter Huewe 600aad628c1SPeter Huewe INIT_LIST_HEAD(&chip->vendor.list); 601aad628c1SPeter Huewe tpm_dev.chip = chip; 602aad628c1SPeter Huewe 603aad628c1SPeter Huewe tpm_get_timeouts(chip); 604aad628c1SPeter Huewe tpm_do_selftest(chip); 605aad628c1SPeter Huewe 606aad628c1SPeter Huewe return 0; 607aad628c1SPeter Huewe 608aad628c1SPeter Huewe out_release: 609aad628c1SPeter Huewe release_locality(chip, chip->vendor.locality, 1); 610aad628c1SPeter Huewe 611aad628c1SPeter Huewe out_vendor: 612aad628c1SPeter Huewe /* close file handles */ 613aad628c1SPeter Huewe tpm_dev_vendor_release(chip); 614aad628c1SPeter Huewe 615aad628c1SPeter Huewe /* remove hardware */ 616aad628c1SPeter Huewe tpm_remove_hardware(chip->dev); 617aad628c1SPeter Huewe 618aad628c1SPeter Huewe /* reset these pointers, otherwise we oops */ 619aad628c1SPeter Huewe chip->dev->release = NULL; 620aad628c1SPeter Huewe chip->release = NULL; 621aad628c1SPeter Huewe tpm_dev.client = NULL; 622aad628c1SPeter Huewe dev_set_drvdata(chip->dev, chip); 623aad628c1SPeter Huewe out_err: 624aad628c1SPeter Huewe return rc; 625aad628c1SPeter Huewe } 626aad628c1SPeter Huewe 627aad628c1SPeter Huewe static const struct i2c_device_id tpm_tis_i2c_table[] = { 628aad628c1SPeter Huewe {"tpm_i2c_infineon", 0}, 629aad628c1SPeter Huewe {}, 630aad628c1SPeter Huewe }; 631aad628c1SPeter Huewe 632aad628c1SPeter Huewe MODULE_DEVICE_TABLE(i2c, tpm_tis_i2c_table); 633aad628c1SPeter Huewe static SIMPLE_DEV_PM_OPS(tpm_tis_i2c_ops, tpm_pm_suspend, tpm_pm_resume); 634aad628c1SPeter Huewe 635aad628c1SPeter Huewe static int __devinit tpm_tis_i2c_probe(struct i2c_client *client, 636aad628c1SPeter Huewe const struct i2c_device_id *id) 637aad628c1SPeter Huewe { 638aad628c1SPeter Huewe int rc; 639aad628c1SPeter Huewe if (tpm_dev.client != NULL) 640aad628c1SPeter Huewe return -EBUSY; /* We only support one client */ 641aad628c1SPeter Huewe 642aad628c1SPeter Huewe if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 643aad628c1SPeter Huewe dev_err(&client->dev, 644aad628c1SPeter Huewe "no algorithms associated to the i2c bus\n"); 645aad628c1SPeter Huewe return -ENODEV; 646aad628c1SPeter Huewe } 647aad628c1SPeter Huewe 648aad628c1SPeter Huewe client->driver = &tpm_tis_i2c_driver; 649aad628c1SPeter Huewe tpm_dev.client = client; 650aad628c1SPeter Huewe rc = tpm_tis_i2c_init(&client->dev); 651aad628c1SPeter Huewe if (rc != 0) { 652aad628c1SPeter Huewe client->driver = NULL; 653aad628c1SPeter Huewe tpm_dev.client = NULL; 654aad628c1SPeter Huewe rc = -ENODEV; 655aad628c1SPeter Huewe } 656aad628c1SPeter Huewe return rc; 657aad628c1SPeter Huewe } 658aad628c1SPeter Huewe 659*39af33fcSBill Pemberton static int tpm_tis_i2c_remove(struct i2c_client *client) 660aad628c1SPeter Huewe { 661aad628c1SPeter Huewe struct tpm_chip *chip = tpm_dev.chip; 662aad628c1SPeter Huewe release_locality(chip, chip->vendor.locality, 1); 663aad628c1SPeter Huewe 664aad628c1SPeter Huewe /* close file handles */ 665aad628c1SPeter Huewe tpm_dev_vendor_release(chip); 666aad628c1SPeter Huewe 667aad628c1SPeter Huewe /* remove hardware */ 668aad628c1SPeter Huewe tpm_remove_hardware(chip->dev); 669aad628c1SPeter Huewe 670aad628c1SPeter Huewe /* reset these pointers, otherwise we oops */ 671aad628c1SPeter Huewe chip->dev->release = NULL; 672aad628c1SPeter Huewe chip->release = NULL; 673aad628c1SPeter Huewe tpm_dev.client = NULL; 674aad628c1SPeter Huewe dev_set_drvdata(chip->dev, chip); 675aad628c1SPeter Huewe 676aad628c1SPeter Huewe return 0; 677aad628c1SPeter Huewe } 678aad628c1SPeter Huewe 679aad628c1SPeter Huewe static struct i2c_driver tpm_tis_i2c_driver = { 680aad628c1SPeter Huewe 681aad628c1SPeter Huewe .id_table = tpm_tis_i2c_table, 682aad628c1SPeter Huewe .probe = tpm_tis_i2c_probe, 683aad628c1SPeter Huewe .remove = tpm_tis_i2c_remove, 684aad628c1SPeter Huewe .driver = { 685aad628c1SPeter Huewe .name = "tpm_i2c_infineon", 686aad628c1SPeter Huewe .owner = THIS_MODULE, 687aad628c1SPeter Huewe .pm = &tpm_tis_i2c_ops, 688aad628c1SPeter Huewe }, 689aad628c1SPeter Huewe }; 690aad628c1SPeter Huewe 691aad628c1SPeter Huewe module_i2c_driver(tpm_tis_i2c_driver); 692aad628c1SPeter Huewe MODULE_AUTHOR("Peter Huewe <peter.huewe@infineon.com>"); 693aad628c1SPeter Huewe MODULE_DESCRIPTION("TPM TIS I2C Infineon Driver"); 694aad628c1SPeter Huewe MODULE_VERSION("2.1.5"); 695aad628c1SPeter Huewe MODULE_LICENSE("GPL"); 696