drivers/char/tpm/tpm_tis_i2c.c
Source file repositories/reference/linux-study-clean/drivers/char/tpm/tpm_tis_i2c.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/char/tpm/tpm_tis_i2c.c- Extension
.c- Size
- 10874 bytes
- Lines
- 407
- Domain
- Driver Families
- Bucket
- drivers/char
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/i2c.hlinux/crc-ccitt.htpm_tis_core.h
Detected Declarations
struct tpm_tis_i2c_phyfunction to_tpm_tis_i2c_phyfunction TPM_ACCESSfunction tpm_tis_i2c_retry_transfer_until_ackfunction tpm_tis_i2c_sanity_check_readfunction tpm_tis_i2c_read_bytesfunction tpm_tis_i2c_write_bytesfunction tpm_tis_i2c_verify_crcfunction readfunction tpm_tis_i2c_probefunction tpm_tis_i2c_remove
Annotated Snippet
struct tpm_tis_i2c_phy {
struct tpm_tis_data priv;
struct i2c_client *i2c_client;
bool guard_time_read;
bool guard_time_write;
u16 guard_time_min;
u16 guard_time_max;
u8 *io_buf;
};
static inline struct tpm_tis_i2c_phy *
to_tpm_tis_i2c_phy(struct tpm_tis_data *data)
{
return container_of(data, struct tpm_tis_i2c_phy, priv);
}
/*
* 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)
{
addr &= TPM_TIS_REGISTER_MASK;
switch (addr) {
case TPM_ACCESS(0):
return TPM_I2C_ACCESS;
case TPM_LOC_SEL:
return TPM_I2C_LOC_SEL;
case TPM_DID_VID(0):
return TPM_I2C_DID_VID;
case TPM_RID(0):
return TPM_I2C_RID;
default:
return addr;
}
}
static int tpm_tis_i2c_retry_transfer_until_ack(struct tpm_tis_data *data,
struct i2c_msg *msg)
{
struct tpm_tis_i2c_phy *phy = to_tpm_tis_i2c_phy(data);
bool guard_time;
int i = 0;
int ret;
if (msg->flags & I2C_M_RD)
guard_time = phy->guard_time_read;
else
guard_time = phy->guard_time_write;
do {
ret = i2c_transfer(phy->i2c_client->adapter, msg, 1);
if (ret < 0)
usleep_range(GUARD_TIME_ERR_MIN, GUARD_TIME_ERR_MAX);
else if (guard_time)
usleep_range(phy->guard_time_min, phy->guard_time_max);
/* retry on TPM NACK */
} while (ret < 0 && i++ < TPM_RETRY);
return ret;
}
/* 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)
{
u32 zero_mask;
u32 value;
switch (len) {
case sizeof(u8):
value = buf[0];
break;
case sizeof(u16):
value = le16_to_cpup((__le16 *)buf);
break;
case sizeof(u32):
value = le32_to_cpup((__le32 *)buf);
Annotation
- Immediate include surface: `linux/i2c.h`, `linux/crc-ccitt.h`, `tpm_tis_core.h`.
- Detected declarations: `struct tpm_tis_i2c_phy`, `function to_tpm_tis_i2c_phy`, `function TPM_ACCESS`, `function tpm_tis_i2c_retry_transfer_until_ack`, `function tpm_tis_i2c_sanity_check_read`, `function tpm_tis_i2c_read_bytes`, `function tpm_tis_i2c_write_bytes`, `function tpm_tis_i2c_verify_crc`, `function read`, `function tpm_tis_i2c_probe`.
- Atlas domain: Driver Families / drivers/char.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.