aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tpm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/tpm')
-rw-r--r--drivers/char/tpm/tpm_i2c_infineon.c137
1 files changed, 97 insertions, 40 deletions
diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c
index 8e47e2b99efc..bd9a2958dc39 100644
--- a/drivers/char/tpm/tpm_i2c_infineon.c
+++ b/drivers/char/tpm/tpm_i2c_infineon.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2012 Infineon Technologies 2 * Copyright (C) 2012,2013 Infineon Technologies
3 * 3 *
4 * Authors: 4 * Authors:
5 * Peter Huewe <peter.huewe@infineon.com> 5 * Peter Huewe <peter.huewe@infineon.com>
@@ -56,13 +56,21 @@
56#define TPM_TIMEOUT_US_HI (TPM_TIMEOUT_US_LOW + 2000) 56#define TPM_TIMEOUT_US_HI (TPM_TIMEOUT_US_LOW + 2000)
57 57
58/* expected value for DIDVID register */ 58/* expected value for DIDVID register */
59#define TPM_TIS_I2C_DID_VID 0x000b15d1L 59#define TPM_TIS_I2C_DID_VID_9635 0xd1150b00L
60#define TPM_TIS_I2C_DID_VID_9645 0x001a15d1L
61
62enum i2c_chip_type {
63 SLB9635,
64 SLB9645,
65 UNKNOWN,
66};
60 67
61/* Structure to store I2C TPM specific stuff */ 68/* Structure to store I2C TPM specific stuff */
62struct tpm_inf_dev { 69struct tpm_inf_dev {
63 struct i2c_client *client; 70 struct i2c_client *client;
64 u8 buf[TPM_BUFSIZE + sizeof(u8)]; /* max. buffer size + addr */ 71 u8 buf[TPM_BUFSIZE + sizeof(u8)]; /* max. buffer size + addr */
65 struct tpm_chip *chip; 72 struct tpm_chip *chip;
73 enum i2c_chip_type chip_type;
66}; 74};
67 75
68static struct tpm_inf_dev tpm_dev; 76static struct tpm_inf_dev tpm_dev;
@@ -101,8 +109,9 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
101 .len = len, 109 .len = len,
102 .buf = buffer 110 .buf = buffer
103 }; 111 };
112 struct i2c_msg msgs[] = {msg1, msg2};
104 113
105 int rc; 114 int rc = 0;
106 int count; 115 int count;
107 116
108 /* Lock the adapter for the duration of the whole sequence. */ 117 /* Lock the adapter for the duration of the whole sequence. */
@@ -110,30 +119,49 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
110 return -EOPNOTSUPP; 119 return -EOPNOTSUPP;
111 i2c_lock_adapter(tpm_dev.client->adapter); 120 i2c_lock_adapter(tpm_dev.client->adapter);
112 121
113 for (count = 0; count < MAX_COUNT; count++) { 122 if (tpm_dev.chip_type == SLB9645) {
114 rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1); 123 /* use a combined read for newer chips
115 if (rc > 0) 124 * unfortunately the smbus functions are not suitable due to
116 break; /* break here to skip sleep */ 125 * the 32 byte limit of the smbus.
117 126 * retries should usually not be needed, but are kept just to
118 usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI); 127 * be on the safe side.
119 } 128 */
120 129 for (count = 0; count < MAX_COUNT; count++) {
121 if (rc <= 0) 130 rc = __i2c_transfer(tpm_dev.client->adapter, msgs, 2);
122 goto out; 131 if (rc > 0)
123 132 break; /* break here to skip sleep */
124 /* After the TPM has successfully received the register address it needs 133 usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
125 * some time, thus we're sleeping here again, before retrieving the data 134 }
126 */ 135 } else {
127 for (count = 0; count < MAX_COUNT; count++) { 136 /* slb9635 protocol should work in all cases */
128 usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI); 137 for (count = 0; count < MAX_COUNT; count++) {
129 rc = __i2c_transfer(tpm_dev.client->adapter, &msg2, 1); 138 rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1);
130 if (rc > 0) 139 if (rc > 0)
131 break; 140 break; /* break here to skip sleep */
141
142 usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
143 }
132 144
145 if (rc <= 0)
146 goto out;
147
148 /* After the TPM has successfully received the register address
149 * it needs some time, thus we're sleeping here again, before
150 * retrieving the data
151 */
152 for (count = 0; count < MAX_COUNT; count++) {
153 usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
154 rc = __i2c_transfer(tpm_dev.client->adapter, &msg2, 1);
155 if (rc > 0)
156 break;
157 }
133 } 158 }
134 159
135out: 160out:
136 i2c_unlock_adapter(tpm_dev.client->adapter); 161 i2c_unlock_adapter(tpm_dev.client->adapter);
162 /* take care of 'guard time' */
163 usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
164
137 if (rc <= 0) 165 if (rc <= 0)
138 return -EIO; 166 return -EIO;
139 167
@@ -167,16 +195,19 @@ static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len,
167 /* 195 /*
168 * NOTE: We have to use these special mechanisms here and unfortunately 196 * NOTE: We have to use these special mechanisms here and unfortunately
169 * cannot rely on the standard behavior of i2c_transfer. 197 * cannot rely on the standard behavior of i2c_transfer.
198 * Even for newer chips the smbus functions are not
199 * suitable due to the 32 byte limit of the smbus.
170 */ 200 */
171 for (count = 0; count < max_count; count++) { 201 for (count = 0; count < max_count; count++) {
172 rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1); 202 rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1);
173 if (rc > 0) 203 if (rc > 0)
174 break; 204 break;
175
176 usleep_range(sleep_low, sleep_hi); 205 usleep_range(sleep_low, sleep_hi);
177 } 206 }
178 207
179 i2c_unlock_adapter(tpm_dev.client->adapter); 208 i2c_unlock_adapter(tpm_dev.client->adapter);
209 /* take care of 'guard time' */
210 usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
180 if (rc <= 0) 211 if (rc <= 0)
181 return -EIO; 212 return -EIO;
182 213
@@ -296,11 +327,18 @@ static int request_locality(struct tpm_chip *chip, int loc)
296static u8 tpm_tis_i2c_status(struct tpm_chip *chip) 327static u8 tpm_tis_i2c_status(struct tpm_chip *chip)
297{ 328{
298 /* NOTE: since I2C read may fail, return 0 in this case --> time-out */ 329 /* NOTE: since I2C read may fail, return 0 in this case --> time-out */
299 u8 buf; 330 u8 buf = 0xFF;
300 if (iic_tpm_read(TPM_STS(chip->vendor.locality), &buf, 1) < 0) 331 u8 i = 0;
301 return 0; 332
302 else 333 do {
303 return buf; 334 if (iic_tpm_read(TPM_STS(chip->vendor.locality), &buf, 1) < 0)
335 return 0;
336
337 i++;
338 /* if locallity is set STS should not be 0xFF */
339 } while ((buf == 0xFF) && i < 10);
340
341 return buf;
304} 342}
305 343
306static void tpm_tis_i2c_ready(struct tpm_chip *chip) 344static void tpm_tis_i2c_ready(struct tpm_chip *chip)
@@ -341,7 +379,7 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
341 379
342 /* check current status */ 380 /* check current status */
343 *status = tpm_tis_i2c_status(chip); 381 *status = tpm_tis_i2c_status(chip);
344 if ((*status & mask) == mask) 382 if ((*status != 0xFF) && (*status & mask) == mask)
345 return 0; 383 return 0;
346 384
347 stop = jiffies + timeout; 385 stop = jiffies + timeout;
@@ -385,7 +423,6 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
385 /* avoid endless loop in case of broken HW */ 423 /* avoid endless loop in case of broken HW */
386 if (retries > MAX_COUNT_LONG) 424 if (retries > MAX_COUNT_LONG)
387 return -EIO; 425 return -EIO;
388
389 } 426 }
390 return size; 427 return size;
391} 428}
@@ -493,7 +530,6 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
493 rc = -EIO; 530 rc = -EIO;
494 goto out_err; 531 goto out_err;
495 } 532 }
496
497 } 533 }
498 534
499 /* write last byte */ 535 /* write last byte */
@@ -581,6 +617,7 @@ static int tpm_tis_i2c_init(struct device *dev)
581 617
582 chip = tpm_register_hardware(dev, &tpm_tis_i2c); 618 chip = tpm_register_hardware(dev, &tpm_tis_i2c);
583 if (!chip) { 619 if (!chip) {
620 dev_err(dev, "could not register hardware\n");
584 rc = -ENODEV; 621 rc = -ENODEV;
585 goto out_err; 622 goto out_err;
586 } 623 }
@@ -595,20 +632,24 @@ static int tpm_tis_i2c_init(struct device *dev)
595 chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT); 632 chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
596 633
597 if (request_locality(chip, 0) != 0) { 634 if (request_locality(chip, 0) != 0) {
635 dev_err(dev, "could not request locality\n");
598 rc = -ENODEV; 636 rc = -ENODEV;
599 goto out_vendor; 637 goto out_vendor;
600 } 638 }
601 639
602 /* read four bytes from DID_VID register */ 640 /* read four bytes from DID_VID register */
603 if (iic_tpm_read(TPM_DID_VID(0), (u8 *)&vendor, 4) < 0) { 641 if (iic_tpm_read(TPM_DID_VID(0), (u8 *)&vendor, 4) < 0) {
642 dev_err(dev, "could not read vendor id\n");
604 rc = -EIO; 643 rc = -EIO;
605 goto out_release; 644 goto out_release;
606 } 645 }
607 646
608 /* create DID_VID register value, after swapping to little-endian */ 647 if (vendor == TPM_TIS_I2C_DID_VID_9645) {
609 vendor = be32_to_cpu((__be32) vendor); 648 tpm_dev.chip_type = SLB9645;
610 649 } else if (vendor == TPM_TIS_I2C_DID_VID_9635) {
611 if (vendor != TPM_TIS_I2C_DID_VID) { 650 tpm_dev.chip_type = SLB9635;
651 } else {
652 dev_err(dev, "vendor id did not match! ID was %08x\n", vendor);
612 rc = -ENODEV; 653 rc = -ENODEV;
613 goto out_release; 654 goto out_release;
614 } 655 }
@@ -644,22 +685,38 @@ out_err:
644 685
645static const struct i2c_device_id tpm_tis_i2c_table[] = { 686static const struct i2c_device_id tpm_tis_i2c_table[] = {
646 {"tpm_i2c_infineon", 0}, 687 {"tpm_i2c_infineon", 0},
688 {"slb9635tt", 0},
689 {"slb9645tt", 1},
647 {}, 690 {},
648}; 691};
649 692
650MODULE_DEVICE_TABLE(i2c, tpm_tis_i2c_table); 693MODULE_DEVICE_TABLE(i2c, tpm_tis_i2c_table);
694
695#ifdef CONFIG_OF
696static const struct of_device_id tpm_tis_i2c_of_match[] = {
697 { .compatible = "infineon,tpm_i2c_infineon", .data = (void *)0 },
698 { .compatible = "infineon,slb9635tt", .data = (void *)0 },
699 { .compatible = "infineon,slb9645tt", .data = (void *)1 },
700 {},
701};
702MODULE_DEVICE_TABLE(of, tpm_tis_i2c_of_match);
703#endif
704
651static SIMPLE_DEV_PM_OPS(tpm_tis_i2c_ops, tpm_pm_suspend, tpm_pm_resume); 705static SIMPLE_DEV_PM_OPS(tpm_tis_i2c_ops, tpm_pm_suspend, tpm_pm_resume);
652 706
653static int tpm_tis_i2c_probe(struct i2c_client *client, 707static int tpm_tis_i2c_probe(struct i2c_client *client,
654 const struct i2c_device_id *id) 708 const struct i2c_device_id *id)
655{ 709{
656 int rc; 710 int rc;
657 if (tpm_dev.client != NULL) 711 struct device *dev = &(client->dev);
712
713 if (tpm_dev.client != NULL) {
714 dev_err(dev, "This driver only supports one client at a time\n");
658 return -EBUSY; /* We only support one client */ 715 return -EBUSY; /* We only support one client */
716 }
659 717
660 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 718 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
661 dev_err(&client->dev, 719 dev_err(dev, "no algorithms associated to the i2c bus\n");
662 "no algorithms associated to the i2c bus\n");
663 return -ENODEV; 720 return -ENODEV;
664 } 721 }
665 722
@@ -695,7 +752,6 @@ static int tpm_tis_i2c_remove(struct i2c_client *client)
695} 752}
696 753
697static struct i2c_driver tpm_tis_i2c_driver = { 754static struct i2c_driver tpm_tis_i2c_driver = {
698
699 .id_table = tpm_tis_i2c_table, 755 .id_table = tpm_tis_i2c_table,
700 .probe = tpm_tis_i2c_probe, 756 .probe = tpm_tis_i2c_probe,
701 .remove = tpm_tis_i2c_remove, 757 .remove = tpm_tis_i2c_remove,
@@ -703,11 +759,12 @@ static struct i2c_driver tpm_tis_i2c_driver = {
703 .name = "tpm_i2c_infineon", 759 .name = "tpm_i2c_infineon",
704 .owner = THIS_MODULE, 760 .owner = THIS_MODULE,
705 .pm = &tpm_tis_i2c_ops, 761 .pm = &tpm_tis_i2c_ops,
762 .of_match_table = of_match_ptr(tpm_tis_i2c_of_match),
706 }, 763 },
707}; 764};
708 765
709module_i2c_driver(tpm_tis_i2c_driver); 766module_i2c_driver(tpm_tis_i2c_driver);
710MODULE_AUTHOR("Peter Huewe <peter.huewe@infineon.com>"); 767MODULE_AUTHOR("Peter Huewe <peter.huewe@infineon.com>");
711MODULE_DESCRIPTION("TPM TIS I2C Infineon Driver"); 768MODULE_DESCRIPTION("TPM TIS I2C Infineon Driver");
712MODULE_VERSION("2.1.5"); 769MODULE_VERSION("2.2.0");
713MODULE_LICENSE("GPL"); 770MODULE_LICENSE("GPL");