drivers/char/tpm/tpm_i2c_infineon.c
Source file repositories/reference/linux-study-clean/drivers/char/tpm/tpm_i2c_infineon.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/char/tpm/tpm_i2c_infineon.c- Extension
.c- Size
- 18371 bytes
- Lines
- 736
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/i2c.hlinux/module.hlinux/wait.htpm.h
Detected Declarations
struct tpm_inf_devenum i2c_chip_typeenum tis_accessenum tis_statusenum tis_defaultsfunction iic_tpm_readfunction iic_tpm_write_genericfunction iic_tpm_writefunction iic_tpm_write_longfunction check_localityfunction release_localityfunction request_localityfunction tpm_tis_i2c_statusfunction tpm_tis_i2c_readyfunction get_burstcountfunction wait_for_statfunction recv_datafunction tpm_tis_i2c_recvfunction tpm_tis_i2c_sendfunction tpm_tis_i2c_req_canceledfunction tpm_tis_i2c_initfunction tpm_tis_i2c_probefunction tpm_tis_i2c_remove
Annotated Snippet
struct tpm_inf_dev {
struct i2c_client *client;
int locality;
/* In addition to the data itself, the buffer must fit the 7-bit I2C
* address and the direction bit.
*/
u8 buf[TPM_I2C_INFINEON_BUFSIZE + 1];
struct tpm_chip *chip;
enum i2c_chip_type chip_type;
unsigned int adapterlimit;
};
static struct tpm_inf_dev tpm_dev;
/*
* iic_tpm_read() - read from TPM register
* @addr: register address to read from
* @buffer: provided by caller
* @len: number of bytes to read
*
* Read len bytes from TPM register and put them into
* buffer (little-endian format, i.e. first byte is put into buffer[0]).
*
* NOTE: TPM is big-endian for multi-byte values. Multi-byte
* values have to be swapped.
*
* NOTE: We can't unfortunately use the combined read/write functions
* provided by the i2c core as the TPM currently does not support the
* repeated start condition and due to it's special requirements.
* The i2c_smbus* functions do not work for this chip.
*
* Return -EIO on error, 0 on success.
*/
static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
{
struct i2c_msg msg1 = {
.addr = tpm_dev.client->addr,
.len = 1,
.buf = &addr
};
struct i2c_msg msg2 = {
.addr = tpm_dev.client->addr,
.flags = I2C_M_RD,
.len = len,
.buf = buffer
};
struct i2c_msg msgs[] = {msg1, msg2};
int rc = 0;
int count;
unsigned int msglen = len;
/* Lock the adapter for the duration of the whole sequence. */
if (!tpm_dev.client->adapter->algo->master_xfer)
return -EOPNOTSUPP;
i2c_lock_bus(tpm_dev.client->adapter, I2C_LOCK_SEGMENT);
if (tpm_dev.chip_type == SLB9645) {
/* use a combined read for newer chips
* unfortunately the smbus functions are not suitable due to
* the 32 byte limit of the smbus.
* retries should usually not be needed, but are kept just to
* be on the safe side.
*/
for (count = 0; count < MAX_COUNT; count++) {
rc = __i2c_transfer(tpm_dev.client->adapter, msgs, 2);
if (rc > 0)
break; /* break here to skip sleep */
usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
}
} else {
/* Expect to send one command message and one data message, but
* support looping over each or both if necessary.
*/
while (len > 0) {
/* slb9635 protocol should work in all cases */
for (count = 0; count < MAX_COUNT; count++) {
rc = __i2c_transfer(tpm_dev.client->adapter,
&msg1, 1);
if (rc > 0)
break; /* break here to skip sleep */
usleep_range(SLEEP_DURATION_LOW,
SLEEP_DURATION_HI);
}
if (rc <= 0)
goto out;
Annotation
- Immediate include surface: `linux/i2c.h`, `linux/module.h`, `linux/wait.h`, `tpm.h`.
- Detected declarations: `struct tpm_inf_dev`, `enum i2c_chip_type`, `enum tis_access`, `enum tis_status`, `enum tis_defaults`, `function iic_tpm_read`, `function iic_tpm_write_generic`, `function iic_tpm_write`, `function iic_tpm_write_long`, `function check_locality`.
- 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.