diff options
Diffstat (limited to 'drivers/input/mouse/inport.c')
-rw-r--r-- | drivers/input/mouse/inport.c | 96 |
1 files changed, 49 insertions, 47 deletions
diff --git a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c index 1f62c0134010..afc66f56df43 100644 --- a/drivers/input/mouse/inport.c +++ b/drivers/input/mouse/inport.c | |||
@@ -87,40 +87,7 @@ MODULE_PARM_DESC(irq, "IRQ number (5=default)"); | |||
87 | 87 | ||
88 | __obsolete_setup("inport_irq="); | 88 | __obsolete_setup("inport_irq="); |
89 | 89 | ||
90 | static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs); | 90 | static struct input_dev *inport_dev; |
91 | |||
92 | static int inport_open(struct input_dev *dev) | ||
93 | { | ||
94 | if (request_irq(inport_irq, inport_interrupt, 0, "inport", NULL)) | ||
95 | return -EBUSY; | ||
96 | outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); | ||
97 | outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT); | ||
98 | |||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | static void inport_close(struct input_dev *dev) | ||
103 | { | ||
104 | outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); | ||
105 | outb(INPORT_MODE_BASE, INPORT_DATA_PORT); | ||
106 | free_irq(inport_irq, NULL); | ||
107 | } | ||
108 | |||
109 | static struct input_dev inport_dev = { | ||
110 | .evbit = { BIT(EV_KEY) | BIT(EV_REL) }, | ||
111 | .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT) }, | ||
112 | .relbit = { BIT(REL_X) | BIT(REL_Y) }, | ||
113 | .open = inport_open, | ||
114 | .close = inport_close, | ||
115 | .name = INPORT_NAME, | ||
116 | .phys = "isa023c/input0", | ||
117 | .id = { | ||
118 | .bustype = BUS_ISA, | ||
119 | .vendor = INPORT_VENDOR, | ||
120 | .product = 0x0001, | ||
121 | .version = 0x0100, | ||
122 | }, | ||
123 | }; | ||
124 | 91 | ||
125 | static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 92 | static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
126 | { | 93 | { |
@@ -129,31 +96,48 @@ static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
129 | outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); | 96 | outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); |
130 | outb(INPORT_MODE_HOLD | INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT); | 97 | outb(INPORT_MODE_HOLD | INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT); |
131 | 98 | ||
132 | input_regs(&inport_dev, regs); | 99 | input_regs(inport_dev, regs); |
133 | 100 | ||
134 | outb(INPORT_REG_X, INPORT_CONTROL_PORT); | 101 | outb(INPORT_REG_X, INPORT_CONTROL_PORT); |
135 | input_report_rel(&inport_dev, REL_X, inb(INPORT_DATA_PORT)); | 102 | input_report_rel(inport_dev, REL_X, inb(INPORT_DATA_PORT)); |
136 | 103 | ||
137 | outb(INPORT_REG_Y, INPORT_CONTROL_PORT); | 104 | outb(INPORT_REG_Y, INPORT_CONTROL_PORT); |
138 | input_report_rel(&inport_dev, REL_Y, inb(INPORT_DATA_PORT)); | 105 | input_report_rel(inport_dev, REL_Y, inb(INPORT_DATA_PORT)); |
139 | 106 | ||
140 | outb(INPORT_REG_BTNS, INPORT_CONTROL_PORT); | 107 | outb(INPORT_REG_BTNS, INPORT_CONTROL_PORT); |
141 | buttons = inb(INPORT_DATA_PORT); | 108 | buttons = inb(INPORT_DATA_PORT); |
142 | 109 | ||
143 | input_report_key(&inport_dev, BTN_MIDDLE, buttons & 1); | 110 | input_report_key(inport_dev, BTN_MIDDLE, buttons & 1); |
144 | input_report_key(&inport_dev, BTN_LEFT, buttons & 2); | 111 | input_report_key(inport_dev, BTN_LEFT, buttons & 2); |
145 | input_report_key(&inport_dev, BTN_RIGHT, buttons & 4); | 112 | input_report_key(inport_dev, BTN_RIGHT, buttons & 4); |
146 | 113 | ||
147 | outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); | 114 | outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); |
148 | outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT); | 115 | outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT); |
149 | 116 | ||
150 | input_sync(&inport_dev); | 117 | input_sync(inport_dev); |
151 | return IRQ_HANDLED; | 118 | return IRQ_HANDLED; |
152 | } | 119 | } |
153 | 120 | ||
121 | static int inport_open(struct input_dev *dev) | ||
122 | { | ||
123 | if (request_irq(inport_irq, inport_interrupt, 0, "inport", NULL)) | ||
124 | return -EBUSY; | ||
125 | outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); | ||
126 | outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT); | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static void inport_close(struct input_dev *dev) | ||
132 | { | ||
133 | outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); | ||
134 | outb(INPORT_MODE_BASE, INPORT_DATA_PORT); | ||
135 | free_irq(inport_irq, NULL); | ||
136 | } | ||
137 | |||
154 | static int __init inport_init(void) | 138 | static int __init inport_init(void) |
155 | { | 139 | { |
156 | unsigned char a,b,c; | 140 | unsigned char a, b, c; |
157 | 141 | ||
158 | if (!request_region(INPORT_BASE, INPORT_EXTENT, "inport")) { | 142 | if (!request_region(INPORT_BASE, INPORT_EXTENT, "inport")) { |
159 | printk(KERN_ERR "inport.c: Can't allocate ports at %#x\n", INPORT_BASE); | 143 | printk(KERN_ERR "inport.c: Can't allocate ports at %#x\n", INPORT_BASE); |
@@ -163,26 +147,44 @@ static int __init inport_init(void) | |||
163 | a = inb(INPORT_SIGNATURE_PORT); | 147 | a = inb(INPORT_SIGNATURE_PORT); |
164 | b = inb(INPORT_SIGNATURE_PORT); | 148 | b = inb(INPORT_SIGNATURE_PORT); |
165 | c = inb(INPORT_SIGNATURE_PORT); | 149 | c = inb(INPORT_SIGNATURE_PORT); |
166 | if (( a == b ) || ( a != c )) { | 150 | if (a == b || a != c) { |
167 | release_region(INPORT_BASE, INPORT_EXTENT); | 151 | release_region(INPORT_BASE, INPORT_EXTENT); |
168 | printk(KERN_ERR "inport.c: Didn't find InPort mouse at %#x\n", INPORT_BASE); | 152 | printk(KERN_ERR "inport.c: Didn't find InPort mouse at %#x\n", INPORT_BASE); |
169 | return -ENODEV; | 153 | return -ENODEV; |
170 | } | 154 | } |
171 | 155 | ||
156 | if (!(inport_dev = input_allocate_device())) { | ||
157 | printk(KERN_ERR "inport.c: Not enough memory for input device\n"); | ||
158 | release_region(INPORT_BASE, INPORT_EXTENT); | ||
159 | return -ENOMEM; | ||
160 | } | ||
161 | |||
162 | inport_dev->name = INPORT_NAME; | ||
163 | inport_dev->phys = "isa023c/input0"; | ||
164 | inport_dev->id.bustype = BUS_ISA; | ||
165 | inport_dev->id.vendor = INPORT_VENDOR; | ||
166 | inport_dev->id.product = 0x0001; | ||
167 | inport_dev->id.version = 0x0100; | ||
168 | |||
169 | inport_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); | ||
170 | inport_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); | ||
171 | inport_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); | ||
172 | |||
173 | inport_dev->open = inport_open; | ||
174 | inport_dev->close = inport_close; | ||
175 | |||
172 | outb(INPORT_RESET, INPORT_CONTROL_PORT); | 176 | outb(INPORT_RESET, INPORT_CONTROL_PORT); |
173 | outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); | 177 | outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); |
174 | outb(INPORT_MODE_BASE, INPORT_DATA_PORT); | 178 | outb(INPORT_MODE_BASE, INPORT_DATA_PORT); |
175 | 179 | ||
176 | input_register_device(&inport_dev); | 180 | input_register_device(inport_dev); |
177 | |||
178 | printk(KERN_INFO "input: " INPORT_NAME " at %#x irq %d\n", INPORT_BASE, inport_irq); | ||
179 | 181 | ||
180 | return 0; | 182 | return 0; |
181 | } | 183 | } |
182 | 184 | ||
183 | static void __exit inport_exit(void) | 185 | static void __exit inport_exit(void) |
184 | { | 186 | { |
185 | input_unregister_device(&inport_dev); | 187 | input_unregister_device(inport_dev); |
186 | release_region(INPORT_BASE, INPORT_EXTENT); | 188 | release_region(INPORT_BASE, INPORT_EXTENT); |
187 | } | 189 | } |
188 | 190 | ||