diff options
author | Jason Gunthorpe <jgunthorpe@obsidianresearch.com> | 2013-10-06 14:43:13 -0400 |
---|---|---|
committer | Peter Huewe <peterhuewe@gmx.de> | 2013-10-22 13:43:04 -0400 |
commit | 4c336e4b1556f4b722ba597bc6e3df786968a600 (patch) | |
tree | 06c87151784a45fa4ae7beb7c0121fd045b469a1 /drivers/char/tpm/tpm_i2c_nuvoton.c | |
parent | 187eea0c353abd4ffa3a9cc86a660af9605fcb10 (diff) |
tpm: Add support for the Nuvoton NPCT501 I2C TPM
This chip is/was also branded as a Winbond WPCT301.
Originally written by Dan Morav <dmorav@nuvoton.com> and posted to LKML:
https://lkml.org/lkml/2011/9/7/206
The original posting was not merged, I have taken it as a
starting point, forward ported, tested and revised the driver:
- Rework interrupt handling to work properly with level triggered
interrupts. The old version just locked up.
- Synchronize various items with Peter Huewe's Infineon driver:
* Add durations/timeouts sysfs calls
* Remove I2C device auto-detection
* Don't fiddle with chip->release
* Call tpm_dev_vendor_release in the probe error path
* Use MODULE_DEVICE_TABLE for the I2C ids
* Provide OF compatible strings for DT support
* Use SIMPLE_DEV_PM_OPS
* Use module_i2c_driver
- checkpatch cleanups
- Testing on ARM Kirkwood with GPIO interrupts, with this device tree:
tpm@57 {
compatible = "nuvoton,npct501";
reg = <0x57>;
interrupt-parent = <&gpio1>;
interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
};
Signed-off-by: Dan Morav <dmorav@nuvoton.com>
[jgg: revised and tested]
Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
[phuewe: minor whitespace changes, fixed module name in kconfig]
Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
Diffstat (limited to 'drivers/char/tpm/tpm_i2c_nuvoton.c')
-rw-r--r-- | drivers/char/tpm/tpm_i2c_nuvoton.c | 710 |
1 files changed, 710 insertions, 0 deletions
diff --git a/drivers/char/tpm/tpm_i2c_nuvoton.c b/drivers/char/tpm/tpm_i2c_nuvoton.c new file mode 100644 index 000000000000..6276fea01ff0 --- /dev/null +++ b/drivers/char/tpm/tpm_i2c_nuvoton.c | |||
@@ -0,0 +1,710 @@ | |||
1 | /****************************************************************************** | ||
2 | * Nuvoton TPM I2C Device Driver Interface for WPCT301/NPCT501, | ||
3 | * based on the TCG TPM Interface Spec version 1.2. | ||
4 | * Specifications at www.trustedcomputinggroup.org | ||
5 | * | ||
6 | * Copyright (C) 2011, Nuvoton Technology Corporation. | ||
7 | * Dan Morav <dan.morav@nuvoton.com> | ||
8 | * Copyright (C) 2013, Obsidian Research Corp. | ||
9 | * Jason Gunthorpe <jgunthorpe@obsidianresearch.com> | ||
10 | * | ||
11 | * This program is free software: you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation, either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program. If not, see http://www.gnu.org/licenses/>. | ||
23 | * | ||
24 | * Nuvoton contact information: APC.Support@nuvoton.com | ||
25 | *****************************************************************************/ | ||
26 | |||
27 | #include <linux/init.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/moduleparam.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/interrupt.h> | ||
32 | #include <linux/wait.h> | ||
33 | #include <linux/i2c.h> | ||
34 | #include "tpm.h" | ||
35 | |||
36 | /* I2C interface offsets */ | ||
37 | #define TPM_STS 0x00 | ||
38 | #define TPM_BURST_COUNT 0x01 | ||
39 | #define TPM_DATA_FIFO_W 0x20 | ||
40 | #define TPM_DATA_FIFO_R 0x40 | ||
41 | #define TPM_VID_DID_RID 0x60 | ||
42 | /* TPM command header size */ | ||
43 | #define TPM_HEADER_SIZE 10 | ||
44 | #define TPM_RETRY 5 | ||
45 | /* | ||
46 | * I2C bus device maximum buffer size w/o counting I2C address or command | ||
47 | * i.e. max size required for I2C write is 34 = addr, command, 32 bytes data | ||
48 | */ | ||
49 | #define TPM_I2C_MAX_BUF_SIZE 32 | ||
50 | #define TPM_I2C_RETRY_COUNT 32 | ||
51 | #define TPM_I2C_BUS_DELAY 1 /* msec */ | ||
52 | #define TPM_I2C_RETRY_DELAY_SHORT 2 /* msec */ | ||
53 | #define TPM_I2C_RETRY_DELAY_LONG 10 /* msec */ | ||
54 | |||
55 | #define I2C_DRIVER_NAME "tpm_i2c_nuvoton" | ||
56 | |||
57 | struct priv_data { | ||
58 | unsigned int intrs; | ||
59 | }; | ||
60 | |||
61 | static s32 i2c_nuvoton_read_buf(struct i2c_client *client, u8 offset, u8 size, | ||
62 | u8 *data) | ||
63 | { | ||
64 | s32 status; | ||
65 | |||
66 | status = i2c_smbus_read_i2c_block_data(client, offset, size, data); | ||
67 | dev_dbg(&client->dev, | ||
68 | "%s(offset=%u size=%u data=%*ph) -> sts=%d\n", __func__, | ||
69 | offset, size, (int)size, data, status); | ||
70 | return status; | ||
71 | } | ||
72 | |||
73 | static s32 i2c_nuvoton_write_buf(struct i2c_client *client, u8 offset, u8 size, | ||
74 | u8 *data) | ||
75 | { | ||
76 | s32 status; | ||
77 | |||
78 | status = i2c_smbus_write_i2c_block_data(client, offset, size, data); | ||
79 | dev_dbg(&client->dev, | ||
80 | "%s(offset=%u size=%u data=%*ph) -> sts=%d\n", __func__, | ||
81 | offset, size, (int)size, data, status); | ||
82 | return status; | ||
83 | } | ||
84 | |||
85 | #define TPM_STS_VALID 0x80 | ||
86 | #define TPM_STS_COMMAND_READY 0x40 | ||
87 | #define TPM_STS_GO 0x20 | ||
88 | #define TPM_STS_DATA_AVAIL 0x10 | ||
89 | #define TPM_STS_EXPECT 0x08 | ||
90 | #define TPM_STS_RESPONSE_RETRY 0x02 | ||
91 | #define TPM_STS_ERR_VAL 0x07 /* bit2...bit0 reads always 0 */ | ||
92 | |||
93 | #define TPM_I2C_SHORT_TIMEOUT 750 /* ms */ | ||
94 | #define TPM_I2C_LONG_TIMEOUT 2000 /* 2 sec */ | ||
95 | |||
96 | /* read TPM_STS register */ | ||
97 | static u8 i2c_nuvoton_read_status(struct tpm_chip *chip) | ||
98 | { | ||
99 | struct i2c_client *client = to_i2c_client(chip->dev); | ||
100 | s32 status; | ||
101 | u8 data; | ||
102 | |||
103 | status = i2c_nuvoton_read_buf(client, TPM_STS, 1, &data); | ||
104 | if (status <= 0) { | ||
105 | dev_err(chip->dev, "%s() error return %d\n", __func__, | ||
106 | status); | ||
107 | data = TPM_STS_ERR_VAL; | ||
108 | } | ||
109 | |||
110 | return data; | ||
111 | } | ||
112 | |||
113 | /* write byte to TPM_STS register */ | ||
114 | static s32 i2c_nuvoton_write_status(struct i2c_client *client, u8 data) | ||
115 | { | ||
116 | s32 status; | ||
117 | int i; | ||
118 | |||
119 | /* this causes the current command to be aborted */ | ||
120 | for (i = 0, status = -1; i < TPM_I2C_RETRY_COUNT && status < 0; i++) { | ||
121 | status = i2c_nuvoton_write_buf(client, TPM_STS, 1, &data); | ||
122 | msleep(TPM_I2C_BUS_DELAY); | ||
123 | } | ||
124 | return status; | ||
125 | } | ||
126 | |||
127 | /* write commandReady to TPM_STS register */ | ||
128 | static void i2c_nuvoton_ready(struct tpm_chip *chip) | ||
129 | { | ||
130 | struct i2c_client *client = to_i2c_client(chip->dev); | ||
131 | s32 status; | ||
132 | |||
133 | /* this causes the current command to be aborted */ | ||
134 | status = i2c_nuvoton_write_status(client, TPM_STS_COMMAND_READY); | ||
135 | if (status < 0) | ||
136 | dev_err(chip->dev, | ||
137 | "%s() fail to write TPM_STS.commandReady\n", __func__); | ||
138 | } | ||
139 | |||
140 | /* read burstCount field from TPM_STS register | ||
141 | * return -1 on fail to read */ | ||
142 | static int i2c_nuvoton_get_burstcount(struct i2c_client *client, | ||
143 | struct tpm_chip *chip) | ||
144 | { | ||
145 | unsigned long stop = jiffies + chip->vendor.timeout_d; | ||
146 | s32 status; | ||
147 | int burst_count = -1; | ||
148 | u8 data; | ||
149 | |||
150 | /* wait for burstcount to be non-zero */ | ||
151 | do { | ||
152 | /* in I2C burstCount is 1 byte */ | ||
153 | status = i2c_nuvoton_read_buf(client, TPM_BURST_COUNT, 1, | ||
154 | &data); | ||
155 | if (status > 0 && data > 0) { | ||
156 | burst_count = min_t(u8, TPM_I2C_MAX_BUF_SIZE, data); | ||
157 | break; | ||
158 | } | ||
159 | msleep(TPM_I2C_BUS_DELAY); | ||
160 | } while (time_before(jiffies, stop)); | ||
161 | |||
162 | return burst_count; | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * WPCT301/NPCT501 SINT# supports only dataAvail | ||
167 | * any call to this function which is not waiting for dataAvail will | ||
168 | * set queue to NULL to avoid waiting for interrupt | ||
169 | */ | ||
170 | static bool i2c_nuvoton_check_status(struct tpm_chip *chip, u8 mask, u8 value) | ||
171 | { | ||
172 | u8 status = i2c_nuvoton_read_status(chip); | ||
173 | return (status != TPM_STS_ERR_VAL) && ((status & mask) == value); | ||
174 | } | ||
175 | |||
176 | static int i2c_nuvoton_wait_for_stat(struct tpm_chip *chip, u8 mask, u8 value, | ||
177 | u32 timeout, wait_queue_head_t *queue) | ||
178 | { | ||
179 | if (chip->vendor.irq && queue) { | ||
180 | s32 rc; | ||
181 | DEFINE_WAIT(wait); | ||
182 | struct priv_data *priv = chip->vendor.priv; | ||
183 | unsigned int cur_intrs = priv->intrs; | ||
184 | |||
185 | enable_irq(chip->vendor.irq); | ||
186 | rc = wait_event_interruptible_timeout(*queue, | ||
187 | cur_intrs != priv->intrs, | ||
188 | timeout); | ||
189 | if (rc > 0) | ||
190 | return 0; | ||
191 | /* At this point we know that the SINT pin is asserted, so we | ||
192 | * do not need to do i2c_nuvoton_check_status */ | ||
193 | } else { | ||
194 | unsigned long ten_msec, stop; | ||
195 | bool status_valid; | ||
196 | |||
197 | /* check current status */ | ||
198 | status_valid = i2c_nuvoton_check_status(chip, mask, value); | ||
199 | if (status_valid) | ||
200 | return 0; | ||
201 | |||
202 | /* use polling to wait for the event */ | ||
203 | ten_msec = jiffies + msecs_to_jiffies(TPM_I2C_RETRY_DELAY_LONG); | ||
204 | stop = jiffies + timeout; | ||
205 | do { | ||
206 | if (time_before(jiffies, ten_msec)) | ||
207 | msleep(TPM_I2C_RETRY_DELAY_SHORT); | ||
208 | else | ||
209 | msleep(TPM_I2C_RETRY_DELAY_LONG); | ||
210 | status_valid = i2c_nuvoton_check_status(chip, mask, | ||
211 | value); | ||
212 | if (status_valid) | ||
213 | return 0; | ||
214 | } while (time_before(jiffies, stop)); | ||
215 | } | ||
216 | dev_err(chip->dev, "%s(%02x, %02x) -> timeout\n", __func__, mask, | ||
217 | value); | ||
218 | return -ETIMEDOUT; | ||
219 | } | ||
220 | |||
221 | /* wait for dataAvail field to be set in the TPM_STS register */ | ||
222 | static int i2c_nuvoton_wait_for_data_avail(struct tpm_chip *chip, u32 timeout, | ||
223 | wait_queue_head_t *queue) | ||
224 | { | ||
225 | return i2c_nuvoton_wait_for_stat(chip, | ||
226 | TPM_STS_DATA_AVAIL | TPM_STS_VALID, | ||
227 | TPM_STS_DATA_AVAIL | TPM_STS_VALID, | ||
228 | timeout, queue); | ||
229 | } | ||
230 | |||
231 | /* Read @count bytes into @buf from TPM_RD_FIFO register */ | ||
232 | static int i2c_nuvoton_recv_data(struct i2c_client *client, | ||
233 | struct tpm_chip *chip, u8 *buf, size_t count) | ||
234 | { | ||
235 | s32 rc; | ||
236 | int burst_count, bytes2read, size = 0; | ||
237 | |||
238 | while (size < count && | ||
239 | i2c_nuvoton_wait_for_data_avail(chip, | ||
240 | chip->vendor.timeout_c, | ||
241 | &chip->vendor.read_queue) == 0) { | ||
242 | burst_count = i2c_nuvoton_get_burstcount(client, chip); | ||
243 | if (burst_count < 0) { | ||
244 | dev_err(chip->dev, | ||
245 | "%s() fail to read burstCount=%d\n", __func__, | ||
246 | burst_count); | ||
247 | return -EIO; | ||
248 | } | ||
249 | bytes2read = min_t(size_t, burst_count, count - size); | ||
250 | rc = i2c_nuvoton_read_buf(client, TPM_DATA_FIFO_R, | ||
251 | bytes2read, &buf[size]); | ||
252 | if (rc < 0) { | ||
253 | dev_err(chip->dev, | ||
254 | "%s() fail on i2c_nuvoton_read_buf()=%d\n", | ||
255 | __func__, rc); | ||
256 | return -EIO; | ||
257 | } | ||
258 | dev_dbg(chip->dev, "%s(%d):", __func__, bytes2read); | ||
259 | size += bytes2read; | ||
260 | } | ||
261 | |||
262 | return size; | ||
263 | } | ||
264 | |||
265 | /* Read TPM command results */ | ||
266 | static int i2c_nuvoton_recv(struct tpm_chip *chip, u8 *buf, size_t count) | ||
267 | { | ||
268 | struct device *dev = chip->dev; | ||
269 | struct i2c_client *client = to_i2c_client(dev); | ||
270 | s32 rc; | ||
271 | int expected, status, burst_count, retries, size = 0; | ||
272 | |||
273 | if (count < TPM_HEADER_SIZE) { | ||
274 | i2c_nuvoton_ready(chip); /* return to idle */ | ||
275 | dev_err(dev, "%s() count < header size\n", __func__); | ||
276 | return -EIO; | ||
277 | } | ||
278 | for (retries = 0; retries < TPM_RETRY; retries++) { | ||
279 | if (retries > 0) { | ||
280 | /* if this is not the first trial, set responseRetry */ | ||
281 | i2c_nuvoton_write_status(client, | ||
282 | TPM_STS_RESPONSE_RETRY); | ||
283 | } | ||
284 | /* | ||
285 | * read first available (> 10 bytes), including: | ||
286 | * tag, paramsize, and result | ||
287 | */ | ||
288 | status = i2c_nuvoton_wait_for_data_avail( | ||
289 | chip, chip->vendor.timeout_c, &chip->vendor.read_queue); | ||
290 | if (status != 0) { | ||
291 | dev_err(dev, "%s() timeout on dataAvail\n", __func__); | ||
292 | size = -ETIMEDOUT; | ||
293 | continue; | ||
294 | } | ||
295 | burst_count = i2c_nuvoton_get_burstcount(client, chip); | ||
296 | if (burst_count < 0) { | ||
297 | dev_err(dev, "%s() fail to get burstCount\n", __func__); | ||
298 | size = -EIO; | ||
299 | continue; | ||
300 | } | ||
301 | size = i2c_nuvoton_recv_data(client, chip, buf, | ||
302 | burst_count); | ||
303 | if (size < TPM_HEADER_SIZE) { | ||
304 | dev_err(dev, "%s() fail to read header\n", __func__); | ||
305 | size = -EIO; | ||
306 | continue; | ||
307 | } | ||
308 | /* | ||
309 | * convert number of expected bytes field from big endian 32 bit | ||
310 | * to machine native | ||
311 | */ | ||
312 | expected = be32_to_cpu(*(__be32 *) (buf + 2)); | ||
313 | if (expected > count) { | ||
314 | dev_err(dev, "%s() expected > count\n", __func__); | ||
315 | size = -EIO; | ||
316 | continue; | ||
317 | } | ||
318 | rc = i2c_nuvoton_recv_data(client, chip, &buf[size], | ||
319 | expected - size); | ||
320 | size += rc; | ||
321 | if (rc < 0 || size < expected) { | ||
322 | dev_err(dev, "%s() fail to read remainder of result\n", | ||
323 | __func__); | ||
324 | size = -EIO; | ||
325 | continue; | ||
326 | } | ||
327 | if (i2c_nuvoton_wait_for_stat( | ||
328 | chip, TPM_STS_VALID | TPM_STS_DATA_AVAIL, | ||
329 | TPM_STS_VALID, chip->vendor.timeout_c, | ||
330 | NULL)) { | ||
331 | dev_err(dev, "%s() error left over data\n", __func__); | ||
332 | size = -ETIMEDOUT; | ||
333 | continue; | ||
334 | } | ||
335 | break; | ||
336 | } | ||
337 | i2c_nuvoton_ready(chip); | ||
338 | dev_dbg(chip->dev, "%s() -> %d\n", __func__, size); | ||
339 | return size; | ||
340 | } | ||
341 | |||
342 | /* | ||
343 | * Send TPM command. | ||
344 | * | ||
345 | * If interrupts are used (signaled by an irq set in the vendor structure) | ||
346 | * tpm.c can skip polling for the data to be available as the interrupt is | ||
347 | * waited for here | ||
348 | */ | ||
349 | static int i2c_nuvoton_send(struct tpm_chip *chip, u8 *buf, size_t len) | ||
350 | { | ||
351 | struct device *dev = chip->dev; | ||
352 | struct i2c_client *client = to_i2c_client(dev); | ||
353 | u32 ordinal; | ||
354 | size_t count = 0; | ||
355 | int burst_count, bytes2write, retries, rc = -EIO; | ||
356 | |||
357 | for (retries = 0; retries < TPM_RETRY; retries++) { | ||
358 | i2c_nuvoton_ready(chip); | ||
359 | if (i2c_nuvoton_wait_for_stat(chip, TPM_STS_COMMAND_READY, | ||
360 | TPM_STS_COMMAND_READY, | ||
361 | chip->vendor.timeout_b, NULL)) { | ||
362 | dev_err(dev, "%s() timeout on commandReady\n", | ||
363 | __func__); | ||
364 | rc = -EIO; | ||
365 | continue; | ||
366 | } | ||
367 | rc = 0; | ||
368 | while (count < len - 1) { | ||
369 | burst_count = i2c_nuvoton_get_burstcount(client, | ||
370 | chip); | ||
371 | if (burst_count < 0) { | ||
372 | dev_err(dev, "%s() fail get burstCount\n", | ||
373 | __func__); | ||
374 | rc = -EIO; | ||
375 | break; | ||
376 | } | ||
377 | bytes2write = min_t(size_t, burst_count, | ||
378 | len - 1 - count); | ||
379 | rc = i2c_nuvoton_write_buf(client, TPM_DATA_FIFO_W, | ||
380 | bytes2write, &buf[count]); | ||
381 | if (rc < 0) { | ||
382 | dev_err(dev, "%s() fail i2cWriteBuf\n", | ||
383 | __func__); | ||
384 | break; | ||
385 | } | ||
386 | dev_dbg(dev, "%s(%d):", __func__, bytes2write); | ||
387 | count += bytes2write; | ||
388 | rc = i2c_nuvoton_wait_for_stat(chip, | ||
389 | TPM_STS_VALID | | ||
390 | TPM_STS_EXPECT, | ||
391 | TPM_STS_VALID | | ||
392 | TPM_STS_EXPECT, | ||
393 | chip->vendor.timeout_c, | ||
394 | NULL); | ||
395 | if (rc < 0) { | ||
396 | dev_err(dev, "%s() timeout on Expect\n", | ||
397 | __func__); | ||
398 | rc = -ETIMEDOUT; | ||
399 | break; | ||
400 | } | ||
401 | } | ||
402 | if (rc < 0) | ||
403 | continue; | ||
404 | |||
405 | /* write last byte */ | ||
406 | rc = i2c_nuvoton_write_buf(client, TPM_DATA_FIFO_W, 1, | ||
407 | &buf[count]); | ||
408 | if (rc < 0) { | ||
409 | dev_err(dev, "%s() fail to write last byte\n", | ||
410 | __func__); | ||
411 | rc = -EIO; | ||
412 | continue; | ||
413 | } | ||
414 | dev_dbg(dev, "%s(last): %02x", __func__, buf[count]); | ||
415 | rc = i2c_nuvoton_wait_for_stat(chip, | ||
416 | TPM_STS_VALID | TPM_STS_EXPECT, | ||
417 | TPM_STS_VALID, | ||
418 | chip->vendor.timeout_c, NULL); | ||
419 | if (rc) { | ||
420 | dev_err(dev, "%s() timeout on Expect to clear\n", | ||
421 | __func__); | ||
422 | rc = -ETIMEDOUT; | ||
423 | continue; | ||
424 | } | ||
425 | break; | ||
426 | } | ||
427 | if (rc < 0) { | ||
428 | /* retries == TPM_RETRY */ | ||
429 | i2c_nuvoton_ready(chip); | ||
430 | return rc; | ||
431 | } | ||
432 | /* execute the TPM command */ | ||
433 | rc = i2c_nuvoton_write_status(client, TPM_STS_GO); | ||
434 | if (rc < 0) { | ||
435 | dev_err(dev, "%s() fail to write Go\n", __func__); | ||
436 | i2c_nuvoton_ready(chip); | ||
437 | return rc; | ||
438 | } | ||
439 | ordinal = be32_to_cpu(*((__be32 *) (buf + 6))); | ||
440 | rc = i2c_nuvoton_wait_for_data_avail(chip, | ||
441 | tpm_calc_ordinal_duration(chip, | ||
442 | ordinal), | ||
443 | &chip->vendor.read_queue); | ||
444 | if (rc) { | ||
445 | dev_err(dev, "%s() timeout command duration\n", __func__); | ||
446 | i2c_nuvoton_ready(chip); | ||
447 | return rc; | ||
448 | } | ||
449 | |||
450 | dev_dbg(dev, "%s() -> %zd\n", __func__, len); | ||
451 | return len; | ||
452 | } | ||
453 | |||
454 | static bool i2c_nuvoton_req_canceled(struct tpm_chip *chip, u8 status) | ||
455 | { | ||
456 | return (status == TPM_STS_COMMAND_READY); | ||
457 | } | ||
458 | |||
459 | static const struct file_operations i2c_nuvoton_ops = { | ||
460 | .owner = THIS_MODULE, | ||
461 | .llseek = no_llseek, | ||
462 | .open = tpm_open, | ||
463 | .read = tpm_read, | ||
464 | .write = tpm_write, | ||
465 | .release = tpm_release, | ||
466 | }; | ||
467 | |||
468 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); | ||
469 | static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); | ||
470 | static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); | ||
471 | static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); | ||
472 | static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); | ||
473 | static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); | ||
474 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); | ||
475 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); | ||
476 | static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); | ||
477 | static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); | ||
478 | |||
479 | static struct attribute *i2c_nuvoton_attrs[] = { | ||
480 | &dev_attr_pubek.attr, | ||
481 | &dev_attr_pcrs.attr, | ||
482 | &dev_attr_enabled.attr, | ||
483 | &dev_attr_active.attr, | ||
484 | &dev_attr_owned.attr, | ||
485 | &dev_attr_temp_deactivated.attr, | ||
486 | &dev_attr_caps.attr, | ||
487 | &dev_attr_cancel.attr, | ||
488 | &dev_attr_durations.attr, | ||
489 | &dev_attr_timeouts.attr, | ||
490 | NULL, | ||
491 | }; | ||
492 | |||
493 | static struct attribute_group i2c_nuvoton_attr_grp = { | ||
494 | .attrs = i2c_nuvoton_attrs | ||
495 | }; | ||
496 | |||
497 | static const struct tpm_vendor_specific tpm_i2c = { | ||
498 | .status = i2c_nuvoton_read_status, | ||
499 | .recv = i2c_nuvoton_recv, | ||
500 | .send = i2c_nuvoton_send, | ||
501 | .cancel = i2c_nuvoton_ready, | ||
502 | .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, | ||
503 | .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, | ||
504 | .req_canceled = i2c_nuvoton_req_canceled, | ||
505 | .attr_group = &i2c_nuvoton_attr_grp, | ||
506 | .miscdev.fops = &i2c_nuvoton_ops, | ||
507 | }; | ||
508 | |||
509 | /* The only purpose for the handler is to signal to any waiting threads that | ||
510 | * the interrupt is currently being asserted. The driver does not do any | ||
511 | * processing triggered by interrupts, and the chip provides no way to mask at | ||
512 | * the source (plus that would be slow over I2C). Run the IRQ as a one-shot, | ||
513 | * this means it cannot be shared. */ | ||
514 | static irqreturn_t i2c_nuvoton_int_handler(int dummy, void *dev_id) | ||
515 | { | ||
516 | struct tpm_chip *chip = dev_id; | ||
517 | struct priv_data *priv = chip->vendor.priv; | ||
518 | |||
519 | priv->intrs++; | ||
520 | wake_up(&chip->vendor.read_queue); | ||
521 | disable_irq_nosync(chip->vendor.irq); | ||
522 | return IRQ_HANDLED; | ||
523 | } | ||
524 | |||
525 | static int get_vid(struct i2c_client *client, u32 *res) | ||
526 | { | ||
527 | static const u8 vid_did_rid_value[] = { 0x50, 0x10, 0xfe }; | ||
528 | u32 temp; | ||
529 | s32 rc; | ||
530 | |||
531 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
532 | return -ENODEV; | ||
533 | rc = i2c_nuvoton_read_buf(client, TPM_VID_DID_RID, 4, (u8 *)&temp); | ||
534 | if (rc < 0) | ||
535 | return rc; | ||
536 | |||
537 | /* check WPCT301 values - ignore RID */ | ||
538 | if (memcmp(&temp, vid_did_rid_value, sizeof(vid_did_rid_value))) { | ||
539 | /* | ||
540 | * f/w rev 2.81 has an issue where the VID_DID_RID is not | ||
541 | * reporting the right value. so give it another chance at | ||
542 | * offset 0x20 (FIFO_W). | ||
543 | */ | ||
544 | rc = i2c_nuvoton_read_buf(client, TPM_DATA_FIFO_W, 4, | ||
545 | (u8 *) (&temp)); | ||
546 | if (rc < 0) | ||
547 | return rc; | ||
548 | |||
549 | /* check WPCT301 values - ignore RID */ | ||
550 | if (memcmp(&temp, vid_did_rid_value, | ||
551 | sizeof(vid_did_rid_value))) | ||
552 | return -ENODEV; | ||
553 | } | ||
554 | |||
555 | *res = temp; | ||
556 | return 0; | ||
557 | } | ||
558 | |||
559 | static int i2c_nuvoton_probe(struct i2c_client *client, | ||
560 | const struct i2c_device_id *id) | ||
561 | { | ||
562 | int rc; | ||
563 | struct tpm_chip *chip; | ||
564 | struct device *dev = &client->dev; | ||
565 | u32 vid = 0; | ||
566 | |||
567 | rc = get_vid(client, &vid); | ||
568 | if (rc) | ||
569 | return rc; | ||
570 | |||
571 | dev_info(dev, "VID: %04X DID: %02X RID: %02X\n", (u16) vid, | ||
572 | (u8) (vid >> 16), (u8) (vid >> 24)); | ||
573 | |||
574 | chip = tpm_register_hardware(dev, &tpm_i2c); | ||
575 | if (!chip) { | ||
576 | dev_err(dev, "%s() error in tpm_register_hardware\n", __func__); | ||
577 | return -ENODEV; | ||
578 | } | ||
579 | |||
580 | chip->vendor.priv = devm_kzalloc(dev, sizeof(struct priv_data), | ||
581 | GFP_KERNEL); | ||
582 | init_waitqueue_head(&chip->vendor.read_queue); | ||
583 | init_waitqueue_head(&chip->vendor.int_queue); | ||
584 | |||
585 | /* Default timeouts */ | ||
586 | chip->vendor.timeout_a = msecs_to_jiffies(TPM_I2C_SHORT_TIMEOUT); | ||
587 | chip->vendor.timeout_b = msecs_to_jiffies(TPM_I2C_LONG_TIMEOUT); | ||
588 | chip->vendor.timeout_c = msecs_to_jiffies(TPM_I2C_SHORT_TIMEOUT); | ||
589 | chip->vendor.timeout_d = msecs_to_jiffies(TPM_I2C_SHORT_TIMEOUT); | ||
590 | |||
591 | /* | ||
592 | * I2C intfcaps (interrupt capabilitieis) in the chip are hard coded to: | ||
593 | * TPM_INTF_INT_LEVEL_LOW | TPM_INTF_DATA_AVAIL_INT | ||
594 | * The IRQ should be set in the i2c_board_info (which is done | ||
595 | * automatically in of_i2c_register_devices, for device tree users */ | ||
596 | chip->vendor.irq = client->irq; | ||
597 | |||
598 | if (chip->vendor.irq) { | ||
599 | dev_dbg(dev, "%s() chip-vendor.irq\n", __func__); | ||
600 | rc = devm_request_irq(dev, chip->vendor.irq, | ||
601 | i2c_nuvoton_int_handler, | ||
602 | IRQF_TRIGGER_LOW, | ||
603 | chip->vendor.miscdev.name, | ||
604 | chip); | ||
605 | if (rc) { | ||
606 | dev_err(dev, "%s() Unable to request irq: %d for use\n", | ||
607 | __func__, chip->vendor.irq); | ||
608 | chip->vendor.irq = 0; | ||
609 | } else { | ||
610 | /* Clear any pending interrupt */ | ||
611 | i2c_nuvoton_ready(chip); | ||
612 | /* - wait for TPM_STS==0xA0 (stsValid, commandReady) */ | ||
613 | rc = i2c_nuvoton_wait_for_stat(chip, | ||
614 | TPM_STS_COMMAND_READY, | ||
615 | TPM_STS_COMMAND_READY, | ||
616 | chip->vendor.timeout_b, | ||
617 | NULL); | ||
618 | if (rc == 0) { | ||
619 | /* | ||
620 | * TIS is in ready state | ||
621 | * write dummy byte to enter reception state | ||
622 | * TPM_DATA_FIFO_W <- rc (0) | ||
623 | */ | ||
624 | rc = i2c_nuvoton_write_buf(client, | ||
625 | TPM_DATA_FIFO_W, | ||
626 | 1, (u8 *) (&rc)); | ||
627 | if (rc < 0) | ||
628 | goto out_err; | ||
629 | /* TPM_STS <- 0x40 (commandReady) */ | ||
630 | i2c_nuvoton_ready(chip); | ||
631 | } else { | ||
632 | /* | ||
633 | * timeout_b reached - command was | ||
634 | * aborted. TIS should now be in idle state - | ||
635 | * only TPM_STS_VALID should be set | ||
636 | */ | ||
637 | if (i2c_nuvoton_read_status(chip) != | ||
638 | TPM_STS_VALID) { | ||
639 | rc = -EIO; | ||
640 | goto out_err; | ||
641 | } | ||
642 | } | ||
643 | } | ||
644 | } | ||
645 | |||
646 | if (tpm_get_timeouts(chip)) { | ||
647 | rc = -ENODEV; | ||
648 | goto out_err; | ||
649 | } | ||
650 | |||
651 | if (tpm_do_selftest(chip)) { | ||
652 | rc = -ENODEV; | ||
653 | goto out_err; | ||
654 | } | ||
655 | |||
656 | return 0; | ||
657 | |||
658 | out_err: | ||
659 | tpm_dev_vendor_release(chip); | ||
660 | tpm_remove_hardware(chip->dev); | ||
661 | return rc; | ||
662 | } | ||
663 | |||
664 | static int i2c_nuvoton_remove(struct i2c_client *client) | ||
665 | { | ||
666 | struct device *dev = &(client->dev); | ||
667 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
668 | |||
669 | if (chip) | ||
670 | tpm_dev_vendor_release(chip); | ||
671 | tpm_remove_hardware(dev); | ||
672 | kfree(chip); | ||
673 | return 0; | ||
674 | } | ||
675 | |||
676 | |||
677 | static const struct i2c_device_id i2c_nuvoton_id[] = { | ||
678 | {I2C_DRIVER_NAME, 0}, | ||
679 | {} | ||
680 | }; | ||
681 | MODULE_DEVICE_TABLE(i2c, i2c_nuvoton_id); | ||
682 | |||
683 | #ifdef CONFIG_OF | ||
684 | static const struct of_device_id i2c_nuvoton_of_match[] = { | ||
685 | {.compatible = "nuvoton,npct501"}, | ||
686 | {.compatible = "winbond,wpct301"}, | ||
687 | {}, | ||
688 | }; | ||
689 | MODULE_DEVICE_TABLE(of, i2c_nuvoton_of_match); | ||
690 | #endif | ||
691 | |||
692 | static SIMPLE_DEV_PM_OPS(i2c_nuvoton_pm_ops, tpm_pm_suspend, tpm_pm_resume); | ||
693 | |||
694 | static struct i2c_driver i2c_nuvoton_driver = { | ||
695 | .id_table = i2c_nuvoton_id, | ||
696 | .probe = i2c_nuvoton_probe, | ||
697 | .remove = i2c_nuvoton_remove, | ||
698 | .driver = { | ||
699 | .name = I2C_DRIVER_NAME, | ||
700 | .owner = THIS_MODULE, | ||
701 | .pm = &i2c_nuvoton_pm_ops, | ||
702 | .of_match_table = of_match_ptr(i2c_nuvoton_of_match), | ||
703 | }, | ||
704 | }; | ||
705 | |||
706 | module_i2c_driver(i2c_nuvoton_driver); | ||
707 | |||
708 | MODULE_AUTHOR("Dan Morav (dan.morav@nuvoton.com)"); | ||
709 | MODULE_DESCRIPTION("Nuvoton TPM I2C Driver"); | ||
710 | MODULE_LICENSE("GPL"); | ||