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