1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Driver for Elan touchscreens that use the i2c-hid protocol. 4 * 5 * Copyright 2020 Google LLC 6 */ 7 8 #include <linux/delay.h> 9 #include <linux/device.h> 10 #include <linux/gpio/consumer.h> 11 #include <linux/i2c.h> 12 #include <linux/kernel.h> 13 #include <linux/module.h> 14 #include <linux/of.h> 15 #include <linux/pm.h> 16 #include <linux/regulator/consumer.h> 17 18 #include "i2c-hid.h" 19 20 struct elan_i2c_hid_chip_data { 21 unsigned int post_gpio_reset_on_delay_ms; 22 unsigned int post_gpio_reset_off_delay_ms; 23 unsigned int post_power_delay_ms; 24 u16 hid_descriptor_address; 25 const char *main_supply_name; 26 }; 27 28 struct i2c_hid_of_elan { 29 struct i2chid_ops ops; 30 31 struct regulator *vcc33; 32 struct regulator *vccio; 33 struct gpio_desc *reset_gpio; 34 bool no_reset_on_power_off; 35 const struct elan_i2c_hid_chip_data *chip_data; 36 }; 37 38 static int elan_i2c_hid_power_up(struct i2chid_ops *ops) 39 { 40 struct i2c_hid_of_elan *ihid_elan = 41 container_of(ops, struct i2c_hid_of_elan, ops); 42 int ret; 43 44 gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1); 45 46 if (ihid_elan->vcc33) { 47 ret = regulator_enable(ihid_elan->vcc33); 48 if (ret) 49 goto err_deassert_reset; 50 } 51 52 ret = regulator_enable(ihid_elan->vccio); 53 if (ret) 54 goto err_disable_vcc33; 55 56 if (ihid_elan->chip_data->post_power_delay_ms) 57 msleep(ihid_elan->chip_data->post_power_delay_ms); 58 59 gpiod_set_value_cansleep(ihid_elan->reset_gpio, 0); 60 if (ihid_elan->chip_data->post_gpio_reset_on_delay_ms) 61 msleep(ihid_elan->chip_data->post_gpio_reset_on_delay_ms); 62 63 return 0; 64 65 err_disable_vcc33: 66 if (ihid_elan->vcc33) 67 regulator_disable(ihid_elan->vcc33); 68 err_deassert_reset: 69 if (ihid_elan->no_reset_on_power_off) 70 gpiod_set_value_cansleep(ihid_elan->reset_gpio, 0); 71 72 return ret; 73 } 74 75 static void elan_i2c_hid_power_down(struct i2chid_ops *ops) 76 { 77 struct i2c_hid_of_elan *ihid_elan = 78 container_of(ops, struct i2c_hid_of_elan, ops); 79 80 /* 81 * Do not assert reset when the hardware allows for it to remain 82 * deasserted regardless of the state of the (shared) power supply to 83 * avoid wasting power when the supply is left on. 84 */ 85 if (!ihid_elan->no_reset_on_power_off) 86 gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1); 87 88 if (ihid_elan->chip_data->post_gpio_reset_off_delay_ms) 89 msleep(ihid_elan->chip_data->post_gpio_reset_off_delay_ms); 90 91 regulator_disable(ihid_elan->vccio); 92 if (ihid_elan->vcc33) 93 regulator_disable(ihid_elan->vcc33); 94 } 95 96 static int i2c_hid_of_elan_probe(struct i2c_client *client) 97 { 98 struct i2c_hid_of_elan *ihid_elan; 99 int ret; 100 101 ihid_elan = devm_kzalloc(&client->dev, sizeof(*ihid_elan), GFP_KERNEL); 102 if (!ihid_elan) 103 return -ENOMEM; 104 105 ihid_elan->ops.power_up = elan_i2c_hid_power_up; 106 ihid_elan->ops.power_down = elan_i2c_hid_power_down; 107 108 /* Start out with reset asserted */ 109 ihid_elan->reset_gpio = 110 devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_HIGH); 111 if (IS_ERR(ihid_elan->reset_gpio)) 112 return PTR_ERR(ihid_elan->reset_gpio); 113 114 ihid_elan->no_reset_on_power_off = of_property_read_bool(client->dev.of_node, 115 "no-reset-on-power-off"); 116 117 ihid_elan->vccio = devm_regulator_get(&client->dev, "vccio"); 118 if (IS_ERR(ihid_elan->vccio)) { 119 ret = PTR_ERR(ihid_elan->vccio); 120 goto err_deassert_reset; 121 } 122 123 ihid_elan->chip_data = device_get_match_data(&client->dev); 124 125 if (ihid_elan->chip_data->main_supply_name) { 126 ihid_elan->vcc33 = devm_regulator_get(&client->dev, 127 ihid_elan->chip_data->main_supply_name); 128 if (IS_ERR(ihid_elan->vcc33)) { 129 ret = PTR_ERR(ihid_elan->vcc33); 130 goto err_deassert_reset; 131 } 132 } 133 134 ret = i2c_hid_core_probe(client, &ihid_elan->ops, 135 ihid_elan->chip_data->hid_descriptor_address, 0); 136 if (ret) 137 goto err_deassert_reset; 138 139 return 0; 140 141 err_deassert_reset: 142 if (ihid_elan->no_reset_on_power_off) 143 gpiod_set_value_cansleep(ihid_elan->reset_gpio, 0); 144 145 return ret; 146 } 147 148 static const struct elan_i2c_hid_chip_data elan_ekth6915_chip_data = { 149 .post_power_delay_ms = 1, 150 .post_gpio_reset_on_delay_ms = 300, 151 .hid_descriptor_address = 0x0001, 152 .main_supply_name = "vcc33", 153 }; 154 155 static const struct elan_i2c_hid_chip_data elan_ekth6a12nay_chip_data = { 156 .post_power_delay_ms = 10, 157 .post_gpio_reset_on_delay_ms = 300, 158 .hid_descriptor_address = 0x0001, 159 .main_supply_name = "vcc33", 160 }; 161 162 static const struct elan_i2c_hid_chip_data ilitek_ili9882t_chip_data = { 163 .post_power_delay_ms = 1, 164 .post_gpio_reset_on_delay_ms = 200, 165 .post_gpio_reset_off_delay_ms = 65, 166 .hid_descriptor_address = 0x0001, 167 /* 168 * this touchscreen is tightly integrated with the panel and assumes 169 * that the relevant power rails (other than the IO rail) have already 170 * been turned on by the panel driver because we're a panel follower. 171 */ 172 .main_supply_name = NULL, 173 }; 174 175 static const struct elan_i2c_hid_chip_data ilitek_ili2901_chip_data = { 176 .post_power_delay_ms = 10, 177 .post_gpio_reset_on_delay_ms = 100, 178 .hid_descriptor_address = 0x0001, 179 .main_supply_name = "vcc33", 180 }; 181 182 static const struct of_device_id elan_i2c_hid_of_match[] = { 183 { .compatible = "elan,ekth6915", .data = &elan_ekth6915_chip_data }, 184 { .compatible = "elan,ekth6a12nay", .data = &elan_ekth6a12nay_chip_data }, 185 { .compatible = "ilitek,ili9882t", .data = &ilitek_ili9882t_chip_data }, 186 { .compatible = "ilitek,ili2901", .data = &ilitek_ili2901_chip_data }, 187 { } 188 }; 189 MODULE_DEVICE_TABLE(of, elan_i2c_hid_of_match); 190 191 static struct i2c_driver elan_i2c_hid_ts_driver = { 192 .driver = { 193 .name = "i2c_hid_of_elan", 194 .pm = &i2c_hid_core_pm, 195 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 196 .of_match_table = of_match_ptr(elan_i2c_hid_of_match), 197 }, 198 .probe = i2c_hid_of_elan_probe, 199 .remove = i2c_hid_core_remove, 200 .shutdown = i2c_hid_core_shutdown, 201 }; 202 module_i2c_driver(elan_i2c_hid_ts_driver); 203 204 MODULE_AUTHOR("Douglas Anderson <dianders@chromium.org>"); 205 MODULE_DESCRIPTION("Elan i2c-hid touchscreen driver"); 206 MODULE_LICENSE("GPL"); 207