]> Pileus Git - ~andy/linux/blobdiff - drivers/input/touchscreen/ucb1400_ts.c
Input: ucb1400_ts - IRQ probe fix
[~andy/linux] / drivers / input / touchscreen / ucb1400_ts.c
index 5200f4cbfe01d69f15252299f1c0f2fdcb8ec713..bce018e45bce4781cb7b61519485502ff8c22171 100644 (file)
@@ -15,7 +15,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
@@ -27,7 +26,6 @@
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 
-#include <sound/driver.h>
 #include <sound/core.h>
 #include <sound/ac97_codec.h>
 
@@ -97,6 +95,8 @@ struct ucb1400 {
 };
 
 static int adcsync;
+static int ts_delay = 55; /* us */
+static int ts_delay_pressure;  /* us */
 
 static inline u16 ucb1400_reg_read(struct ucb1400 *ucb, u16 reg)
 {
@@ -128,8 +128,7 @@ static unsigned int ucb1400_adc_read(struct ucb1400 *ucb, u16 adc_channel)
                if (val & UCB_ADC_DAT_VALID)
                        break;
                /* yield to other processes */
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        }
 
        return UCB_ADC_DAT_VALUE(val);
@@ -159,6 +158,7 @@ static inline unsigned int ucb1400_ts_read_pressure(struct ucb1400 *ucb)
                        UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
                        UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
                        UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
+       udelay(ts_delay_pressure);
        return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPY);
 }
 
@@ -180,7 +180,7 @@ static inline unsigned int ucb1400_ts_read_xpos(struct ucb1400 *ucb)
                        UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
                        UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
 
-       udelay(55);
+       udelay(ts_delay);
 
        return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPY);
 }
@@ -203,7 +203,7 @@ static inline unsigned int ucb1400_ts_read_ypos(struct ucb1400 *ucb)
                        UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
                        UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
 
-       udelay(55);
+       udelay(ts_delay);
 
        return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPX);
 }
@@ -285,10 +285,11 @@ static int ucb1400_ts_thread(void *_ucb)
        struct ucb1400 *ucb = _ucb;
        struct task_struct *tsk = current;
        int valid = 0;
+       struct sched_param param = { .sched_priority = 1 };
 
-       tsk->policy = SCHED_FIFO;
-       tsk->rt_priority = 1;
+       sched_setscheduler(tsk, SCHED_FIFO, &param);
 
+       set_freezable();
        while (!kthread_should_stop()) {
                unsigned int x, y, p;
                long timeout;
@@ -330,10 +331,9 @@ static int ucb1400_ts_thread(void *_ucb)
                        timeout = msecs_to_jiffies(10);
                }
 
-               wait_event_interruptible_timeout(ucb->ts_wait,
+               wait_event_freezable_timeout(ucb->ts_wait,
                        ucb->irq_pending || ucb->ts_restart || kthread_should_stop(),
                        timeout);
-               try_to_freeze();
        }
 
        /* Send the "pen off" if we are stopping with the pen still active */
@@ -427,10 +427,6 @@ static int ucb1400_detect_irq(struct ucb1400 *ucb)
        unsigned long mask, timeout;
 
        mask = probe_irq_on();
-       if (!mask) {
-               probe_irq_off(mask);
-               return -EBUSY;
-       }
 
        /* Enable the ADC interrupt. */
        ucb1400_reg_write(ucb, UCB_IE_RIS, UCB_IE_ADC);
@@ -515,7 +511,7 @@ static int ucb1400_ts_probe(struct device *dev)
        idev->id.product        = id;
        idev->open              = ucb1400_ts_open;
        idev->close             = ucb1400_ts_close;
-       idev->evbit[0]          = BIT(EV_ABS);
+       idev->evbit[0]          = BIT_MASK(EV_ABS);
 
        ucb1400_adc_enable(ucb);
        x_res = ucb1400_ts_read_xres(ucb);
@@ -554,6 +550,7 @@ static int ucb1400_ts_remove(struct device *dev)
 }
 
 static struct device_driver ucb1400_ts_driver = {
+       .name           = "ucb1400_ts",
        .owner          = THIS_MODULE,
        .bus            = &ac97_bus_type,
        .probe          = ucb1400_ts_probe,
@@ -571,7 +568,15 @@ static void __exit ucb1400_ts_exit(void)
        driver_unregister(&ucb1400_ts_driver);
 }
 
-module_param(adcsync, int, 0444);
+module_param(adcsync, bool, 0444);
+MODULE_PARM_DESC(adcsync, "Synchronize touch readings with ADCSYNC pin.");
+
+module_param(ts_delay, int, 0444);
+MODULE_PARM_DESC(ts_delay, "Delay between panel setup and position read. Default = 55us.");
+
+module_param(ts_delay_pressure, int, 0444);
+MODULE_PARM_DESC(ts_delay_pressure,
+                 "delay between panel setup and pressure read.  Default = 0us.");
 
 module_init(ucb1400_ts_init);
 module_exit(ucb1400_ts_exit);