i2c-hid-of-goodix.c 5.2 KB

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