aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen
diff options
context:
space:
mode:
authorEric Miao <eric.y.miao@gmail.com>2008-09-10 12:06:15 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2008-09-10 12:13:28 -0400
commit4d5975e5016a9025814b92981de21eaf9203caa6 (patch)
treed1bc92acac3db21a5e92795ed7802f3776acb0bd /drivers/input/touchscreen
parent0d46ed1c747edfe6476961d4d9f732ceb7a29074 (diff)
Input: ads7846 - introduce .gpio_pendown to get pendown state
The GPIO connected to ADS7846 nPENIRQ signal is usually used to get the pendown state as well. Introduce a .gpio_pendown, and use this to decide the pendown state if .get_pendown_state is NULL. Signed-off-by: Eric Miao <eric.miao@marvell.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r--drivers/input/touchscreen/ads7846.c68
1 files changed, 54 insertions, 14 deletions
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index efbbbe48621a..6020a7dcce33 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -24,6 +24,7 @@
24#include <linux/input.h> 24#include <linux/input.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/gpio.h>
27#include <linux/spi/spi.h> 28#include <linux/spi/spi.h>
28#include <linux/spi/ads7846.h> 29#include <linux/spi/ads7846.h>
29#include <asm/irq.h> 30#include <asm/irq.h>
@@ -116,6 +117,7 @@ struct ads7846 {
116 void *filter_data; 117 void *filter_data;
117 void (*filter_cleanup)(void *data); 118 void (*filter_cleanup)(void *data);
118 int (*get_pendown_state)(void); 119 int (*get_pendown_state)(void);
120 int gpio_pendown;
119}; 121};
120 122
121/* leave chip selected when we're done, for quicker re-select? */ 123/* leave chip selected when we're done, for quicker re-select? */
@@ -492,6 +494,14 @@ static struct attribute_group ads784x_attr_group = {
492 494
493/*--------------------------------------------------------------------------*/ 495/*--------------------------------------------------------------------------*/
494 496
497static int get_pendown_state(struct ads7846 *ts)
498{
499 if (ts->get_pendown_state)
500 return ts->get_pendown_state();
501
502 return !gpio_get_value(ts->gpio_pendown);
503}
504
495/* 505/*
496 * PENIRQ only kicks the timer. The timer only reissues the SPI transfer, 506 * PENIRQ only kicks the timer. The timer only reissues the SPI transfer,
497 * to retrieve touchscreen status. 507 * to retrieve touchscreen status.
@@ -551,7 +561,7 @@ static void ads7846_rx(void *ads)
551 */ 561 */
552 if (ts->penirq_recheck_delay_usecs) { 562 if (ts->penirq_recheck_delay_usecs) {
553 udelay(ts->penirq_recheck_delay_usecs); 563 udelay(ts->penirq_recheck_delay_usecs);
554 if (!ts->get_pendown_state()) 564 if (!get_pendown_state(ts))
555 Rt = 0; 565 Rt = 0;
556 } 566 }
557 567
@@ -678,7 +688,7 @@ static enum hrtimer_restart ads7846_timer(struct hrtimer *handle)
678 688
679 spin_lock_irq(&ts->lock); 689 spin_lock_irq(&ts->lock);
680 690
681 if (unlikely(!ts->get_pendown_state() || 691 if (unlikely(!get_pendown_state(ts) ||
682 device_suspended(&ts->spi->dev))) { 692 device_suspended(&ts->spi->dev))) {
683 if (ts->pendown) { 693 if (ts->pendown) {
684 struct input_dev *input = ts->input; 694 struct input_dev *input = ts->input;
@@ -717,7 +727,7 @@ static irqreturn_t ads7846_irq(int irq, void *handle)
717 unsigned long flags; 727 unsigned long flags;
718 728
719 spin_lock_irqsave(&ts->lock, flags); 729 spin_lock_irqsave(&ts->lock, flags);
720 if (likely(ts->get_pendown_state())) { 730 if (likely(get_pendown_state(ts))) {
721 if (!ts->irq_disabled) { 731 if (!ts->irq_disabled) {
722 /* The ARM do_simple_IRQ() dispatcher doesn't act 732 /* The ARM do_simple_IRQ() dispatcher doesn't act
723 * like the other dispatchers: it will report IRQs 733 * like the other dispatchers: it will report IRQs
@@ -807,6 +817,36 @@ static int ads7846_resume(struct spi_device *spi)
807 return 0; 817 return 0;
808} 818}
809 819
820static int __devinit setup_pendown(struct spi_device *spi, struct ads7846 *ts)
821{
822 struct ads7846_platform_data *pdata = spi->dev.platform_data;
823 int err;
824
825 /* REVISIT when the irq can be triggered active-low, or if for some
826 * reason the touchscreen isn't hooked up, we don't need to access
827 * the pendown state.
828 */
829 if (!pdata->get_pendown_state && !gpio_is_valid(pdata->gpio_pendown)) {
830 dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n");
831 return -EINVAL;
832 }
833
834 if (pdata->get_pendown_state) {
835 ts->get_pendown_state = pdata->get_pendown_state;
836 return 0;
837 }
838
839 err = gpio_request(pdata->gpio_pendown, "ads7846_pendown");
840 if (err) {
841 dev_err(&spi->dev, "failed to request pendown GPIO%d\n",
842 pdata->gpio_pendown);
843 return err;
844 }
845
846 ts->gpio_pendown = pdata->gpio_pendown;
847 return 0;
848}
849
810static int __devinit ads7846_probe(struct spi_device *spi) 850static int __devinit ads7846_probe(struct spi_device *spi)
811{ 851{
812 struct ads7846 *ts; 852 struct ads7846 *ts;
@@ -834,15 +874,6 @@ static int __devinit ads7846_probe(struct spi_device *spi)
834 return -EINVAL; 874 return -EINVAL;
835 } 875 }
836 876
837 /* REVISIT when the irq can be triggered active-low, or if for some
838 * reason the touchscreen isn't hooked up, we don't need to access
839 * the pendown state.
840 */
841 if (pdata->get_pendown_state == NULL) {
842 dev_dbg(&spi->dev, "no get_pendown_state function?\n");
843 return -EINVAL;
844 }
845
846 /* We'd set TX wordsize 8 bits and RX wordsize to 13 bits ... except 877 /* We'd set TX wordsize 8 bits and RX wordsize to 13 bits ... except
847 * that even if the hardware can do that, the SPI controller driver 878 * that even if the hardware can do that, the SPI controller driver
848 * may not. So we stick to very-portable 8 bit words, both RX and TX. 879 * may not. So we stick to very-portable 8 bit words, both RX and TX.
@@ -894,7 +925,10 @@ static int __devinit ads7846_probe(struct spi_device *spi)
894 ts->filter_data = ts; 925 ts->filter_data = ts;
895 } else 926 } else
896 ts->filter = ads7846_no_filter; 927 ts->filter = ads7846_no_filter;
897 ts->get_pendown_state = pdata->get_pendown_state; 928
929 err = setup_pendown(spi, ts);
930 if (err)
931 goto err_cleanup_filter;
898 932
899 if (pdata->penirq_recheck_delay_usecs) 933 if (pdata->penirq_recheck_delay_usecs)
900 ts->penirq_recheck_delay_usecs = 934 ts->penirq_recheck_delay_usecs =
@@ -1086,7 +1120,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1086 spi->dev.driver->name, ts)) { 1120 spi->dev.driver->name, ts)) {
1087 dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); 1121 dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
1088 err = -EBUSY; 1122 err = -EBUSY;
1089 goto err_cleanup_filter; 1123 goto err_free_gpio;
1090 } 1124 }
1091 1125
1092 err = ads784x_hwmon_register(spi, ts); 1126 err = ads784x_hwmon_register(spi, ts);
@@ -1117,6 +1151,9 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1117 ads784x_hwmon_unregister(spi, ts); 1151 ads784x_hwmon_unregister(spi, ts);
1118 err_free_irq: 1152 err_free_irq:
1119 free_irq(spi->irq, ts); 1153 free_irq(spi->irq, ts);
1154 err_free_gpio:
1155 if (ts->gpio_pendown != -1)
1156 gpio_free(ts->gpio_pendown);
1120 err_cleanup_filter: 1157 err_cleanup_filter:
1121 if (ts->filter_cleanup) 1158 if (ts->filter_cleanup)
1122 ts->filter_cleanup(ts->filter_data); 1159 ts->filter_cleanup(ts->filter_data);
@@ -1141,6 +1178,9 @@ static int __devexit ads7846_remove(struct spi_device *spi)
1141 /* suspend left the IRQ disabled */ 1178 /* suspend left the IRQ disabled */
1142 enable_irq(ts->spi->irq); 1179 enable_irq(ts->spi->irq);
1143 1180
1181 if (ts->gpio_pendown != -1)
1182 gpio_free(ts->gpio_pendown);
1183
1144 if (ts->filter_cleanup) 1184 if (ts->filter_cleanup)
1145 ts->filter_cleanup(ts->filter_data); 1185 ts->filter_cleanup(ts->filter_data);
1146 1186