1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * STMicroelectronics TPM I2C Linux driver for TPM ST33ZP24
4 * Copyright (C) 2009 - 2016 STMicroelectronics
7 #include <linux/module.h>
10 #include <linux/acpi.h>
11 #include <linux/tpm.h>
16 #define TPM_DUMMY_BYTE 0xAA
18 struct st33zp24_i2c_phy
{
19 struct i2c_client
*client
;
20 u8 buf
[ST33ZP24_BUFSIZE
+ 1];
25 * Send byte to the TIS register according to the ST33ZP24 I2C protocol.
26 * @param: tpm_register, the tpm tis register where the data should be written
27 * @param: tpm_data, the tpm_data to write inside the tpm_register
28 * @param: tpm_size, The length of the data
29 * @return: Returns negative errno, or else the number of bytes written.
31 static int write8_reg(void *phy_id
, u8 tpm_register
, u8
*tpm_data
, int tpm_size
)
33 struct st33zp24_i2c_phy
*phy
= phy_id
;
35 phy
->buf
[0] = tpm_register
;
36 memcpy(phy
->buf
+ 1, tpm_data
, tpm_size
);
37 return i2c_master_send(phy
->client
, phy
->buf
, tpm_size
+ 1);
42 * Recv byte from the TIS register according to the ST33ZP24 I2C protocol.
43 * @param: tpm_register, the tpm tis register where the data should be read
44 * @param: tpm_data, the TPM response
45 * @param: tpm_size, tpm TPM response size to read.
46 * @return: number of byte read successfully: should be one if success.
48 static int read8_reg(void *phy_id
, u8 tpm_register
, u8
*tpm_data
, int tpm_size
)
50 struct st33zp24_i2c_phy
*phy
= phy_id
;
54 data
= TPM_DUMMY_BYTE
;
55 status
= write8_reg(phy
, tpm_register
, &data
, 1);
57 status
= i2c_master_recv(phy
->client
, tpm_data
, tpm_size
);
63 * Send byte to the TIS register according to the ST33ZP24 I2C protocol.
64 * @param: phy_id, the phy description
65 * @param: tpm_register, the tpm tis register where the data should be written
66 * @param: tpm_data, the tpm_data to write inside the tpm_register
67 * @param: tpm_size, the length of the data
68 * @return: number of byte written successfully: should be one if success.
70 static int st33zp24_i2c_send(void *phy_id
, u8 tpm_register
, u8
*tpm_data
,
73 return write8_reg(phy_id
, tpm_register
| TPM_WRITE_DIRECTION
, tpm_data
,
79 * Recv byte from the TIS register according to the ST33ZP24 I2C protocol.
80 * @param: phy_id, the phy description
81 * @param: tpm_register, the tpm tis register where the data should be read
82 * @param: tpm_data, the TPM response
83 * @param: tpm_size, tpm TPM response size to read.
84 * @return: number of byte read successfully: should be one if success.
86 static int st33zp24_i2c_recv(void *phy_id
, u8 tpm_register
, u8
*tpm_data
,
89 return read8_reg(phy_id
, tpm_register
, tpm_data
, tpm_size
);
92 static const struct st33zp24_phy_ops i2c_phy_ops
= {
93 .send
= st33zp24_i2c_send
,
94 .recv
= st33zp24_i2c_recv
,
98 * st33zp24_i2c_probe initialize the TPM device
99 * @param: client, the i2c_client description (TPM I2C description).
100 * @param: id, the i2c_device_id struct.
101 * @return: 0 in case of success.
104 static int st33zp24_i2c_probe(struct i2c_client
*client
)
106 struct st33zp24_i2c_phy
*phy
;
108 if (!i2c_check_functionality(client
->adapter
, I2C_FUNC_I2C
)) {
109 dev_info(&client
->dev
, "client not i2c capable\n");
113 phy
= devm_kzalloc(&client
->dev
, sizeof(struct st33zp24_i2c_phy
),
118 phy
->client
= client
;
120 return st33zp24_probe(phy
, &i2c_phy_ops
, &client
->dev
, client
->irq
);
124 * st33zp24_i2c_remove remove the TPM device
125 * @param: client, the i2c_client description (TPM I2C description).
126 * @return: 0 in case of success.
128 static void st33zp24_i2c_remove(struct i2c_client
*client
)
130 struct tpm_chip
*chip
= i2c_get_clientdata(client
);
132 st33zp24_remove(chip
);
135 static const struct i2c_device_id st33zp24_i2c_id
[] = {
139 MODULE_DEVICE_TABLE(i2c
, st33zp24_i2c_id
);
141 static const struct of_device_id of_st33zp24_i2c_match
[] __maybe_unused
= {
142 { .compatible
= "st,st33zp24-i2c", },
145 MODULE_DEVICE_TABLE(of
, of_st33zp24_i2c_match
);
147 static const struct acpi_device_id st33zp24_i2c_acpi_match
[] __maybe_unused
= {
151 MODULE_DEVICE_TABLE(acpi
, st33zp24_i2c_acpi_match
);
153 static SIMPLE_DEV_PM_OPS(st33zp24_i2c_ops
, st33zp24_pm_suspend
,
156 static struct i2c_driver st33zp24_i2c_driver
= {
158 .name
= TPM_ST33_I2C
,
159 .pm
= &st33zp24_i2c_ops
,
160 .of_match_table
= of_match_ptr(of_st33zp24_i2c_match
),
161 .acpi_match_table
= ACPI_PTR(st33zp24_i2c_acpi_match
),
163 .probe
= st33zp24_i2c_probe
,
164 .remove
= st33zp24_i2c_remove
,
165 .id_table
= st33zp24_i2c_id
168 module_i2c_driver(st33zp24_i2c_driver
);
170 MODULE_AUTHOR("TPM support <TPMsupport@list.st.com>");
171 MODULE_DESCRIPTION("STM TPM 1.2 I2C ST33 Driver");
172 MODULE_VERSION("1.3.0");
173 MODULE_LICENSE("GPL");