0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/delay.h>
0009 #include <linux/device.h>
0010 #include <linux/gpio/consumer.h>
0011 #include <linux/i2c.h>
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/of.h>
0015 #include <linux/pm.h>
0016 #include <linux/regulator/consumer.h>
0017
0018 #include "i2c-hid.h"
0019
0020 struct elan_i2c_hid_chip_data {
0021 unsigned int post_gpio_reset_delay_ms;
0022 unsigned int post_power_delay_ms;
0023 u16 hid_descriptor_address;
0024 };
0025
0026 struct i2c_hid_of_elan {
0027 struct i2chid_ops ops;
0028
0029 struct regulator *vcc33;
0030 struct regulator *vccio;
0031 struct gpio_desc *reset_gpio;
0032 const struct elan_i2c_hid_chip_data *chip_data;
0033 };
0034
0035 static int elan_i2c_hid_power_up(struct i2chid_ops *ops)
0036 {
0037 struct i2c_hid_of_elan *ihid_elan =
0038 container_of(ops, struct i2c_hid_of_elan, ops);
0039 int ret;
0040
0041 ret = regulator_enable(ihid_elan->vcc33);
0042 if (ret)
0043 return ret;
0044
0045 ret = regulator_enable(ihid_elan->vccio);
0046 if (ret) {
0047 regulator_disable(ihid_elan->vcc33);
0048 return ret;
0049 }
0050
0051 if (ihid_elan->chip_data->post_power_delay_ms)
0052 msleep(ihid_elan->chip_data->post_power_delay_ms);
0053
0054 gpiod_set_value_cansleep(ihid_elan->reset_gpio, 0);
0055 if (ihid_elan->chip_data->post_gpio_reset_delay_ms)
0056 msleep(ihid_elan->chip_data->post_gpio_reset_delay_ms);
0057
0058 return 0;
0059 }
0060
0061 static void elan_i2c_hid_power_down(struct i2chid_ops *ops)
0062 {
0063 struct i2c_hid_of_elan *ihid_elan =
0064 container_of(ops, struct i2c_hid_of_elan, ops);
0065
0066 gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1);
0067 regulator_disable(ihid_elan->vccio);
0068 regulator_disable(ihid_elan->vcc33);
0069 }
0070
0071 static int i2c_hid_of_elan_probe(struct i2c_client *client,
0072 const struct i2c_device_id *id)
0073 {
0074 struct i2c_hid_of_elan *ihid_elan;
0075
0076 ihid_elan = devm_kzalloc(&client->dev, sizeof(*ihid_elan), GFP_KERNEL);
0077 if (!ihid_elan)
0078 return -ENOMEM;
0079
0080 ihid_elan->ops.power_up = elan_i2c_hid_power_up;
0081 ihid_elan->ops.power_down = elan_i2c_hid_power_down;
0082
0083
0084 ihid_elan->reset_gpio =
0085 devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_HIGH);
0086 if (IS_ERR(ihid_elan->reset_gpio))
0087 return PTR_ERR(ihid_elan->reset_gpio);
0088
0089 ihid_elan->vccio = devm_regulator_get(&client->dev, "vccio");
0090 if (IS_ERR(ihid_elan->vccio))
0091 return PTR_ERR(ihid_elan->vccio);
0092
0093 ihid_elan->vcc33 = devm_regulator_get(&client->dev, "vcc33");
0094 if (IS_ERR(ihid_elan->vcc33))
0095 return PTR_ERR(ihid_elan->vcc33);
0096
0097 ihid_elan->chip_data = device_get_match_data(&client->dev);
0098
0099 return i2c_hid_core_probe(client, &ihid_elan->ops,
0100 ihid_elan->chip_data->hid_descriptor_address, 0);
0101 }
0102
0103 static const struct elan_i2c_hid_chip_data elan_ekth6915_chip_data = {
0104 .post_power_delay_ms = 1,
0105 .post_gpio_reset_delay_ms = 300,
0106 .hid_descriptor_address = 0x0001,
0107 };
0108
0109 static const struct of_device_id elan_i2c_hid_of_match[] = {
0110 { .compatible = "elan,ekth6915", .data = &elan_ekth6915_chip_data },
0111 { }
0112 };
0113 MODULE_DEVICE_TABLE(of, elan_i2c_hid_of_match);
0114
0115 static struct i2c_driver elan_i2c_hid_ts_driver = {
0116 .driver = {
0117 .name = "i2c_hid_of_elan",
0118 .pm = &i2c_hid_core_pm,
0119 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
0120 .of_match_table = of_match_ptr(elan_i2c_hid_of_match),
0121 },
0122 .probe = i2c_hid_of_elan_probe,
0123 .remove = i2c_hid_core_remove,
0124 .shutdown = i2c_hid_core_shutdown,
0125 };
0126 module_i2c_driver(elan_i2c_hid_ts_driver);
0127
0128 MODULE_AUTHOR("Douglas Anderson <dianders@chromium.org>");
0129 MODULE_DESCRIPTION("Elan i2c-hid touchscreen driver");
0130 MODULE_LICENSE("GPL");