xref: /openbmc/linux/drivers/char/tpm/tpm_i2c_atmel.c (revision 6fa24b41)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * ATMEL I2C TPM AT97SC3204T
4  *
5  * Copyright (C) 2012 V Lab Technologies
6  *  Teddy Reed <teddy@prosauce.org>
7  * Copyright (C) 2013, Obsidian Research Corp.
8  *  Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
9  * Device driver for ATMEL I2C TPMs.
10  *
11  * Teddy Reed determined the basic I2C command flow, unlike other I2C TPM
12  * devices the raw TCG formatted TPM command data is written via I2C and then
13  * raw TCG formatted TPM command data is returned via I2C.
14  *
15  * TGC status/locality/etc functions seen in the LPC implementation do not
16  * seem to be present.
17  */
18 #include <linux/init.h>
19 #include <linux/module.h>
20 #include <linux/moduleparam.h>
21 #include <linux/slab.h>
22 #include <linux/i2c.h>
23 #include "tpm.h"
24 
25 #define I2C_DRIVER_NAME "tpm_i2c_atmel"
26 
27 #define TPM_I2C_SHORT_TIMEOUT  750     /* ms */
28 #define TPM_I2C_LONG_TIMEOUT   2000    /* 2 sec */
29 
30 #define ATMEL_STS_OK 1
31 
32 struct priv_data {
33 	size_t len;
34 	/* This is the amount we read on the first try. 25 was chosen to fit a
35 	 * fair number of read responses in the buffer so a 2nd retry can be
36 	 * avoided in small message cases. */
37 	u8 buffer[sizeof(struct tpm_header) + 25];
38 };
39 
40 static int i2c_atmel_send(struct tpm_chip *chip, u8 *buf, size_t len)
41 {
42 	struct priv_data *priv = dev_get_drvdata(&chip->dev);
43 	struct i2c_client *client = to_i2c_client(chip->dev.parent);
44 	s32 status;
45 
46 	priv->len = 0;
47 
48 	if (len <= 2)
49 		return -EIO;
50 
51 	status = i2c_master_send(client, buf, len);
52 
53 	dev_dbg(&chip->dev,
54 		"%s(buf=%*ph len=%0zx) -> sts=%d\n", __func__,
55 		(int)min_t(size_t, 64, len), buf, len, status);
56 
57 	if (status < 0)
58 		return status;
59 
60 	/* The upper layer does not support incomplete sends. */
61 	if (status != len)
62 		return -E2BIG;
63 
64 	return 0;
65 }
66 
67 static int i2c_atmel_recv(struct tpm_chip *chip, u8 *buf, size_t count)
68 {
69 	struct priv_data *priv = dev_get_drvdata(&chip->dev);
70 	struct i2c_client *client = to_i2c_client(chip->dev.parent);
71 	struct tpm_header *hdr = (struct tpm_header *)priv->buffer;
72 	u32 expected_len;
73 	int rc;
74 
75 	if (priv->len == 0)
76 		return -EIO;
77 
78 	/* Get the message size from the message header, if we didn't get the
79 	 * whole message in read_status then we need to re-read the
80 	 * message. */
81 	expected_len = be32_to_cpu(hdr->length);
82 	if (expected_len > count)
83 		return -ENOMEM;
84 
85 	if (priv->len >= expected_len) {
86 		dev_dbg(&chip->dev,
87 			"%s early(buf=%*ph count=%0zx) -> ret=%d\n", __func__,
88 			(int)min_t(size_t, 64, expected_len), buf, count,
89 			expected_len);
90 		memcpy(buf, priv->buffer, expected_len);
91 		return expected_len;
92 	}
93 
94 	rc = i2c_master_recv(client, buf, expected_len);
95 	dev_dbg(&chip->dev,
96 		"%s reread(buf=%*ph count=%0zx) -> ret=%d\n", __func__,
97 		(int)min_t(size_t, 64, expected_len), buf, count,
98 		expected_len);
99 	return rc;
100 }
101 
102 static void i2c_atmel_cancel(struct tpm_chip *chip)
103 {
104 	dev_err(&chip->dev, "TPM operation cancellation was requested, but is not supported");
105 }
106 
107 static u8 i2c_atmel_read_status(struct tpm_chip *chip)
108 {
109 	struct priv_data *priv = dev_get_drvdata(&chip->dev);
110 	struct i2c_client *client = to_i2c_client(chip->dev.parent);
111 	int rc;
112 
113 	/* The TPM fails the I2C read until it is ready, so we do the entire
114 	 * transfer here and buffer it locally. This way the common code can
115 	 * properly handle the timeouts. */
116 	priv->len = 0;
117 	memset(priv->buffer, 0, sizeof(priv->buffer));
118 
119 
120 	/* Once the TPM has completed the command the command remains readable
121 	 * until another command is issued. */
122 	rc = i2c_master_recv(client, priv->buffer, sizeof(priv->buffer));
123 	dev_dbg(&chip->dev,
124 		"%s: sts=%d", __func__, rc);
125 	if (rc <= 0)
126 		return 0;
127 
128 	priv->len = rc;
129 
130 	return ATMEL_STS_OK;
131 }
132 
133 static bool i2c_atmel_req_canceled(struct tpm_chip *chip, u8 status)
134 {
135 	return false;
136 }
137 
138 static const struct tpm_class_ops i2c_atmel = {
139 	.flags = TPM_OPS_AUTO_STARTUP,
140 	.status = i2c_atmel_read_status,
141 	.recv = i2c_atmel_recv,
142 	.send = i2c_atmel_send,
143 	.cancel = i2c_atmel_cancel,
144 	.req_complete_mask = ATMEL_STS_OK,
145 	.req_complete_val = ATMEL_STS_OK,
146 	.req_canceled = i2c_atmel_req_canceled,
147 };
148 
149 static int i2c_atmel_probe(struct i2c_client *client)
150 {
151 	struct tpm_chip *chip;
152 	struct device *dev = &client->dev;
153 	struct priv_data *priv;
154 
155 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
156 		return -ENODEV;
157 
158 	chip = tpmm_chip_alloc(dev, &i2c_atmel);
159 	if (IS_ERR(chip))
160 		return PTR_ERR(chip);
161 
162 	priv = devm_kzalloc(dev, sizeof(struct priv_data), GFP_KERNEL);
163 	if (!priv)
164 		return -ENOMEM;
165 
166 	/* Default timeouts */
167 	chip->timeout_a = msecs_to_jiffies(TPM_I2C_SHORT_TIMEOUT);
168 	chip->timeout_b = msecs_to_jiffies(TPM_I2C_LONG_TIMEOUT);
169 	chip->timeout_c = msecs_to_jiffies(TPM_I2C_SHORT_TIMEOUT);
170 	chip->timeout_d = msecs_to_jiffies(TPM_I2C_SHORT_TIMEOUT);
171 
172 	dev_set_drvdata(&chip->dev, priv);
173 
174 	/* There is no known way to probe for this device, and all version
175 	 * information seems to be read via TPM commands. Thus we rely on the
176 	 * TPM startup process in the common code to detect the device. */
177 
178 	return tpm_chip_register(chip);
179 }
180 
181 static void i2c_atmel_remove(struct i2c_client *client)
182 {
183 	struct device *dev = &(client->dev);
184 	struct tpm_chip *chip = dev_get_drvdata(dev);
185 	tpm_chip_unregister(chip);
186 }
187 
188 static const struct i2c_device_id i2c_atmel_id[] = {
189 	{I2C_DRIVER_NAME, 0},
190 	{}
191 };
192 MODULE_DEVICE_TABLE(i2c, i2c_atmel_id);
193 
194 #ifdef CONFIG_OF
195 static const struct of_device_id i2c_atmel_of_match[] = {
196 	{.compatible = "atmel,at97sc3204t"},
197 	{},
198 };
199 MODULE_DEVICE_TABLE(of, i2c_atmel_of_match);
200 #endif
201 
202 static SIMPLE_DEV_PM_OPS(i2c_atmel_pm_ops, tpm_pm_suspend, tpm_pm_resume);
203 
204 static struct i2c_driver i2c_atmel_driver = {
205 	.id_table = i2c_atmel_id,
206 	.probe = i2c_atmel_probe,
207 	.remove = i2c_atmel_remove,
208 	.driver = {
209 		.name = I2C_DRIVER_NAME,
210 		.pm = &i2c_atmel_pm_ops,
211 		.of_match_table = of_match_ptr(i2c_atmel_of_match),
212 	},
213 };
214 
215 module_i2c_driver(i2c_atmel_driver);
216 
217 MODULE_AUTHOR("Jason Gunthorpe <jgunthorpe@obsidianresearch.com>");
218 MODULE_DESCRIPTION("Atmel TPM I2C Driver");
219 MODULE_LICENSE("GPL");
220