1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for Goodix touchscreens that use the i2c-hid protocol.
5 * Copyright 2020 Google LLC
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>
16 #include <linux/regulator/consumer.h>
20 struct goodix_i2c_hid_timing_data
{
21 unsigned int post_gpio_reset_delay_ms
;
22 unsigned int post_power_delay_ms
;
25 struct i2c_hid_of_goodix
{
26 struct i2chid_ops ops
;
28 struct regulator
*vdd
;
29 struct notifier_block nb
;
30 struct gpio_desc
*reset_gpio
;
31 const struct goodix_i2c_hid_timing_data
*timings
;
34 static void goodix_i2c_hid_deassert_reset(struct i2c_hid_of_goodix
*ihid_goodix
,
35 bool regulator_just_turned_on
)
37 if (regulator_just_turned_on
&& ihid_goodix
->timings
->post_power_delay_ms
)
38 msleep(ihid_goodix
->timings
->post_power_delay_ms
);
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
);
45 static int goodix_i2c_hid_power_up(struct i2chid_ops
*ops
)
47 struct i2c_hid_of_goodix
*ihid_goodix
=
48 container_of(ops
, struct i2c_hid_of_goodix
, ops
);
50 return regulator_enable(ihid_goodix
->vdd
);
53 static void goodix_i2c_hid_power_down(struct i2chid_ops
*ops
)
55 struct i2c_hid_of_goodix
*ihid_goodix
=
56 container_of(ops
, struct i2c_hid_of_goodix
, ops
);
58 regulator_disable(ihid_goodix
->vdd
);
61 static int ihid_goodix_vdd_notify(struct notifier_block
*nb
,
65 struct i2c_hid_of_goodix
*ihid_goodix
=
66 container_of(nb
, struct i2c_hid_of_goodix
, nb
);
70 case REGULATOR_EVENT_PRE_DISABLE
:
71 gpiod_set_value_cansleep(ihid_goodix
->reset_gpio
, 1);
74 case REGULATOR_EVENT_ENABLE
:
75 goodix_i2c_hid_deassert_reset(ihid_goodix
, true);
78 case REGULATOR_EVENT_ABORT_DISABLE
:
79 goodix_i2c_hid_deassert_reset(ihid_goodix
, false);
90 static int i2c_hid_of_goodix_probe(struct i2c_client
*client
,
91 const struct i2c_device_id
*id
)
93 struct i2c_hid_of_goodix
*ihid_goodix
;
95 ihid_goodix
= devm_kzalloc(&client
->dev
, sizeof(*ihid_goodix
),
100 ihid_goodix
->ops
.power_up
= goodix_i2c_hid_power_up
;
101 ihid_goodix
->ops
.power_down
= goodix_i2c_hid_power_down
;
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
);
109 ihid_goodix
->vdd
= devm_regulator_get(&client
->dev
, "vdd");
110 if (IS_ERR(ihid_goodix
->vdd
))
111 return PTR_ERR(ihid_goodix
->vdd
);
113 ihid_goodix
->timings
= device_get_match_data(&client
->dev
);
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
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
126 ihid_goodix
->nb
.notifier_call
= ihid_goodix_vdd_notify
;
127 ret
= devm_regulator_register_notifier(ihid_goodix
->vdd
, &ihid_goodix
->nb
);
129 return dev_err_probe(&client
->dev
, ret
,
130 "regulator notifier request failed\n");
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
141 if (ihid_goodix
->reset_gpio
&& regulator_is_enabled(ihid_goodix
->vdd
)) {
142 ret
= regulator_enable(ihid_goodix
->vdd
);
145 goodix_i2c_hid_deassert_reset(ihid_goodix
, true);
146 regulator_disable(ihid_goodix
->vdd
);
149 return i2c_hid_core_probe(client
, &ihid_goodix
->ops
, 0x0001, 0);
152 static const struct goodix_i2c_hid_timing_data goodix_gt7375p_timing_data
= {
153 .post_power_delay_ms
= 10,
154 .post_gpio_reset_delay_ms
= 180,
157 static const struct of_device_id goodix_i2c_hid_of_match
[] = {
158 { .compatible
= "goodix,gt7375p", .data
= &goodix_gt7375p_timing_data
},
161 MODULE_DEVICE_TABLE(of
, goodix_i2c_hid_of_match
);
163 static struct i2c_driver goodix_i2c_hid_ts_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
),
170 .probe
= i2c_hid_of_goodix_probe
,
171 .remove
= i2c_hid_core_remove
,
172 .shutdown
= i2c_hid_core_shutdown
,
174 module_i2c_driver(goodix_i2c_hid_ts_driver
);
176 MODULE_AUTHOR("Douglas Anderson <dianders@chromium.org>");
177 MODULE_DESCRIPTION("Goodix i2c-hid touchscreen driver");
178 MODULE_LICENSE("GPL v2");