drivers/char/tpm/tpm_i2c_nuvoton.c
Source file repositories/reference/linux-study-clean/drivers/char/tpm/tpm_i2c_nuvoton.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/char/tpm/tpm_i2c_nuvoton.c- Extension
.c- Size
- 18514 bytes
- Lines
- 661
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/init.hlinux/module.hlinux/moduleparam.hlinux/slab.hlinux/interrupt.hlinux/wait.hlinux/i2c.hlinux/of.hlinux/property.htpm.h
Detected Declarations
struct priv_datafunction i2c_nuvoton_read_buffunction i2c_nuvoton_write_buffunction i2c_nuvoton_read_statusfunction i2c_nuvoton_write_statusfunction i2c_nuvoton_readyfunction i2c_nuvoton_get_burstcountfunction i2c_nuvoton_check_statusfunction i2c_nuvoton_wait_for_statfunction i2c_nuvoton_wait_for_data_availfunction i2c_nuvoton_recv_datafunction i2c_nuvoton_recvfunction usedfunction i2c_nuvoton_req_canceledfunction sourcefunction get_vidfunction i2c_nuvoton_probefunction i2c_nuvoton_remove
Annotated Snippet
struct priv_data {
int irq;
unsigned int intrs;
wait_queue_head_t read_queue;
};
static s32 i2c_nuvoton_read_buf(struct i2c_client *client, u8 offset, u8 size,
u8 *data)
{
s32 status;
status = i2c_smbus_read_i2c_block_data(client, offset, size, data);
dev_dbg(&client->dev,
"%s(offset=%u size=%u data=%*ph) -> sts=%d\n", __func__,
offset, size, (int)size, data, status);
return status;
}
static s32 i2c_nuvoton_write_buf(struct i2c_client *client, u8 offset, u8 size,
u8 *data)
{
s32 status;
status = i2c_smbus_write_i2c_block_data(client, offset, size, data);
dev_dbg(&client->dev,
"%s(offset=%u size=%u data=%*ph) -> sts=%d\n", __func__,
offset, size, (int)size, data, status);
return status;
}
#define TPM_STS_VALID 0x80
#define TPM_STS_COMMAND_READY 0x40
#define TPM_STS_GO 0x20
#define TPM_STS_DATA_AVAIL 0x10
#define TPM_STS_EXPECT 0x08
#define TPM_STS_RESPONSE_RETRY 0x02
#define TPM_STS_ERR_VAL 0x07 /* bit2...bit0 reads always 0 */
#define TPM_I2C_SHORT_TIMEOUT 750 /* ms */
#define TPM_I2C_LONG_TIMEOUT 2000 /* 2 sec */
/* read TPM_STS register */
static u8 i2c_nuvoton_read_status(struct tpm_chip *chip)
{
struct i2c_client *client = to_i2c_client(chip->dev.parent);
s32 status;
u8 data;
status = i2c_nuvoton_read_buf(client, TPM_STS, 1, &data);
if (status <= 0) {
dev_err(&chip->dev, "%s() error return %d\n", __func__,
status);
data = TPM_STS_ERR_VAL;
}
return data;
}
/* write byte to TPM_STS register */
static s32 i2c_nuvoton_write_status(struct i2c_client *client, u8 data)
{
s32 status;
int i;
/* this causes the current command to be aborted */
for (i = 0, status = -1; i < TPM_I2C_RETRY_COUNT && status < 0; i++) {
status = i2c_nuvoton_write_buf(client, TPM_STS, 1, &data);
if (status < 0)
usleep_range(TPM_I2C_BUS_DELAY, TPM_I2C_BUS_DELAY
+ TPM_I2C_DELAY_RANGE);
}
return status;
}
/* write commandReady to TPM_STS register */
static void i2c_nuvoton_ready(struct tpm_chip *chip)
{
struct i2c_client *client = to_i2c_client(chip->dev.parent);
s32 status;
/* this causes the current command to be aborted */
status = i2c_nuvoton_write_status(client, TPM_STS_COMMAND_READY);
if (status < 0)
dev_err(&chip->dev,
"%s() fail to write TPM_STS.commandReady\n", __func__);
}
/* read burstCount field from TPM_STS register
* return -1 on fail to read */
static int i2c_nuvoton_get_burstcount(struct i2c_client *client,
Annotation
- Immediate include surface: `linux/init.h`, `linux/module.h`, `linux/moduleparam.h`, `linux/slab.h`, `linux/interrupt.h`, `linux/wait.h`, `linux/i2c.h`, `linux/of.h`.
- Detected declarations: `struct priv_data`, `function i2c_nuvoton_read_buf`, `function i2c_nuvoton_write_buf`, `function i2c_nuvoton_read_status`, `function i2c_nuvoton_write_status`, `function i2c_nuvoton_ready`, `function i2c_nuvoton_get_burstcount`, `function i2c_nuvoton_check_status`, `function i2c_nuvoton_wait_for_stat`, `function i2c_nuvoton_wait_for_data_avail`.
- Atlas domain: Driver Families / drivers/char.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.