aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorLothar Waßmann <LW@KARO-electronics.de>2014-03-28 12:23:02 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-03-28 12:33:03 -0400
commitdac90dc23211996286c3b934057d0df77cfef0b4 (patch)
treeddf114d901f257d7f63c60163a529a94bbbf1967 /drivers/input
parent1730d81460b929b1f217cb7d9cb193a7b0e58dd9 (diff)
Input: edt-ft5x06 - add DT support
Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/touchscreen/edt-ft5x06.c145
1 files changed, 114 insertions, 31 deletions
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index 155ab3ba84ee..9d61f1e36b33 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (C) 2012 Simon Budig, <simon.budig@kernelconcepts.de> 2 * Copyright (C) 2012 Simon Budig, <simon.budig@kernelconcepts.de>
3 * Lothar Waßmann <LW@KARO-electronics.de> (DT support)
3 * 4 *
4 * This software is licensed under the terms of the GNU General Public 5 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and 6 * License version 2, as published by the Free Software Foundation, and
@@ -33,6 +34,7 @@
33#include <linux/debugfs.h> 34#include <linux/debugfs.h>
34#include <linux/slab.h> 35#include <linux/slab.h>
35#include <linux/gpio.h> 36#include <linux/gpio.h>
37#include <linux/of_gpio.h>
36#include <linux/input/mt.h> 38#include <linux/input/mt.h>
37#include <linux/input/edt-ft5x06.h> 39#include <linux/input/edt-ft5x06.h>
38 40
@@ -65,6 +67,10 @@ struct edt_ft5x06_ts_data {
65 u16 num_x; 67 u16 num_x;
66 u16 num_y; 68 u16 num_y;
67 69
70 int reset_pin;
71 int irq_pin;
72 int wake_pin;
73
68#if defined(CONFIG_DEBUG_FS) 74#if defined(CONFIG_DEBUG_FS)
69 struct dentry *debug_dir; 75 struct dentry *debug_dir;
70 u8 *raw_buffer; 76 u8 *raw_buffer;
@@ -614,24 +620,38 @@ edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
614#endif /* CONFIG_DEBUGFS */ 620#endif /* CONFIG_DEBUGFS */
615 621
616static int edt_ft5x06_ts_reset(struct i2c_client *client, 622static int edt_ft5x06_ts_reset(struct i2c_client *client,
617 int reset_pin) 623 struct edt_ft5x06_ts_data *tsdata)
618{ 624{
619 int error; 625 int error;
620 626
621 if (gpio_is_valid(reset_pin)) { 627 if (gpio_is_valid(tsdata->wake_pin)) {
628 error = devm_gpio_request_one(&client->dev,
629 tsdata->wake_pin, GPIOF_OUT_INIT_LOW,
630 "edt-ft5x06 wake");
631 if (error) {
632 dev_err(&client->dev,
633 "Failed to request GPIO %d as wake pin, error %d\n",
634 tsdata->wake_pin, error);
635 return error;
636 }
637
638 mdelay(5);
639 gpio_set_value(tsdata->wake_pin, 1);
640 }
641 if (gpio_is_valid(tsdata->reset_pin)) {
622 /* this pulls reset down, enabling the low active reset */ 642 /* this pulls reset down, enabling the low active reset */
623 error = devm_gpio_request_one(&client->dev, reset_pin, 643 error = devm_gpio_request_one(&client->dev,
624 GPIOF_OUT_INIT_LOW, 644 tsdata->reset_pin, GPIOF_OUT_INIT_LOW,
625 "edt-ft5x06 reset"); 645 "edt-ft5x06 reset");
626 if (error) { 646 if (error) {
627 dev_err(&client->dev, 647 dev_err(&client->dev,
628 "Failed to request GPIO %d as reset pin, error %d\n", 648 "Failed to request GPIO %d as reset pin, error %d\n",
629 reset_pin, error); 649 tsdata->reset_pin, error);
630 return error; 650 return error;
631 } 651 }
632 652
633 mdelay(50); 653 mdelay(50);
634 gpio_set_value(reset_pin, 1); 654 gpio_set_value(tsdata->reset_pin, 1);
635 mdelay(100); 655 mdelay(100);
636 } 656 }
637 657
@@ -672,6 +692,20 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client,
672 pdata->name <= edt_ft5x06_attr_##name.limit_high) \ 692 pdata->name <= edt_ft5x06_attr_##name.limit_high) \
673 edt_ft5x06_register_write(tsdata, reg, pdata->name) 693 edt_ft5x06_register_write(tsdata, reg, pdata->name)
674 694
695#define EDT_GET_PROP(name, reg) { \
696 u32 val; \
697 if (of_property_read_u32(np, #name, &val) == 0) \
698 edt_ft5x06_register_write(tsdata, reg, val); \
699}
700
701static void edt_ft5x06_ts_get_dt_defaults(struct device_node *np,
702 struct edt_ft5x06_ts_data *tsdata)
703{
704 EDT_GET_PROP(threshold, WORK_REGISTER_THRESHOLD);
705 EDT_GET_PROP(gain, WORK_REGISTER_GAIN);
706 EDT_GET_PROP(offset, WORK_REGISTER_OFFSET);
707}
708
675static void 709static void
676edt_ft5x06_ts_get_defaults(struct edt_ft5x06_ts_data *tsdata, 710edt_ft5x06_ts_get_defaults(struct edt_ft5x06_ts_data *tsdata,
677 const struct edt_ft5x06_platform_data *pdata) 711 const struct edt_ft5x06_platform_data *pdata)
@@ -699,6 +733,30 @@ edt_ft5x06_ts_get_parameters(struct edt_ft5x06_ts_data *tsdata)
699 tsdata->num_y = edt_ft5x06_register_read(tsdata, WORK_REGISTER_NUM_Y); 733 tsdata->num_y = edt_ft5x06_register_read(tsdata, WORK_REGISTER_NUM_Y);
700} 734}
701 735
736#ifdef CONFIG_OF
737static int edt_ft5x06_i2c_ts_probe_dt(struct device *dev,
738 struct edt_ft5x06_ts_data *tsdata)
739{
740 struct device_node *np = dev->of_node;
741
742 /*
743 * irq_pin is not needed for DT setup.
744 * irq is associated via 'interrupts' property in DT
745 */
746 tsdata->irq_pin = -EINVAL;
747 tsdata->reset_pin = of_get_named_gpio(np, "reset-gpios", 0);
748 tsdata->wake_pin = of_get_named_gpio(np, "wake-gpios", 0);
749
750 return 0;
751}
752#else
753static inline int edt_ft5x06_i2c_ts_probe_dt(struct device *dev,
754 struct edt_ft5x06_ts_data *tsdata)
755{
756 return -ENODEV;
757}
758#endif
759
702static int edt_ft5x06_ts_probe(struct i2c_client *client, 760static int edt_ft5x06_ts_probe(struct i2c_client *client,
703 const struct i2c_device_id *id) 761 const struct i2c_device_id *id)
704{ 762{
@@ -711,32 +769,40 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
711 769
712 dev_dbg(&client->dev, "probing for EDT FT5x06 I2C\n"); 770 dev_dbg(&client->dev, "probing for EDT FT5x06 I2C\n");
713 771
772 tsdata = devm_kzalloc(&client->dev, sizeof(*tsdata), GFP_KERNEL);
773 if (!tsdata) {
774 dev_err(&client->dev, "failed to allocate driver data.\n");
775 return -ENOMEM;
776 }
777
714 if (!pdata) { 778 if (!pdata) {
715 dev_err(&client->dev, "no platform data?\n"); 779 error = edt_ft5x06_i2c_ts_probe_dt(&client->dev, tsdata);
716 return -EINVAL; 780 if (error) {
781 dev_err(&client->dev,
782 "DT probe failed and no platform data present\n");
783 return error;
784 }
785 } else {
786 tsdata->reset_pin = pdata->reset_pin;
787 tsdata->irq_pin = pdata->irq_pin;
788 tsdata->wake_pin = -EINVAL;
717 } 789 }
718 790
719 error = edt_ft5x06_ts_reset(client, pdata->reset_pin); 791 error = edt_ft5x06_ts_reset(client, tsdata);
720 if (error) 792 if (error)
721 return error; 793 return error;
722 794
723 if (gpio_is_valid(pdata->irq_pin)) { 795 if (gpio_is_valid(tsdata->irq_pin)) {
724 error = devm_gpio_request_one(&client->dev, pdata->irq_pin, 796 error = devm_gpio_request_one(&client->dev, tsdata->irq_pin,
725 GPIOF_IN, "edt-ft5x06 irq"); 797 GPIOF_IN, "edt-ft5x06 irq");
726 if (error) { 798 if (error) {
727 dev_err(&client->dev, 799 dev_err(&client->dev,
728 "Failed to request GPIO %d, error %d\n", 800 "Failed to request GPIO %d, error %d\n",
729 pdata->irq_pin, error); 801 tsdata->irq_pin, error);
730 return error; 802 return error;
731 } 803 }
732 } 804 }
733 805
734 tsdata = devm_kzalloc(&client->dev, sizeof(*tsdata), GFP_KERNEL);
735 if (!tsdata) {
736 dev_err(&client->dev, "failed to allocate driver data.\n");
737 return -ENOMEM;
738 }
739
740 input = devm_input_allocate_device(&client->dev); 806 input = devm_input_allocate_device(&client->dev);
741 if (!input) { 807 if (!input) {
742 dev_err(&client->dev, "failed to allocate input device.\n"); 808 dev_err(&client->dev, "failed to allocate input device.\n");
@@ -754,7 +820,11 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
754 return error; 820 return error;
755 } 821 }
756 822
757 edt_ft5x06_ts_get_defaults(tsdata, pdata); 823 if (!pdata)
824 edt_ft5x06_ts_get_dt_defaults(client->dev.of_node, tsdata);
825 else
826 edt_ft5x06_ts_get_defaults(tsdata, pdata);
827
758 edt_ft5x06_ts_get_parameters(tsdata); 828 edt_ft5x06_ts_get_parameters(tsdata);
759 829
760 dev_dbg(&client->dev, 830 dev_dbg(&client->dev,
@@ -784,10 +854,10 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
784 input_set_drvdata(input, tsdata); 854 input_set_drvdata(input, tsdata);
785 i2c_set_clientdata(client, tsdata); 855 i2c_set_clientdata(client, tsdata);
786 856
787 error = devm_request_threaded_irq(&client->dev, client->irq, 857 error = devm_request_threaded_irq(&client->dev, client->irq, NULL,
788 NULL, edt_ft5x06_ts_isr, 858 edt_ft5x06_ts_isr,
789 IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 859 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
790 client->name, tsdata); 860 client->name, tsdata);
791 if (error) { 861 if (error) {
792 dev_err(&client->dev, "Unable to request touchscreen IRQ.\n"); 862 dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
793 return error; 863 return error;
@@ -798,19 +868,21 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
798 return error; 868 return error;
799 869
800 error = input_register_device(input); 870 error = input_register_device(input);
801 if (error) { 871 if (error)
802 sysfs_remove_group(&client->dev.kobj, &edt_ft5x06_attr_group); 872 goto err_remove_attrs;
803 return error;
804 }
805 873
806 edt_ft5x06_ts_prepare_debugfs(tsdata, dev_driver_string(&client->dev)); 874 edt_ft5x06_ts_prepare_debugfs(tsdata, dev_driver_string(&client->dev));
807 device_init_wakeup(&client->dev, 1); 875 device_init_wakeup(&client->dev, 1);
808 876
809 dev_dbg(&client->dev, 877 dev_dbg(&client->dev,
810 "EDT FT5x06 initialized: IRQ pin %d, Reset pin %d.\n", 878 "EDT FT5x06 initialized: IRQ %d, WAKE pin %d, Reset pin %d.\n",
811 pdata->irq_pin, pdata->reset_pin); 879 client->irq, tsdata->wake_pin, tsdata->reset_pin);
812 880
813 return 0; 881 return 0;
882
883err_remove_attrs:
884 sysfs_remove_group(&client->dev.kobj, &edt_ft5x06_attr_group);
885 return error;
814} 886}
815 887
816static int edt_ft5x06_ts_remove(struct i2c_client *client) 888static int edt_ft5x06_ts_remove(struct i2c_client *client)
@@ -854,10 +926,21 @@ static const struct i2c_device_id edt_ft5x06_ts_id[] = {
854}; 926};
855MODULE_DEVICE_TABLE(i2c, edt_ft5x06_ts_id); 927MODULE_DEVICE_TABLE(i2c, edt_ft5x06_ts_id);
856 928
929#ifdef CONFIG_OF
930static const struct of_device_id edt_ft5x06_of_match[] = {
931 { .compatible = "edt,edt-ft5206", },
932 { .compatible = "edt,edt-ft5306", },
933 { .compatible = "edt,edt-ft5406", },
934 { /* sentinel */ }
935};
936MODULE_DEVICE_TABLE(of, edt_ft5x06_of_match);
937#endif
938
857static struct i2c_driver edt_ft5x06_ts_driver = { 939static struct i2c_driver edt_ft5x06_ts_driver = {
858 .driver = { 940 .driver = {
859 .owner = THIS_MODULE, 941 .owner = THIS_MODULE,
860 .name = "edt_ft5x06", 942 .name = "edt_ft5x06",
943 .of_match_table = of_match_ptr(edt_ft5x06_of_match),
861 .pm = &edt_ft5x06_ts_pm_ops, 944 .pm = &edt_ft5x06_ts_pm_ops,
862 }, 945 },
863 .id_table = edt_ft5x06_ts_id, 946 .id_table = edt_ft5x06_ts_id,