aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/serio/sa1111ps2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/serio/sa1111ps2.c')
-rw-r--r--drivers/input/serio/sa1111ps2.c59
1 files changed, 42 insertions, 17 deletions
diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
index 44fc8b4bcd81..5ebabe3fc845 100644
--- a/drivers/input/serio/sa1111ps2.c
+++ b/drivers/input/serio/sa1111ps2.c
@@ -24,6 +24,26 @@
24 24
25#include <asm/hardware/sa1111.h> 25#include <asm/hardware/sa1111.h>
26 26
27#define PS2CR 0x0000
28#define PS2STAT 0x0004
29#define PS2DATA 0x0008
30#define PS2CLKDIV 0x000c
31#define PS2PRECNT 0x0010
32
33#define PS2CR_ENA 0x08
34#define PS2CR_FKD 0x02
35#define PS2CR_FKC 0x01
36
37#define PS2STAT_STP 0x0100
38#define PS2STAT_TXE 0x0080
39#define PS2STAT_TXB 0x0040
40#define PS2STAT_RXF 0x0020
41#define PS2STAT_RXB 0x0010
42#define PS2STAT_ENA 0x0008
43#define PS2STAT_RXP 0x0004
44#define PS2STAT_KBD 0x0002
45#define PS2STAT_KBC 0x0001
46
27struct ps2if { 47struct ps2if {
28 struct serio *io; 48 struct serio *io;
29 struct sa1111_dev *dev; 49 struct sa1111_dev *dev;
@@ -45,22 +65,22 @@ static irqreturn_t ps2_rxint(int irq, void *dev_id)
45 struct ps2if *ps2if = dev_id; 65 struct ps2if *ps2if = dev_id;
46 unsigned int scancode, flag, status; 66 unsigned int scancode, flag, status;
47 67
48 status = sa1111_readl(ps2if->base + SA1111_PS2STAT); 68 status = sa1111_readl(ps2if->base + PS2STAT);
49 while (status & PS2STAT_RXF) { 69 while (status & PS2STAT_RXF) {
50 if (status & PS2STAT_STP) 70 if (status & PS2STAT_STP)
51 sa1111_writel(PS2STAT_STP, ps2if->base + SA1111_PS2STAT); 71 sa1111_writel(PS2STAT_STP, ps2if->base + PS2STAT);
52 72
53 flag = (status & PS2STAT_STP ? SERIO_FRAME : 0) | 73 flag = (status & PS2STAT_STP ? SERIO_FRAME : 0) |
54 (status & PS2STAT_RXP ? 0 : SERIO_PARITY); 74 (status & PS2STAT_RXP ? 0 : SERIO_PARITY);
55 75
56 scancode = sa1111_readl(ps2if->base + SA1111_PS2DATA) & 0xff; 76 scancode = sa1111_readl(ps2if->base + PS2DATA) & 0xff;
57 77
58 if (hweight8(scancode) & 1) 78 if (hweight8(scancode) & 1)
59 flag ^= SERIO_PARITY; 79 flag ^= SERIO_PARITY;
60 80
61 serio_interrupt(ps2if->io, scancode, flag); 81 serio_interrupt(ps2if->io, scancode, flag);
62 82
63 status = sa1111_readl(ps2if->base + SA1111_PS2STAT); 83 status = sa1111_readl(ps2if->base + PS2STAT);
64 } 84 }
65 85
66 return IRQ_HANDLED; 86 return IRQ_HANDLED;
@@ -75,12 +95,12 @@ static irqreturn_t ps2_txint(int irq, void *dev_id)
75 unsigned int status; 95 unsigned int status;
76 96
77 spin_lock(&ps2if->lock); 97 spin_lock(&ps2if->lock);
78 status = sa1111_readl(ps2if->base + SA1111_PS2STAT); 98 status = sa1111_readl(ps2if->base + PS2STAT);
79 if (ps2if->head == ps2if->tail) { 99 if (ps2if->head == ps2if->tail) {
80 disable_irq_nosync(irq); 100 disable_irq_nosync(irq);
81 /* done */ 101 /* done */
82 } else if (status & PS2STAT_TXE) { 102 } else if (status & PS2STAT_TXE) {
83 sa1111_writel(ps2if->buf[ps2if->tail], ps2if->base + SA1111_PS2DATA); 103 sa1111_writel(ps2if->buf[ps2if->tail], ps2if->base + PS2DATA);
84 ps2if->tail = (ps2if->tail + 1) & (sizeof(ps2if->buf) - 1); 104 ps2if->tail = (ps2if->tail + 1) & (sizeof(ps2if->buf) - 1);
85 } 105 }
86 spin_unlock(&ps2if->lock); 106 spin_unlock(&ps2if->lock);
@@ -103,8 +123,8 @@ static int ps2_write(struct serio *io, unsigned char val)
103 /* 123 /*
104 * If the TX register is empty, we can go straight out. 124 * If the TX register is empty, we can go straight out.
105 */ 125 */
106 if (sa1111_readl(ps2if->base + SA1111_PS2STAT) & PS2STAT_TXE) { 126 if (sa1111_readl(ps2if->base + PS2STAT) & PS2STAT_TXE) {
107 sa1111_writel(val, ps2if->base + SA1111_PS2DATA); 127 sa1111_writel(val, ps2if->base + PS2DATA);
108 } else { 128 } else {
109 if (ps2if->head == ps2if->tail) 129 if (ps2if->head == ps2if->tail)
110 enable_irq(ps2if->dev->irq[1]); 130 enable_irq(ps2if->dev->irq[1]);
@@ -124,13 +144,16 @@ static int ps2_open(struct serio *io)
124 struct ps2if *ps2if = io->port_data; 144 struct ps2if *ps2if = io->port_data;
125 int ret; 145 int ret;
126 146
127 sa1111_enable_device(ps2if->dev); 147 ret = sa1111_enable_device(ps2if->dev);
148 if (ret)
149 return ret;
128 150
129 ret = request_irq(ps2if->dev->irq[0], ps2_rxint, 0, 151 ret = request_irq(ps2if->dev->irq[0], ps2_rxint, 0,
130 SA1111_DRIVER_NAME(ps2if->dev), ps2if); 152 SA1111_DRIVER_NAME(ps2if->dev), ps2if);
131 if (ret) { 153 if (ret) {
132 printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n", 154 printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n",
133 ps2if->dev->irq[0], ret); 155 ps2if->dev->irq[0], ret);
156 sa1111_disable_device(ps2if->dev);
134 return ret; 157 return ret;
135 } 158 }
136 159
@@ -140,6 +163,7 @@ static int ps2_open(struct serio *io)
140 printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n", 163 printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n",
141 ps2if->dev->irq[1], ret); 164 ps2if->dev->irq[1], ret);
142 free_irq(ps2if->dev->irq[0], ps2if); 165 free_irq(ps2if->dev->irq[0], ps2if);
166 sa1111_disable_device(ps2if->dev);
143 return ret; 167 return ret;
144 } 168 }
145 169
@@ -147,7 +171,7 @@ static int ps2_open(struct serio *io)
147 171
148 enable_irq_wake(ps2if->dev->irq[0]); 172 enable_irq_wake(ps2if->dev->irq[0]);
149 173
150 sa1111_writel(PS2CR_ENA, ps2if->base + SA1111_PS2CR); 174 sa1111_writel(PS2CR_ENA, ps2if->base + PS2CR);
151 return 0; 175 return 0;
152} 176}
153 177
@@ -155,7 +179,7 @@ static void ps2_close(struct serio *io)
155{ 179{
156 struct ps2if *ps2if = io->port_data; 180 struct ps2if *ps2if = io->port_data;
157 181
158 sa1111_writel(0, ps2if->base + SA1111_PS2CR); 182 sa1111_writel(0, ps2if->base + PS2CR);
159 183
160 disable_irq_wake(ps2if->dev->irq[0]); 184 disable_irq_wake(ps2if->dev->irq[0]);
161 185
@@ -175,7 +199,7 @@ static void __devinit ps2_clear_input(struct ps2if *ps2if)
175 int maxread = 100; 199 int maxread = 100;
176 200
177 while (maxread--) { 201 while (maxread--) {
178 if ((sa1111_readl(ps2if->base + SA1111_PS2DATA) & 0xff) == 0xff) 202 if ((sa1111_readl(ps2if->base + PS2DATA) & 0xff) == 0xff)
179 break; 203 break;
180 } 204 }
181} 205}
@@ -185,11 +209,11 @@ static unsigned int __devinit ps2_test_one(struct ps2if *ps2if,
185{ 209{
186 unsigned int val; 210 unsigned int val;
187 211
188 sa1111_writel(PS2CR_ENA | mask, ps2if->base + SA1111_PS2CR); 212 sa1111_writel(PS2CR_ENA | mask, ps2if->base + PS2CR);
189 213
190 udelay(2); 214 udelay(2);
191 215
192 val = sa1111_readl(ps2if->base + SA1111_PS2STAT); 216 val = sa1111_readl(ps2if->base + PS2STAT);
193 return val & (PS2STAT_KBC | PS2STAT_KBD); 217 return val & (PS2STAT_KBC | PS2STAT_KBD);
194} 218}
195 219
@@ -220,7 +244,7 @@ static int __devinit ps2_test(struct ps2if *ps2if)
220 ret = -ENODEV; 244 ret = -ENODEV;
221 } 245 }
222 246
223 sa1111_writel(0, ps2if->base + SA1111_PS2CR); 247 sa1111_writel(0, ps2if->base + PS2CR);
224 248
225 return ret; 249 return ret;
226} 250}
@@ -274,8 +298,8 @@ static int __devinit ps2_probe(struct sa1111_dev *dev)
274 sa1111_enable_device(ps2if->dev); 298 sa1111_enable_device(ps2if->dev);
275 299
276 /* Incoming clock is 8MHz */ 300 /* Incoming clock is 8MHz */
277 sa1111_writel(0, ps2if->base + SA1111_PS2CLKDIV); 301 sa1111_writel(0, ps2if->base + PS2CLKDIV);
278 sa1111_writel(127, ps2if->base + SA1111_PS2PRECNT); 302 sa1111_writel(127, ps2if->base + PS2PRECNT);
279 303
280 /* 304 /*
281 * Flush any pending input. 305 * Flush any pending input.
@@ -330,6 +354,7 @@ static int __devexit ps2_remove(struct sa1111_dev *dev)
330static struct sa1111_driver ps2_driver = { 354static struct sa1111_driver ps2_driver = {
331 .drv = { 355 .drv = {
332 .name = "sa1111-ps2", 356 .name = "sa1111-ps2",
357 .owner = THIS_MODULE,
333 }, 358 },
334 .devid = SA1111_DEVID_PS2, 359 .devid = SA1111_DEVID_PS2,
335 .probe = ps2_probe, 360 .probe = ps2_probe,