linux/drivers/char/tpm/tpm_tis_i2c.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2014-2021 Nuvoton Technology corporation
 * Copyright (C) 2019-2022 Infineon Technologies AG
 *
 * This device driver implements the TPM interface as defined in the TCG PC
 * Client Platform TPM Profile (PTP) Specification for TPM 2.0 v1.04
 * Revision 14.
 *
 * It is based on the tpm_tis_spi device driver.
 */

#include <linux/i2c.h>
#include <linux/crc-ccitt.h>
#include "tpm_tis_core.h"

/* TPM registers */
#define TPM_I2C_LOC_SEL
#define TPM_I2C_ACCESS
#define TPM_I2C_INTERFACE_CAPABILITY
#define TPM_I2C_DEVICE_ADDRESS
#define TPM_I2C_DATA_CSUM_ENABLE
#define TPM_DATA_CSUM
#define TPM_I2C_DID_VID
#define TPM_I2C_RID

/* TIS-compatible register address to avoid clash with TPM_ACCESS (0x00) */
#define TPM_LOC_SEL

/* Mask to extract the I2C register from TIS register addresses */
#define TPM_TIS_REGISTER_MASK

/* Default Guard Time of 250µs until interface capability register is read */
#define GUARD_TIME_DEFAULT_MIN
#define GUARD_TIME_DEFAULT_MAX

/* Guard Time of 250µs after I2C slave NACK */
#define GUARD_TIME_ERR_MIN
#define GUARD_TIME_ERR_MAX

/* Guard Time bit masks; SR is repeated start, RW is read then write, etc. */
#define TPM_GUARD_TIME_SR_MASK
#define TPM_GUARD_TIME_RR_MASK
#define TPM_GUARD_TIME_RW_MASK
#define TPM_GUARD_TIME_WR_MASK
#define TPM_GUARD_TIME_WW_MASK
#define TPM_GUARD_TIME_MIN_MASK
#define TPM_GUARD_TIME_MIN_SHIFT

/* Masks with bits that must be read zero */
#define TPM_ACCESS_READ_ZERO
#define TPM_INT_ENABLE_ZERO
#define TPM_STS_READ_ZERO
#define TPM_INTF_CAPABILITY_ZERO
#define TPM_I2C_INTERFACE_CAPABILITY_ZERO

struct tpm_tis_i2c_phy {};

static inline struct tpm_tis_i2c_phy *
to_tpm_tis_i2c_phy(struct tpm_tis_data *data)
{}

/*
 * tpm_tis_core uses the register addresses as defined in Table 19 "Allocation
 * of Register Space for FIFO TPM Access" of the TCG PC Client PTP
 * Specification. In order for this code to work together with tpm_tis_core,
 * those addresses need to mapped to the registers defined for I2C TPMs in
 * Table 51 "I2C-TPM Register Overview".
 *
 * For most addresses this can be done by simply stripping off the locality
 * information from the address. A few addresses need to be mapped explicitly,
 * since the corresponding I2C registers have been moved around. TPM_LOC_SEL is
 * only defined for I2C TPMs and is also mapped explicitly here to distinguish
 * it from TPM_ACCESS(0).
 *
 * Locality information is ignored, since this driver assumes exclusive access
 * to the TPM and always uses locality 0.
 */
static u8 tpm_tis_i2c_address_to_register(u32 addr)
{}

static int tpm_tis_i2c_retry_transfer_until_ack(struct tpm_tis_data *data,
						struct i2c_msg *msg)
{}

/* Check that bits which must be read zero are not set */
static int tpm_tis_i2c_sanity_check_read(u8 reg, u16 len, u8 *buf)
{}

static int tpm_tis_i2c_read_bytes(struct tpm_tis_data *data, u32 addr, u16 len,
				  u8 *result, enum tpm_tis_io_mode io_mode)
{}

static int tpm_tis_i2c_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len,
				   const u8 *value,
				   enum tpm_tis_io_mode io_mode)
{}

static int tpm_tis_i2c_verify_crc(struct tpm_tis_data *data, size_t len,
				  const u8 *value)
{}

/*
 * Guard Time:
 * After each I2C operation, the TPM might require the master to wait.
 * The time period is vendor-specific and must be read from the
 * TPM_I2C_INTERFACE_CAPABILITY register.
 *
 * Before the Guard Time is read (or after the TPM failed to send an I2C NACK),
 * a Guard Time of 250µs applies.
 *
 * Various flags in the same register indicate if a guard time is needed:
 *  - SR: <I2C read with repeated start> <guard time> <I2C read>
 *  - RR: <I2C read> <guard time> <I2C read>
 *  - RW: <I2C read> <guard time> <I2C write>
 *  - WR: <I2C write> <guard time> <I2C read>
 *  - WW: <I2C write> <guard time> <I2C write>
 *
 * See TCG PC Client PTP Specification v1.04, 8.1.10 GUARD_TIME
 */
static int tpm_tis_i2c_init_guard_time(struct tpm_tis_i2c_phy *phy)
{}

static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume);

static const struct tpm_tis_phy_ops tpm_i2c_phy_ops =;

static int tpm_tis_i2c_probe(struct i2c_client *dev)
{}

static void tpm_tis_i2c_remove(struct i2c_client *client)
{}

static const struct i2c_device_id tpm_tis_i2c_id[] =;
MODULE_DEVICE_TABLE(i2c, tpm_tis_i2c_id);

#ifdef CONFIG_OF
static const struct of_device_id of_tis_i2c_match[] =;
MODULE_DEVICE_TABLE(of, of_tis_i2c_match);
#endif

static struct i2c_driver tpm_tis_i2c_driver =;
module_i2c_driver();

MODULE_DESCRIPTION();
MODULE_LICENSE();