0001
0002
0003
0004
0005
0006
0007 #include <linux/module.h>
0008 #include <linux/i2c.h>
0009 #include <linux/gpio.h>
0010 #include <linux/gpio/consumer.h>
0011 #include <linux/of_irq.h>
0012 #include <linux/of_gpio.h>
0013 #include <linux/acpi.h>
0014 #include <linux/tpm.h>
0015 #include <linux/platform_data/st33zp24.h>
0016
0017 #include "../tpm.h"
0018 #include "st33zp24.h"
0019
0020 #define TPM_DUMMY_BYTE 0xAA
0021
0022 struct st33zp24_i2c_phy {
0023 struct i2c_client *client;
0024 u8 buf[ST33ZP24_BUFSIZE + 1];
0025 int io_lpcpd;
0026 };
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 static int write8_reg(void *phy_id, u8 tpm_register, u8 *tpm_data, int tpm_size)
0037 {
0038 struct st33zp24_i2c_phy *phy = phy_id;
0039
0040 phy->buf[0] = tpm_register;
0041 memcpy(phy->buf + 1, tpm_data, tpm_size);
0042 return i2c_master_send(phy->client, phy->buf, tpm_size + 1);
0043 }
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 static int read8_reg(void *phy_id, u8 tpm_register, u8 *tpm_data, int tpm_size)
0054 {
0055 struct st33zp24_i2c_phy *phy = phy_id;
0056 u8 status = 0;
0057 u8 data;
0058
0059 data = TPM_DUMMY_BYTE;
0060 status = write8_reg(phy, tpm_register, &data, 1);
0061 if (status == 2)
0062 status = i2c_master_recv(phy->client, tpm_data, tpm_size);
0063 return status;
0064 }
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075 static int st33zp24_i2c_send(void *phy_id, u8 tpm_register, u8 *tpm_data,
0076 int tpm_size)
0077 {
0078 return write8_reg(phy_id, tpm_register | TPM_WRITE_DIRECTION, tpm_data,
0079 tpm_size);
0080 }
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091 static int st33zp24_i2c_recv(void *phy_id, u8 tpm_register, u8 *tpm_data,
0092 int tpm_size)
0093 {
0094 return read8_reg(phy_id, tpm_register, tpm_data, tpm_size);
0095 }
0096
0097 static const struct st33zp24_phy_ops i2c_phy_ops = {
0098 .send = st33zp24_i2c_send,
0099 .recv = st33zp24_i2c_recv,
0100 };
0101
0102 static const struct acpi_gpio_params lpcpd_gpios = { 1, 0, false };
0103
0104 static const struct acpi_gpio_mapping acpi_st33zp24_gpios[] = {
0105 { "lpcpd-gpios", &lpcpd_gpios, 1 },
0106 {},
0107 };
0108
0109 static int st33zp24_i2c_acpi_request_resources(struct i2c_client *client)
0110 {
0111 struct tpm_chip *chip = i2c_get_clientdata(client);
0112 struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
0113 struct st33zp24_i2c_phy *phy = tpm_dev->phy_id;
0114 struct gpio_desc *gpiod_lpcpd;
0115 struct device *dev = &client->dev;
0116 int ret;
0117
0118 ret = devm_acpi_dev_add_driver_gpios(dev, acpi_st33zp24_gpios);
0119 if (ret)
0120 return ret;
0121
0122
0123 gpiod_lpcpd = devm_gpiod_get(dev, "lpcpd", GPIOD_OUT_HIGH);
0124 if (IS_ERR(gpiod_lpcpd)) {
0125 dev_err(&client->dev,
0126 "Failed to retrieve lpcpd-gpios from acpi.\n");
0127 phy->io_lpcpd = -1;
0128
0129
0130
0131
0132
0133 return 0;
0134 }
0135
0136 phy->io_lpcpd = desc_to_gpio(gpiod_lpcpd);
0137
0138 return 0;
0139 }
0140
0141 static int st33zp24_i2c_of_request_resources(struct i2c_client *client)
0142 {
0143 struct tpm_chip *chip = i2c_get_clientdata(client);
0144 struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
0145 struct st33zp24_i2c_phy *phy = tpm_dev->phy_id;
0146 struct device_node *pp;
0147 int gpio;
0148 int ret;
0149
0150 pp = client->dev.of_node;
0151 if (!pp) {
0152 dev_err(&client->dev, "No platform data\n");
0153 return -ENODEV;
0154 }
0155
0156
0157 gpio = of_get_named_gpio(pp, "lpcpd-gpios", 0);
0158 if (gpio < 0) {
0159 dev_err(&client->dev,
0160 "Failed to retrieve lpcpd-gpios from dts.\n");
0161 phy->io_lpcpd = -1;
0162
0163
0164
0165
0166
0167 return 0;
0168 }
0169
0170 ret = devm_gpio_request_one(&client->dev, gpio,
0171 GPIOF_OUT_INIT_HIGH, "TPM IO LPCPD");
0172 if (ret) {
0173 dev_err(&client->dev, "Failed to request lpcpd pin\n");
0174 return -ENODEV;
0175 }
0176 phy->io_lpcpd = gpio;
0177
0178 return 0;
0179 }
0180
0181 static int st33zp24_i2c_request_resources(struct i2c_client *client)
0182 {
0183 struct tpm_chip *chip = i2c_get_clientdata(client);
0184 struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
0185 struct st33zp24_i2c_phy *phy = tpm_dev->phy_id;
0186 struct st33zp24_platform_data *pdata;
0187 int ret;
0188
0189 pdata = client->dev.platform_data;
0190 if (!pdata) {
0191 dev_err(&client->dev, "No platform data\n");
0192 return -ENODEV;
0193 }
0194
0195
0196 phy->io_lpcpd = pdata->io_lpcpd;
0197
0198 if (gpio_is_valid(pdata->io_lpcpd)) {
0199 ret = devm_gpio_request_one(&client->dev,
0200 pdata->io_lpcpd, GPIOF_OUT_INIT_HIGH,
0201 "TPM IO_LPCPD");
0202 if (ret) {
0203 dev_err(&client->dev, "Failed to request lpcpd pin\n");
0204 return ret;
0205 }
0206 }
0207
0208 return 0;
0209 }
0210
0211
0212
0213
0214
0215
0216
0217
0218 static int st33zp24_i2c_probe(struct i2c_client *client,
0219 const struct i2c_device_id *id)
0220 {
0221 int ret;
0222 struct st33zp24_platform_data *pdata;
0223 struct st33zp24_i2c_phy *phy;
0224
0225 if (!client) {
0226 pr_info("%s: i2c client is NULL. Device not accessible.\n",
0227 __func__);
0228 return -ENODEV;
0229 }
0230
0231 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
0232 dev_info(&client->dev, "client not i2c capable\n");
0233 return -ENODEV;
0234 }
0235
0236 phy = devm_kzalloc(&client->dev, sizeof(struct st33zp24_i2c_phy),
0237 GFP_KERNEL);
0238 if (!phy)
0239 return -ENOMEM;
0240
0241 phy->client = client;
0242
0243 pdata = client->dev.platform_data;
0244 if (!pdata && client->dev.of_node) {
0245 ret = st33zp24_i2c_of_request_resources(client);
0246 if (ret)
0247 return ret;
0248 } else if (pdata) {
0249 ret = st33zp24_i2c_request_resources(client);
0250 if (ret)
0251 return ret;
0252 } else if (ACPI_HANDLE(&client->dev)) {
0253 ret = st33zp24_i2c_acpi_request_resources(client);
0254 if (ret)
0255 return ret;
0256 }
0257
0258 return st33zp24_probe(phy, &i2c_phy_ops, &client->dev, client->irq,
0259 phy->io_lpcpd);
0260 }
0261
0262
0263
0264
0265
0266
0267 static int st33zp24_i2c_remove(struct i2c_client *client)
0268 {
0269 struct tpm_chip *chip = i2c_get_clientdata(client);
0270
0271 st33zp24_remove(chip);
0272
0273 return 0;
0274 }
0275
0276 static const struct i2c_device_id st33zp24_i2c_id[] = {
0277 {TPM_ST33_I2C, 0},
0278 {}
0279 };
0280 MODULE_DEVICE_TABLE(i2c, st33zp24_i2c_id);
0281
0282 static const struct of_device_id of_st33zp24_i2c_match[] = {
0283 { .compatible = "st,st33zp24-i2c", },
0284 {}
0285 };
0286 MODULE_DEVICE_TABLE(of, of_st33zp24_i2c_match);
0287
0288 static const struct acpi_device_id st33zp24_i2c_acpi_match[] = {
0289 {"SMO3324"},
0290 {}
0291 };
0292 MODULE_DEVICE_TABLE(acpi, st33zp24_i2c_acpi_match);
0293
0294 static SIMPLE_DEV_PM_OPS(st33zp24_i2c_ops, st33zp24_pm_suspend,
0295 st33zp24_pm_resume);
0296
0297 static struct i2c_driver st33zp24_i2c_driver = {
0298 .driver = {
0299 .name = TPM_ST33_I2C,
0300 .pm = &st33zp24_i2c_ops,
0301 .of_match_table = of_match_ptr(of_st33zp24_i2c_match),
0302 .acpi_match_table = ACPI_PTR(st33zp24_i2c_acpi_match),
0303 },
0304 .probe = st33zp24_i2c_probe,
0305 .remove = st33zp24_i2c_remove,
0306 .id_table = st33zp24_i2c_id
0307 };
0308
0309 module_i2c_driver(st33zp24_i2c_driver);
0310
0311 MODULE_AUTHOR("TPM support (TPMsupport@list.st.com)");
0312 MODULE_DESCRIPTION("STM TPM 1.2 I2C ST33 Driver");
0313 MODULE_VERSION("1.3.0");
0314 MODULE_LICENSE("GPL");