aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIrina Tirdea <irina.tirdea@intel.com>2015-12-17 19:43:39 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2015-12-17 20:11:53 -0500
commit5ab09d6a8f6406134085fb3f30ab61968c6f1ddf (patch)
treeea3327fd4310c682bacc92e57b0bf38f503c42d0
parent68caf85881cd842b59d5e2124a236ecce0389a73 (diff)
Input: goodix - add power management support
Implement suspend/resume for goodix driver. The suspend and resume process uses the gpio pins. If the device ACPI/DT information does not declare gpio pins, suspend/resume will not be available for these devices. This is based on Goodix datasheets for GT911 and GT9271 and on Goodix driver gt9xx.c for Android (publicly available in Android kernel trees for various devices). Signed-off-by: Octavian Purdila <octavian.purdila@intel.com> Signed-off-by: Irina Tirdea <irina.tirdea@intel.com> Tested-by: Bastien Nocera <hadess@hadess.net> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--drivers/input/touchscreen/goodix.c103
1 files changed, 98 insertions, 5 deletions
diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c
index cd92d8ff3059..34ed68679853 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -45,6 +45,7 @@ struct goodix_ts_data {
45 u16 version; 45 u16 version;
46 const char *cfg_name; 46 const char *cfg_name;
47 struct completion firmware_loading_complete; 47 struct completion firmware_loading_complete;
48 unsigned long irq_flags;
48}; 49};
49 50
50#define GOODIX_GPIO_INT_NAME "irq" 51#define GOODIX_GPIO_INT_NAME "irq"
@@ -61,6 +62,9 @@ struct goodix_ts_data {
61#define GOODIX_CONFIG_967_LENGTH 228 62#define GOODIX_CONFIG_967_LENGTH 228
62 63
63/* Register defines */ 64/* Register defines */
65#define GOODIX_REG_COMMAND 0x8040
66#define GOODIX_CMD_SCREEN_OFF 0x05
67
64#define GOODIX_READ_COOR_ADDR 0x814E 68#define GOODIX_READ_COOR_ADDR 0x814E
65#define GOODIX_REG_CONFIG_DATA 0x8047 69#define GOODIX_REG_CONFIG_DATA 0x8047
66#define GOODIX_REG_ID 0x8140 70#define GOODIX_REG_ID 0x8140
@@ -162,6 +166,11 @@ static int goodix_i2c_write(struct i2c_client *client, u16 reg, const u8 *buf,
162 return ret < 0 ? ret : (ret != 1 ? -EIO : 0); 166 return ret < 0 ? ret : (ret != 1 ? -EIO : 0);
163} 167}
164 168
169static int goodix_i2c_write_u8(struct i2c_client *client, u16 reg, u8 value)
170{
171 return goodix_i2c_write(client, reg, &value, sizeof(value));
172}
173
165static int goodix_get_cfg_len(u16 id) 174static int goodix_get_cfg_len(u16 id)
166{ 175{
167 switch (id) { 176 switch (id) {
@@ -283,6 +292,18 @@ static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id)
283 return IRQ_HANDLED; 292 return IRQ_HANDLED;
284} 293}
285 294
295static void goodix_free_irq(struct goodix_ts_data *ts)
296{
297 devm_free_irq(&ts->client->dev, ts->client->irq, ts);
298}
299
300static int goodix_request_irq(struct goodix_ts_data *ts)
301{
302 return devm_request_threaded_irq(&ts->client->dev, ts->client->irq,
303 NULL, goodix_ts_irq_handler,
304 ts->irq_flags, ts->client->name, ts);
305}
306
286/** 307/**
287 * goodix_check_cfg - Checks if config fw is valid 308 * goodix_check_cfg - Checks if config fw is valid
288 * 309 *
@@ -605,7 +626,6 @@ static int goodix_request_input_dev(struct goodix_ts_data *ts)
605static int goodix_configure_dev(struct goodix_ts_data *ts) 626static int goodix_configure_dev(struct goodix_ts_data *ts)
606{ 627{
607 int error; 628 int error;
608 unsigned long irq_flags;
609 629
610 goodix_read_config(ts); 630 goodix_read_config(ts);
611 631
@@ -613,10 +633,8 @@ static int goodix_configure_dev(struct goodix_ts_data *ts)
613 if (error) 633 if (error)
614 return error; 634 return error;
615 635
616 irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT; 636 ts->irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT;
617 error = devm_request_threaded_irq(&ts->client->dev, ts->client->irq, 637 error = goodix_request_irq(ts);
618 NULL, goodix_ts_irq_handler,
619 irq_flags, ts->client->name, ts);
620 if (error) { 638 if (error) {
621 dev_err(&ts->client->dev, "request IRQ failed: %d\n", error); 639 dev_err(&ts->client->dev, "request IRQ failed: %d\n", error);
622 return error; 640 return error;
@@ -737,6 +755,80 @@ static int goodix_ts_remove(struct i2c_client *client)
737 return 0; 755 return 0;
738} 756}
739 757
758static int __maybe_unused goodix_suspend(struct device *dev)
759{
760 struct i2c_client *client = to_i2c_client(dev);
761 struct goodix_ts_data *ts = i2c_get_clientdata(client);
762 int error;
763
764 /* We need gpio pins to suspend/resume */
765 if (!ts->gpiod_int || !ts->gpiod_rst)
766 return 0;
767
768 wait_for_completion(&ts->firmware_loading_complete);
769
770 /* Free IRQ as IRQ pin is used as output in the suspend sequence */
771 goodix_free_irq(ts);
772
773 /* Output LOW on the INT pin for 5 ms */
774 error = gpiod_direction_output(ts->gpiod_int, 0);
775 if (error) {
776 goodix_request_irq(ts);
777 return error;
778 }
779
780 usleep_range(5000, 6000);
781
782 error = goodix_i2c_write_u8(ts->client, GOODIX_REG_COMMAND,
783 GOODIX_CMD_SCREEN_OFF);
784 if (error) {
785 dev_err(&ts->client->dev, "Screen off command failed\n");
786 gpiod_direction_input(ts->gpiod_int);
787 goodix_request_irq(ts);
788 return -EAGAIN;
789 }
790
791 /*
792 * The datasheet specifies that the interval between sending screen-off
793 * command and wake-up should be longer than 58 ms. To avoid waking up
794 * sooner, delay 58ms here.
795 */
796 msleep(58);
797 return 0;
798}
799
800static int __maybe_unused goodix_resume(struct device *dev)
801{
802 struct i2c_client *client = to_i2c_client(dev);
803 struct goodix_ts_data *ts = i2c_get_clientdata(client);
804 int error;
805
806 if (!ts->gpiod_int || !ts->gpiod_rst)
807 return 0;
808
809 /*
810 * Exit sleep mode by outputting HIGH level to INT pin
811 * for 2ms~5ms.
812 */
813 error = gpiod_direction_output(ts->gpiod_int, 1);
814 if (error)
815 return error;
816
817 usleep_range(2000, 5000);
818
819 error = goodix_int_sync(ts);
820 if (error)
821 return error;
822
823 error = goodix_request_irq(ts);
824 if (error)
825 return error;
826
827 return 0;
828}
829
830static SIMPLE_DEV_PM_OPS(goodix_pm_ops, goodix_suspend, goodix_resume);
831
740static const struct i2c_device_id goodix_ts_id[] = { 832static const struct i2c_device_id goodix_ts_id[] = {
741 { "GDIX1001:00", 0 }, 833 { "GDIX1001:00", 0 },
742 { } 834 { }
@@ -773,6 +865,7 @@ static struct i2c_driver goodix_ts_driver = {
773 .name = "Goodix-TS", 865 .name = "Goodix-TS",
774 .acpi_match_table = ACPI_PTR(goodix_acpi_match), 866 .acpi_match_table = ACPI_PTR(goodix_acpi_match),
775 .of_match_table = of_match_ptr(goodix_of_match), 867 .of_match_table = of_match_ptr(goodix_of_match),
868 .pm = &goodix_pm_ops,
776 }, 869 },
777}; 870};
778module_i2c_driver(goodix_ts_driver); 871module_i2c_driver(goodix_ts_driver);