i2c-hid-of-goodix.c (5295B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Driver for Goodix 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 20struct goodix_i2c_hid_timing_data { 21 unsigned int post_gpio_reset_delay_ms; 22 unsigned int post_power_delay_ms; 23}; 24 25struct i2c_hid_of_goodix { 26 struct i2chid_ops ops; 27 28 struct regulator *vdd; 29 struct notifier_block nb; 30 struct gpio_desc *reset_gpio; 31 const struct goodix_i2c_hid_timing_data *timings; 32}; 33 34static void goodix_i2c_hid_deassert_reset(struct i2c_hid_of_goodix *ihid_goodix, 35 bool regulator_just_turned_on) 36{ 37 if (regulator_just_turned_on && ihid_goodix->timings->post_power_delay_ms) 38 msleep(ihid_goodix->timings->post_power_delay_ms); 39 40 gpiod_set_value_cansleep(ihid_goodix->reset_gpio, 0); 41 if (ihid_goodix->timings->post_gpio_reset_delay_ms) 42 msleep(ihid_goodix->timings->post_gpio_reset_delay_ms); 43} 44 45static int goodix_i2c_hid_power_up(struct i2chid_ops *ops) 46{ 47 struct i2c_hid_of_goodix *ihid_goodix = 48 container_of(ops, struct i2c_hid_of_goodix, ops); 49 50 return regulator_enable(ihid_goodix->vdd); 51} 52 53static void goodix_i2c_hid_power_down(struct i2chid_ops *ops) 54{ 55 struct i2c_hid_of_goodix *ihid_goodix = 56 container_of(ops, struct i2c_hid_of_goodix, ops); 57 58 regulator_disable(ihid_goodix->vdd); 59} 60 61static int ihid_goodix_vdd_notify(struct notifier_block *nb, 62 unsigned long event, 63 void *ignored) 64{ 65 struct i2c_hid_of_goodix *ihid_goodix = 66 container_of(nb, struct i2c_hid_of_goodix, nb); 67 int ret = NOTIFY_OK; 68 69 switch (event) { 70 case REGULATOR_EVENT_PRE_DISABLE: 71 gpiod_set_value_cansleep(ihid_goodix->reset_gpio, 1); 72 break; 73 74 case REGULATOR_EVENT_ENABLE: 75 goodix_i2c_hid_deassert_reset(ihid_goodix, true); 76 break; 77 78 case REGULATOR_EVENT_ABORT_DISABLE: 79 goodix_i2c_hid_deassert_reset(ihid_goodix, false); 80 break; 81 82 default: 83 ret = NOTIFY_DONE; 84 break; 85 } 86 87 return ret; 88} 89 90static int i2c_hid_of_goodix_probe(struct i2c_client *client, 91 const struct i2c_device_id *id) 92{ 93 struct i2c_hid_of_goodix *ihid_goodix; 94 int ret; 95 ihid_goodix = devm_kzalloc(&client->dev, sizeof(*ihid_goodix), 96 GFP_KERNEL); 97 if (!ihid_goodix) 98 return -ENOMEM; 99 100 ihid_goodix->ops.power_up = goodix_i2c_hid_power_up; 101 ihid_goodix->ops.power_down = goodix_i2c_hid_power_down; 102 103 /* Start out with reset asserted */ 104 ihid_goodix->reset_gpio = 105 devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_HIGH); 106 if (IS_ERR(ihid_goodix->reset_gpio)) 107 return PTR_ERR(ihid_goodix->reset_gpio); 108 109 ihid_goodix->vdd = devm_regulator_get(&client->dev, "vdd"); 110 if (IS_ERR(ihid_goodix->vdd)) 111 return PTR_ERR(ihid_goodix->vdd); 112 113 ihid_goodix->timings = device_get_match_data(&client->dev); 114 115 /* 116 * We need to control the "reset" line in lockstep with the regulator 117 * actually turning on an off instead of just when we make the request. 118 * This matters if the regulator is shared with another consumer. 119 * - If the regulator is off then we must assert reset. The reset 120 * line is active low and on some boards it could cause a current 121 * leak if left high. 122 * - If the regulator is on then we don't want reset asserted for very 123 * long. Holding the controller in reset apparently draws extra 124 * power. 125 */ 126 ihid_goodix->nb.notifier_call = ihid_goodix_vdd_notify; 127 ret = devm_regulator_register_notifier(ihid_goodix->vdd, &ihid_goodix->nb); 128 if (ret) 129 return dev_err_probe(&client->dev, ret, 130 "regulator notifier request failed\n"); 131 132 /* 133 * If someone else is holding the regulator on (or the regulator is 134 * an always-on one) we might never be told to deassert reset. Do it 135 * now... and temporarily bump the regulator reference count just to 136 * make sure it is impossible for this to race with our own notifier! 137 * We also assume that someone else might have _just barely_ turned 138 * the regulator on so we'll do the full "post_power_delay" just in 139 * case. 140 */ 141 if (ihid_goodix->reset_gpio && regulator_is_enabled(ihid_goodix->vdd)) { 142 ret = regulator_enable(ihid_goodix->vdd); 143 if (ret) 144 return ret; 145 goodix_i2c_hid_deassert_reset(ihid_goodix, true); 146 regulator_disable(ihid_goodix->vdd); 147 } 148 149 return i2c_hid_core_probe(client, &ihid_goodix->ops, 0x0001, 0); 150} 151 152static const struct goodix_i2c_hid_timing_data goodix_gt7375p_timing_data = { 153 .post_power_delay_ms = 10, 154 .post_gpio_reset_delay_ms = 180, 155}; 156 157static const struct of_device_id goodix_i2c_hid_of_match[] = { 158 { .compatible = "goodix,gt7375p", .data = &goodix_gt7375p_timing_data }, 159 { } 160}; 161MODULE_DEVICE_TABLE(of, goodix_i2c_hid_of_match); 162 163static struct i2c_driver goodix_i2c_hid_ts_driver = { 164 .driver = { 165 .name = "i2c_hid_of_goodix", 166 .pm = &i2c_hid_core_pm, 167 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 168 .of_match_table = of_match_ptr(goodix_i2c_hid_of_match), 169 }, 170 .probe = i2c_hid_of_goodix_probe, 171 .remove = i2c_hid_core_remove, 172 .shutdown = i2c_hid_core_shutdown, 173}; 174module_i2c_driver(goodix_i2c_hid_ts_driver); 175 176MODULE_AUTHOR("Douglas Anderson <dianders@chromium.org>"); 177MODULE_DESCRIPTION("Goodix i2c-hid touchscreen driver"); 178MODULE_LICENSE("GPL v2");