1bbc23a07SAlexander Steffen // SPDX-License-Identifier: GPL-2.0 2bbc23a07SAlexander Steffen /* 3bbc23a07SAlexander Steffen * Copyright (c) 2014-2021 Nuvoton Technology corporation 4bbc23a07SAlexander Steffen * Copyright (C) 2019-2022 Infineon Technologies AG 5bbc23a07SAlexander Steffen * 6bbc23a07SAlexander Steffen * This device driver implements the TPM interface as defined in the TCG PC 7bbc23a07SAlexander Steffen * Client Platform TPM Profile (PTP) Specification for TPM 2.0 v1.04 8bbc23a07SAlexander Steffen * Revision 14. 9bbc23a07SAlexander Steffen * 10bbc23a07SAlexander Steffen * It is based on the tpm_tis_spi device driver. 11bbc23a07SAlexander Steffen */ 12bbc23a07SAlexander Steffen 13bbc23a07SAlexander Steffen #include <linux/i2c.h> 14bbc23a07SAlexander Steffen #include <linux/crc-ccitt.h> 15bbc23a07SAlexander Steffen #include "tpm_tis_core.h" 16bbc23a07SAlexander Steffen 17bbc23a07SAlexander Steffen /* TPM registers */ 18bbc23a07SAlexander Steffen #define TPM_I2C_LOC_SEL 0x00 19bbc23a07SAlexander Steffen #define TPM_I2C_ACCESS 0x04 20bbc23a07SAlexander Steffen #define TPM_I2C_INTERFACE_CAPABILITY 0x30 21bbc23a07SAlexander Steffen #define TPM_I2C_DEVICE_ADDRESS 0x38 22bbc23a07SAlexander Steffen #define TPM_I2C_DATA_CSUM_ENABLE 0x40 23bbc23a07SAlexander Steffen #define TPM_DATA_CSUM 0x44 24bbc23a07SAlexander Steffen #define TPM_I2C_DID_VID 0x48 25bbc23a07SAlexander Steffen #define TPM_I2C_RID 0x4C 26bbc23a07SAlexander Steffen 27bbc23a07SAlexander Steffen /* TIS-compatible register address to avoid clash with TPM_ACCESS (0x00) */ 28bbc23a07SAlexander Steffen #define TPM_LOC_SEL 0x0FFF 29bbc23a07SAlexander Steffen 30bbc23a07SAlexander Steffen /* Mask to extract the I2C register from TIS register addresses */ 31bbc23a07SAlexander Steffen #define TPM_TIS_REGISTER_MASK 0x0FFF 32bbc23a07SAlexander Steffen 33bbc23a07SAlexander Steffen /* Default Guard Time of 250µs until interface capability register is read */ 34bbc23a07SAlexander Steffen #define GUARD_TIME_DEFAULT_MIN 250 35bbc23a07SAlexander Steffen #define GUARD_TIME_DEFAULT_MAX 300 36bbc23a07SAlexander Steffen 37bbc23a07SAlexander Steffen /* Guard Time of 250µs after I2C slave NACK */ 38bbc23a07SAlexander Steffen #define GUARD_TIME_ERR_MIN 250 39bbc23a07SAlexander Steffen #define GUARD_TIME_ERR_MAX 300 40bbc23a07SAlexander Steffen 41bbc23a07SAlexander Steffen /* Guard Time bit masks; SR is repeated start, RW is read then write, etc. */ 42bbc23a07SAlexander Steffen #define TPM_GUARD_TIME_SR_MASK 0x40000000 43bbc23a07SAlexander Steffen #define TPM_GUARD_TIME_RR_MASK 0x00100000 44bbc23a07SAlexander Steffen #define TPM_GUARD_TIME_RW_MASK 0x00080000 45bbc23a07SAlexander Steffen #define TPM_GUARD_TIME_WR_MASK 0x00040000 46bbc23a07SAlexander Steffen #define TPM_GUARD_TIME_WW_MASK 0x00020000 47bbc23a07SAlexander Steffen #define TPM_GUARD_TIME_MIN_MASK 0x0001FE00 48bbc23a07SAlexander Steffen #define TPM_GUARD_TIME_MIN_SHIFT 9 49bbc23a07SAlexander Steffen 50bbc23a07SAlexander Steffen /* Masks with bits that must be read zero */ 51bbc23a07SAlexander Steffen #define TPM_ACCESS_READ_ZERO 0x48 52561d6ef7SEddie James #define TPM_INT_ENABLE_ZERO 0x7FFFFF60 53bbc23a07SAlexander Steffen #define TPM_STS_READ_ZERO 0x23 54bbc23a07SAlexander Steffen #define TPM_INTF_CAPABILITY_ZERO 0x0FFFF000 55bbc23a07SAlexander Steffen #define TPM_I2C_INTERFACE_CAPABILITY_ZERO 0x80000000 56bbc23a07SAlexander Steffen 57bbc23a07SAlexander Steffen struct tpm_tis_i2c_phy { 58bbc23a07SAlexander Steffen struct tpm_tis_data priv; 59bbc23a07SAlexander Steffen struct i2c_client *i2c_client; 60bbc23a07SAlexander Steffen bool guard_time_read; 61bbc23a07SAlexander Steffen bool guard_time_write; 62bbc23a07SAlexander Steffen u16 guard_time_min; 63bbc23a07SAlexander Steffen u16 guard_time_max; 64bbc23a07SAlexander Steffen u8 *io_buf; 65bbc23a07SAlexander Steffen }; 66bbc23a07SAlexander Steffen 67bbc23a07SAlexander Steffen static inline struct tpm_tis_i2c_phy * 68bbc23a07SAlexander Steffen to_tpm_tis_i2c_phy(struct tpm_tis_data *data) 69bbc23a07SAlexander Steffen { 70bbc23a07SAlexander Steffen return container_of(data, struct tpm_tis_i2c_phy, priv); 71bbc23a07SAlexander Steffen } 72bbc23a07SAlexander Steffen 73bbc23a07SAlexander Steffen /* 74bbc23a07SAlexander Steffen * tpm_tis_core uses the register addresses as defined in Table 19 "Allocation 75bbc23a07SAlexander Steffen * of Register Space for FIFO TPM Access" of the TCG PC Client PTP 76bbc23a07SAlexander Steffen * Specification. In order for this code to work together with tpm_tis_core, 77bbc23a07SAlexander Steffen * those addresses need to mapped to the registers defined for I2C TPMs in 78bbc23a07SAlexander Steffen * Table 51 "I2C-TPM Register Overview". 79bbc23a07SAlexander Steffen * 80bbc23a07SAlexander Steffen * For most addresses this can be done by simply stripping off the locality 81bbc23a07SAlexander Steffen * information from the address. A few addresses need to be mapped explicitly, 82bbc23a07SAlexander Steffen * since the corresponding I2C registers have been moved around. TPM_LOC_SEL is 83bbc23a07SAlexander Steffen * only defined for I2C TPMs and is also mapped explicitly here to distinguish 84bbc23a07SAlexander Steffen * it from TPM_ACCESS(0). 85bbc23a07SAlexander Steffen * 86bbc23a07SAlexander Steffen * Locality information is ignored, since this driver assumes exclusive access 87bbc23a07SAlexander Steffen * to the TPM and always uses locality 0. 88bbc23a07SAlexander Steffen */ 89bbc23a07SAlexander Steffen static u8 tpm_tis_i2c_address_to_register(u32 addr) 90bbc23a07SAlexander Steffen { 91bbc23a07SAlexander Steffen addr &= TPM_TIS_REGISTER_MASK; 92bbc23a07SAlexander Steffen 93bbc23a07SAlexander Steffen switch (addr) { 94bbc23a07SAlexander Steffen case TPM_ACCESS(0): 95bbc23a07SAlexander Steffen return TPM_I2C_ACCESS; 96bbc23a07SAlexander Steffen case TPM_LOC_SEL: 97bbc23a07SAlexander Steffen return TPM_I2C_LOC_SEL; 98bbc23a07SAlexander Steffen case TPM_DID_VID(0): 99bbc23a07SAlexander Steffen return TPM_I2C_DID_VID; 100bbc23a07SAlexander Steffen case TPM_RID(0): 101bbc23a07SAlexander Steffen return TPM_I2C_RID; 102bbc23a07SAlexander Steffen default: 103bbc23a07SAlexander Steffen return addr; 104bbc23a07SAlexander Steffen } 105bbc23a07SAlexander Steffen } 106bbc23a07SAlexander Steffen 107bbc23a07SAlexander Steffen static int tpm_tis_i2c_retry_transfer_until_ack(struct tpm_tis_data *data, 108bbc23a07SAlexander Steffen struct i2c_msg *msg) 109bbc23a07SAlexander Steffen { 110bbc23a07SAlexander Steffen struct tpm_tis_i2c_phy *phy = to_tpm_tis_i2c_phy(data); 111bbc23a07SAlexander Steffen bool guard_time; 112bbc23a07SAlexander Steffen int i = 0; 113bbc23a07SAlexander Steffen int ret; 114bbc23a07SAlexander Steffen 115bbc23a07SAlexander Steffen if (msg->flags & I2C_M_RD) 116bbc23a07SAlexander Steffen guard_time = phy->guard_time_read; 117bbc23a07SAlexander Steffen else 118bbc23a07SAlexander Steffen guard_time = phy->guard_time_write; 119bbc23a07SAlexander Steffen 120bbc23a07SAlexander Steffen do { 121bbc23a07SAlexander Steffen ret = i2c_transfer(phy->i2c_client->adapter, msg, 1); 122bbc23a07SAlexander Steffen if (ret < 0) 123bbc23a07SAlexander Steffen usleep_range(GUARD_TIME_ERR_MIN, GUARD_TIME_ERR_MAX); 124bbc23a07SAlexander Steffen else if (guard_time) 125bbc23a07SAlexander Steffen usleep_range(phy->guard_time_min, phy->guard_time_max); 126bbc23a07SAlexander Steffen /* retry on TPM NACK */ 127bbc23a07SAlexander Steffen } while (ret < 0 && i++ < TPM_RETRY); 128bbc23a07SAlexander Steffen 129bbc23a07SAlexander Steffen return ret; 130bbc23a07SAlexander Steffen } 131bbc23a07SAlexander Steffen 132bbc23a07SAlexander Steffen /* Check that bits which must be read zero are not set */ 133bbc23a07SAlexander Steffen static int tpm_tis_i2c_sanity_check_read(u8 reg, u16 len, u8 *buf) 134bbc23a07SAlexander Steffen { 135bbc23a07SAlexander Steffen u32 zero_mask; 136bbc23a07SAlexander Steffen u32 value; 137bbc23a07SAlexander Steffen 138bbc23a07SAlexander Steffen switch (len) { 139bbc23a07SAlexander Steffen case sizeof(u8): 140bbc23a07SAlexander Steffen value = buf[0]; 141bbc23a07SAlexander Steffen break; 142bbc23a07SAlexander Steffen case sizeof(u16): 143bbc23a07SAlexander Steffen value = le16_to_cpup((__le16 *)buf); 144bbc23a07SAlexander Steffen break; 145bbc23a07SAlexander Steffen case sizeof(u32): 146bbc23a07SAlexander Steffen value = le32_to_cpup((__le32 *)buf); 147bbc23a07SAlexander Steffen break; 148bbc23a07SAlexander Steffen default: 149bbc23a07SAlexander Steffen /* unknown length, skip check */ 150bbc23a07SAlexander Steffen return 0; 151bbc23a07SAlexander Steffen } 152bbc23a07SAlexander Steffen 153bbc23a07SAlexander Steffen switch (reg) { 154bbc23a07SAlexander Steffen case TPM_I2C_ACCESS: 155bbc23a07SAlexander Steffen zero_mask = TPM_ACCESS_READ_ZERO; 156bbc23a07SAlexander Steffen break; 157bbc23a07SAlexander Steffen case TPM_INT_ENABLE(0) & TPM_TIS_REGISTER_MASK: 158bbc23a07SAlexander Steffen zero_mask = TPM_INT_ENABLE_ZERO; 159bbc23a07SAlexander Steffen break; 160bbc23a07SAlexander Steffen case TPM_STS(0) & TPM_TIS_REGISTER_MASK: 161bbc23a07SAlexander Steffen zero_mask = TPM_STS_READ_ZERO; 162bbc23a07SAlexander Steffen break; 163bbc23a07SAlexander Steffen case TPM_INTF_CAPS(0) & TPM_TIS_REGISTER_MASK: 164bbc23a07SAlexander Steffen zero_mask = TPM_INTF_CAPABILITY_ZERO; 165bbc23a07SAlexander Steffen break; 166bbc23a07SAlexander Steffen case TPM_I2C_INTERFACE_CAPABILITY: 167bbc23a07SAlexander Steffen zero_mask = TPM_I2C_INTERFACE_CAPABILITY_ZERO; 168bbc23a07SAlexander Steffen break; 169bbc23a07SAlexander Steffen default: 170bbc23a07SAlexander Steffen /* unknown register, skip check */ 171bbc23a07SAlexander Steffen return 0; 172bbc23a07SAlexander Steffen } 173bbc23a07SAlexander Steffen 174bbc23a07SAlexander Steffen if (unlikely((value & zero_mask) != 0x00)) { 175bbc23a07SAlexander Steffen pr_debug("TPM I2C read of register 0x%02x failed sanity check: 0x%x\n", reg, value); 176bbc23a07SAlexander Steffen return -EIO; 177bbc23a07SAlexander Steffen } 178bbc23a07SAlexander Steffen 179bbc23a07SAlexander Steffen return 0; 180bbc23a07SAlexander Steffen } 181bbc23a07SAlexander Steffen 182bbc23a07SAlexander Steffen static int tpm_tis_i2c_read_bytes(struct tpm_tis_data *data, u32 addr, u16 len, 183bbc23a07SAlexander Steffen u8 *result, enum tpm_tis_io_mode io_mode) 184bbc23a07SAlexander Steffen { 185bbc23a07SAlexander Steffen struct tpm_tis_i2c_phy *phy = to_tpm_tis_i2c_phy(data); 186bbc23a07SAlexander Steffen struct i2c_msg msg = { .addr = phy->i2c_client->addr }; 187bbc23a07SAlexander Steffen u8 reg = tpm_tis_i2c_address_to_register(addr); 188bbc23a07SAlexander Steffen int i; 189bbc23a07SAlexander Steffen int ret; 190bbc23a07SAlexander Steffen 191bbc23a07SAlexander Steffen for (i = 0; i < TPM_RETRY; i++) { 192f3b70b6eSAlexander Sverdlin u16 read = 0; 193f3b70b6eSAlexander Sverdlin 194f3b70b6eSAlexander Sverdlin while (read < len) { 195bbc23a07SAlexander Steffen /* write register */ 196bbc23a07SAlexander Steffen msg.len = sizeof(reg); 197bbc23a07SAlexander Steffen msg.buf = ® 198bbc23a07SAlexander Steffen msg.flags = 0; 199bbc23a07SAlexander Steffen ret = tpm_tis_i2c_retry_transfer_until_ack(data, &msg); 200bbc23a07SAlexander Steffen if (ret < 0) 201bbc23a07SAlexander Steffen return ret; 202bbc23a07SAlexander Steffen 203bbc23a07SAlexander Steffen /* read data */ 204f3b70b6eSAlexander Sverdlin msg.buf = result + read; 205f3b70b6eSAlexander Sverdlin msg.len = len - read; 206bbc23a07SAlexander Steffen msg.flags = I2C_M_RD; 207f3b70b6eSAlexander Sverdlin if (msg.len > I2C_SMBUS_BLOCK_MAX) 208f3b70b6eSAlexander Sverdlin msg.len = I2C_SMBUS_BLOCK_MAX; 209bbc23a07SAlexander Steffen ret = tpm_tis_i2c_retry_transfer_until_ack(data, &msg); 210bbc23a07SAlexander Steffen if (ret < 0) 211bbc23a07SAlexander Steffen return ret; 212f3b70b6eSAlexander Sverdlin read += msg.len; 213f3b70b6eSAlexander Sverdlin } 214bbc23a07SAlexander Steffen 215bbc23a07SAlexander Steffen ret = tpm_tis_i2c_sanity_check_read(reg, len, result); 216bbc23a07SAlexander Steffen if (ret == 0) 217bbc23a07SAlexander Steffen return 0; 218bbc23a07SAlexander Steffen 219bbc23a07SAlexander Steffen usleep_range(GUARD_TIME_ERR_MIN, GUARD_TIME_ERR_MAX); 220bbc23a07SAlexander Steffen } 221bbc23a07SAlexander Steffen 222bbc23a07SAlexander Steffen return ret; 223bbc23a07SAlexander Steffen } 224bbc23a07SAlexander Steffen 225bbc23a07SAlexander Steffen static int tpm_tis_i2c_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len, 226bbc23a07SAlexander Steffen const u8 *value, 227bbc23a07SAlexander Steffen enum tpm_tis_io_mode io_mode) 228bbc23a07SAlexander Steffen { 229bbc23a07SAlexander Steffen struct tpm_tis_i2c_phy *phy = to_tpm_tis_i2c_phy(data); 230bbc23a07SAlexander Steffen struct i2c_msg msg = { .addr = phy->i2c_client->addr }; 231bbc23a07SAlexander Steffen u8 reg = tpm_tis_i2c_address_to_register(addr); 232bbc23a07SAlexander Steffen int ret; 233*83e7e5d8SAlexander Sverdlin u16 wrote = 0; 234bbc23a07SAlexander Steffen 235bbc23a07SAlexander Steffen if (len > TPM_BUFSIZE - 1) 236bbc23a07SAlexander Steffen return -EIO; 237bbc23a07SAlexander Steffen 238bbc23a07SAlexander Steffen phy->io_buf[0] = reg; 239bbc23a07SAlexander Steffen msg.buf = phy->io_buf; 240*83e7e5d8SAlexander Sverdlin while (wrote < len) { 241*83e7e5d8SAlexander Sverdlin /* write register and data in one go */ 242*83e7e5d8SAlexander Sverdlin msg.len = sizeof(reg) + len - wrote; 243*83e7e5d8SAlexander Sverdlin if (msg.len > I2C_SMBUS_BLOCK_MAX) 244*83e7e5d8SAlexander Sverdlin msg.len = I2C_SMBUS_BLOCK_MAX; 245*83e7e5d8SAlexander Sverdlin 246*83e7e5d8SAlexander Sverdlin memcpy(phy->io_buf + sizeof(reg), value + wrote, 247*83e7e5d8SAlexander Sverdlin msg.len - sizeof(reg)); 248*83e7e5d8SAlexander Sverdlin 249bbc23a07SAlexander Steffen ret = tpm_tis_i2c_retry_transfer_until_ack(data, &msg); 250bbc23a07SAlexander Steffen if (ret < 0) 251bbc23a07SAlexander Steffen return ret; 252*83e7e5d8SAlexander Sverdlin wrote += msg.len - sizeof(reg); 253*83e7e5d8SAlexander Sverdlin } 254bbc23a07SAlexander Steffen 255bbc23a07SAlexander Steffen return 0; 256bbc23a07SAlexander Steffen } 257bbc23a07SAlexander Steffen 258bbc23a07SAlexander Steffen static int tpm_tis_i2c_verify_crc(struct tpm_tis_data *data, size_t len, 259bbc23a07SAlexander Steffen const u8 *value) 260bbc23a07SAlexander Steffen { 261bbc23a07SAlexander Steffen u16 crc_tpm, crc_host; 262bbc23a07SAlexander Steffen int rc; 263bbc23a07SAlexander Steffen 264bbc23a07SAlexander Steffen rc = tpm_tis_read16(data, TPM_DATA_CSUM, &crc_tpm); 265bbc23a07SAlexander Steffen if (rc < 0) 266bbc23a07SAlexander Steffen return rc; 267bbc23a07SAlexander Steffen 268bbc23a07SAlexander Steffen /* reflect crc result, regardless of host endianness */ 269bbc23a07SAlexander Steffen crc_host = swab16(crc_ccitt(0, value, len)); 270bbc23a07SAlexander Steffen if (crc_tpm != crc_host) 271bbc23a07SAlexander Steffen return -EIO; 272bbc23a07SAlexander Steffen 273bbc23a07SAlexander Steffen return 0; 274bbc23a07SAlexander Steffen } 275bbc23a07SAlexander Steffen 276bbc23a07SAlexander Steffen /* 277bbc23a07SAlexander Steffen * Guard Time: 278bbc23a07SAlexander Steffen * After each I2C operation, the TPM might require the master to wait. 279bbc23a07SAlexander Steffen * The time period is vendor-specific and must be read from the 280bbc23a07SAlexander Steffen * TPM_I2C_INTERFACE_CAPABILITY register. 281bbc23a07SAlexander Steffen * 282bbc23a07SAlexander Steffen * Before the Guard Time is read (or after the TPM failed to send an I2C NACK), 283bbc23a07SAlexander Steffen * a Guard Time of 250µs applies. 284bbc23a07SAlexander Steffen * 285bbc23a07SAlexander Steffen * Various flags in the same register indicate if a guard time is needed: 286bbc23a07SAlexander Steffen * - SR: <I2C read with repeated start> <guard time> <I2C read> 287bbc23a07SAlexander Steffen * - RR: <I2C read> <guard time> <I2C read> 288bbc23a07SAlexander Steffen * - RW: <I2C read> <guard time> <I2C write> 289bbc23a07SAlexander Steffen * - WR: <I2C write> <guard time> <I2C read> 290bbc23a07SAlexander Steffen * - WW: <I2C write> <guard time> <I2C write> 291bbc23a07SAlexander Steffen * 292bbc23a07SAlexander Steffen * See TCG PC Client PTP Specification v1.04, 8.1.10 GUARD_TIME 293bbc23a07SAlexander Steffen */ 294bbc23a07SAlexander Steffen static int tpm_tis_i2c_init_guard_time(struct tpm_tis_i2c_phy *phy) 295bbc23a07SAlexander Steffen { 296bbc23a07SAlexander Steffen u32 i2c_caps; 297bbc23a07SAlexander Steffen int ret; 298bbc23a07SAlexander Steffen 299bbc23a07SAlexander Steffen phy->guard_time_read = true; 300bbc23a07SAlexander Steffen phy->guard_time_write = true; 301bbc23a07SAlexander Steffen phy->guard_time_min = GUARD_TIME_DEFAULT_MIN; 302bbc23a07SAlexander Steffen phy->guard_time_max = GUARD_TIME_DEFAULT_MAX; 303bbc23a07SAlexander Steffen 304bbc23a07SAlexander Steffen ret = tpm_tis_i2c_read_bytes(&phy->priv, TPM_I2C_INTERFACE_CAPABILITY, 305bbc23a07SAlexander Steffen sizeof(i2c_caps), (u8 *)&i2c_caps, 306bbc23a07SAlexander Steffen TPM_TIS_PHYS_32); 307bbc23a07SAlexander Steffen if (ret) 308bbc23a07SAlexander Steffen return ret; 309bbc23a07SAlexander Steffen 310bbc23a07SAlexander Steffen phy->guard_time_read = (i2c_caps & TPM_GUARD_TIME_RR_MASK) || 311bbc23a07SAlexander Steffen (i2c_caps & TPM_GUARD_TIME_RW_MASK); 312bbc23a07SAlexander Steffen phy->guard_time_write = (i2c_caps & TPM_GUARD_TIME_WR_MASK) || 313bbc23a07SAlexander Steffen (i2c_caps & TPM_GUARD_TIME_WW_MASK); 314bbc23a07SAlexander Steffen phy->guard_time_min = (i2c_caps & TPM_GUARD_TIME_MIN_MASK) >> 315bbc23a07SAlexander Steffen TPM_GUARD_TIME_MIN_SHIFT; 316bbc23a07SAlexander Steffen /* guard_time_max = guard_time_min * 1.2 */ 317bbc23a07SAlexander Steffen phy->guard_time_max = phy->guard_time_min + phy->guard_time_min / 5; 318bbc23a07SAlexander Steffen 319bbc23a07SAlexander Steffen return 0; 320bbc23a07SAlexander Steffen } 321bbc23a07SAlexander Steffen 322bbc23a07SAlexander Steffen static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume); 323bbc23a07SAlexander Steffen 324bbc23a07SAlexander Steffen static const struct tpm_tis_phy_ops tpm_i2c_phy_ops = { 325bbc23a07SAlexander Steffen .read_bytes = tpm_tis_i2c_read_bytes, 326bbc23a07SAlexander Steffen .write_bytes = tpm_tis_i2c_write_bytes, 327bbc23a07SAlexander Steffen .verify_crc = tpm_tis_i2c_verify_crc, 328bbc23a07SAlexander Steffen }; 329bbc23a07SAlexander Steffen 33040078327SUwe Kleine-König static int tpm_tis_i2c_probe(struct i2c_client *dev) 331bbc23a07SAlexander Steffen { 332bbc23a07SAlexander Steffen struct tpm_tis_i2c_phy *phy; 333bbc23a07SAlexander Steffen const u8 crc_enable = 1; 334bbc23a07SAlexander Steffen const u8 locality = 0; 335bbc23a07SAlexander Steffen int ret; 336bbc23a07SAlexander Steffen 337bbc23a07SAlexander Steffen phy = devm_kzalloc(&dev->dev, sizeof(struct tpm_tis_i2c_phy), 338bbc23a07SAlexander Steffen GFP_KERNEL); 339bbc23a07SAlexander Steffen if (!phy) 340bbc23a07SAlexander Steffen return -ENOMEM; 341bbc23a07SAlexander Steffen 342bbc23a07SAlexander Steffen phy->io_buf = devm_kzalloc(&dev->dev, TPM_BUFSIZE, GFP_KERNEL); 343bbc23a07SAlexander Steffen if (!phy->io_buf) 344bbc23a07SAlexander Steffen return -ENOMEM; 345bbc23a07SAlexander Steffen 3467bfda9c7SEddie James set_bit(TPM_TIS_DEFAULT_CANCELLATION, &phy->priv.flags); 347bbc23a07SAlexander Steffen phy->i2c_client = dev; 348bbc23a07SAlexander Steffen 349bbc23a07SAlexander Steffen /* must precede all communication with the tpm */ 350bbc23a07SAlexander Steffen ret = tpm_tis_i2c_init_guard_time(phy); 351bbc23a07SAlexander Steffen if (ret) 352bbc23a07SAlexander Steffen return ret; 353bbc23a07SAlexander Steffen 354bbc23a07SAlexander Steffen ret = tpm_tis_i2c_write_bytes(&phy->priv, TPM_LOC_SEL, sizeof(locality), 355bbc23a07SAlexander Steffen &locality, TPM_TIS_PHYS_8); 356bbc23a07SAlexander Steffen if (ret) 357bbc23a07SAlexander Steffen return ret; 358bbc23a07SAlexander Steffen 359bbc23a07SAlexander Steffen ret = tpm_tis_i2c_write_bytes(&phy->priv, TPM_I2C_DATA_CSUM_ENABLE, 360bbc23a07SAlexander Steffen sizeof(crc_enable), &crc_enable, 361bbc23a07SAlexander Steffen TPM_TIS_PHYS_8); 362bbc23a07SAlexander Steffen if (ret) 363bbc23a07SAlexander Steffen return ret; 364bbc23a07SAlexander Steffen 365bbc23a07SAlexander Steffen return tpm_tis_core_init(&dev->dev, &phy->priv, -1, &tpm_i2c_phy_ops, 366bbc23a07SAlexander Steffen NULL); 367bbc23a07SAlexander Steffen } 368bbc23a07SAlexander Steffen 369ed5c2f5fSUwe Kleine-König static void tpm_tis_i2c_remove(struct i2c_client *client) 370bbc23a07SAlexander Steffen { 371bbc23a07SAlexander Steffen struct tpm_chip *chip = i2c_get_clientdata(client); 372bbc23a07SAlexander Steffen 373bbc23a07SAlexander Steffen tpm_chip_unregister(chip); 374bbc23a07SAlexander Steffen tpm_tis_remove(chip); 375bbc23a07SAlexander Steffen } 376bbc23a07SAlexander Steffen 377bbc23a07SAlexander Steffen static const struct i2c_device_id tpm_tis_i2c_id[] = { 378bbc23a07SAlexander Steffen { "tpm_tis_i2c", 0 }, 379bbc23a07SAlexander Steffen {} 380bbc23a07SAlexander Steffen }; 381bbc23a07SAlexander Steffen MODULE_DEVICE_TABLE(i2c, tpm_tis_i2c_id); 382bbc23a07SAlexander Steffen 383bbc23a07SAlexander Steffen #ifdef CONFIG_OF 384bbc23a07SAlexander Steffen static const struct of_device_id of_tis_i2c_match[] = { 385bbc23a07SAlexander Steffen { .compatible = "infineon,slb9673", }, 386bbc23a07SAlexander Steffen {} 387bbc23a07SAlexander Steffen }; 388bbc23a07SAlexander Steffen MODULE_DEVICE_TABLE(of, of_tis_i2c_match); 389bbc23a07SAlexander Steffen #endif 390bbc23a07SAlexander Steffen 391bbc23a07SAlexander Steffen static struct i2c_driver tpm_tis_i2c_driver = { 392bbc23a07SAlexander Steffen .driver = { 393bbc23a07SAlexander Steffen .name = "tpm_tis_i2c", 394bbc23a07SAlexander Steffen .pm = &tpm_tis_pm, 395bbc23a07SAlexander Steffen .of_match_table = of_match_ptr(of_tis_i2c_match), 396bbc23a07SAlexander Steffen }, 39740078327SUwe Kleine-König .probe_new = tpm_tis_i2c_probe, 398bbc23a07SAlexander Steffen .remove = tpm_tis_i2c_remove, 399bbc23a07SAlexander Steffen .id_table = tpm_tis_i2c_id, 400bbc23a07SAlexander Steffen }; 401bbc23a07SAlexander Steffen module_i2c_driver(tpm_tis_i2c_driver); 402bbc23a07SAlexander Steffen 403bbc23a07SAlexander Steffen MODULE_DESCRIPTION("TPM Driver for native I2C access"); 404bbc23a07SAlexander Steffen MODULE_LICENSE("GPL"); 405