diff options
| -rw-r--r-- | arch/m68k/amiga/platform.c | 5 | ||||
| -rw-r--r-- | drivers/input/keyboard/amikbd.c | 97 |
2 files changed, 63 insertions, 39 deletions
diff --git a/arch/m68k/amiga/platform.c b/arch/m68k/amiga/platform.c index 907f6f5f2cac..d427de23c02e 100644 --- a/arch/m68k/amiga/platform.c +++ b/arch/m68k/amiga/platform.c | |||
| @@ -160,6 +160,11 @@ static int __init amiga_init_devices(void) | |||
| 160 | sizeof(a4000_ide_pdata)); | 160 | sizeof(a4000_ide_pdata)); |
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | |||
| 164 | /* other I/O hardware */ | ||
| 165 | if (AMIGAHW_PRESENT(AMI_KEYBOARD)) | ||
| 166 | platform_device_register_simple("amiga-keyboard", -1, NULL, 0); | ||
| 167 | |||
| 163 | return 0; | 168 | return 0; |
| 164 | } | 169 | } |
| 165 | 170 | ||
diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c index 35149ec455a9..79172af164f2 100644 --- a/drivers/input/keyboard/amikbd.c +++ b/drivers/input/keyboard/amikbd.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
| 36 | #include <linux/interrupt.h> | 36 | #include <linux/interrupt.h> |
| 37 | #include <linux/keyboard.h> | 37 | #include <linux/keyboard.h> |
| 38 | #include <linux/platform_device.h> | ||
| 38 | 39 | ||
| 39 | #include <asm/amigaints.h> | 40 | #include <asm/amigaints.h> |
| 40 | #include <asm/amigahw.h> | 41 | #include <asm/amigahw.h> |
| @@ -154,10 +155,9 @@ static const char *amikbd_messages[8] = { | |||
| 154 | [7] = KERN_WARNING "amikbd: keyboard interrupt\n" | 155 | [7] = KERN_WARNING "amikbd: keyboard interrupt\n" |
| 155 | }; | 156 | }; |
| 156 | 157 | ||
| 157 | static struct input_dev *amikbd_dev; | 158 | static irqreturn_t amikbd_interrupt(int irq, void *data) |
| 158 | |||
| 159 | static irqreturn_t amikbd_interrupt(int irq, void *dummy) | ||
| 160 | { | 159 | { |
| 160 | struct input_dev *dev = data; | ||
| 161 | unsigned char scancode, down; | 161 | unsigned char scancode, down; |
| 162 | 162 | ||
| 163 | scancode = ~ciaa.sdr; /* get and invert scancode (keyboard is active low) */ | 163 | scancode = ~ciaa.sdr; /* get and invert scancode (keyboard is active low) */ |
| @@ -170,47 +170,42 @@ static irqreturn_t amikbd_interrupt(int irq, void *dummy) | |||
| 170 | 170 | ||
| 171 | if (scancode < 0x78) { /* scancodes < 0x78 are keys */ | 171 | if (scancode < 0x78) { /* scancodes < 0x78 are keys */ |
| 172 | if (scancode == 98) { /* CapsLock is a toggle switch key on Amiga */ | 172 | if (scancode == 98) { /* CapsLock is a toggle switch key on Amiga */ |
| 173 | input_report_key(amikbd_dev, scancode, 1); | 173 | input_report_key(dev, scancode, 1); |
| 174 | input_report_key(amikbd_dev, scancode, 0); | 174 | input_report_key(dev, scancode, 0); |
| 175 | } else { | 175 | } else { |
| 176 | input_report_key(amikbd_dev, scancode, down); | 176 | input_report_key(dev, scancode, down); |
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | input_sync(amikbd_dev); | 179 | input_sync(dev); |
| 180 | } else /* scancodes >= 0x78 are error codes */ | 180 | } else /* scancodes >= 0x78 are error codes */ |
| 181 | printk(amikbd_messages[scancode - 0x78]); | 181 | printk(amikbd_messages[scancode - 0x78]); |
| 182 | 182 | ||
| 183 | return IRQ_HANDLED; | 183 | return IRQ_HANDLED; |
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | static int __init amikbd_init(void) | 186 | static int __init amikbd_probe(struct platform_device *pdev) |
| 187 | { | 187 | { |
| 188 | struct input_dev *dev; | ||
| 188 | int i, j, err; | 189 | int i, j, err; |
| 189 | 190 | ||
| 190 | if (!AMIGAHW_PRESENT(AMI_KEYBOARD)) | 191 | dev = input_allocate_device(); |
| 191 | return -ENODEV; | 192 | if (!dev) { |
| 192 | 193 | dev_err(&pdev->dev, "Not enough memory for input device\n"); | |
| 193 | if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb")) | 194 | return -ENOMEM; |
| 194 | return -EBUSY; | ||
| 195 | |||
| 196 | amikbd_dev = input_allocate_device(); | ||
| 197 | if (!amikbd_dev) { | ||
| 198 | printk(KERN_ERR "amikbd: not enough memory for input device\n"); | ||
| 199 | err = -ENOMEM; | ||
| 200 | goto fail1; | ||
| 201 | } | 195 | } |
| 202 | 196 | ||
| 203 | amikbd_dev->name = "Amiga Keyboard"; | 197 | dev->name = pdev->name; |
| 204 | amikbd_dev->phys = "amikbd/input0"; | 198 | dev->phys = "amikbd/input0"; |
| 205 | amikbd_dev->id.bustype = BUS_AMIGA; | 199 | dev->id.bustype = BUS_AMIGA; |
| 206 | amikbd_dev->id.vendor = 0x0001; | 200 | dev->id.vendor = 0x0001; |
| 207 | amikbd_dev->id.product = 0x0001; | 201 | dev->id.product = 0x0001; |
| 208 | amikbd_dev->id.version = 0x0100; | 202 | dev->id.version = 0x0100; |
| 203 | dev->dev.parent = &pdev->dev; | ||
| 209 | 204 | ||
| 210 | amikbd_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | 205 | dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); |
| 211 | 206 | ||
| 212 | for (i = 0; i < 0x78; i++) | 207 | for (i = 0; i < 0x78; i++) |
| 213 | set_bit(i, amikbd_dev->keybit); | 208 | set_bit(i, dev->keybit); |
| 214 | 209 | ||
| 215 | for (i = 0; i < MAX_NR_KEYMAPS; i++) { | 210 | for (i = 0; i < MAX_NR_KEYMAPS; i++) { |
| 216 | static u_short temp_map[NR_KEYS] __initdata; | 211 | static u_short temp_map[NR_KEYS] __initdata; |
| @@ -229,30 +224,54 @@ static int __init amikbd_init(void) | |||
| 229 | memcpy(key_maps[i], temp_map, sizeof(temp_map)); | 224 | memcpy(key_maps[i], temp_map, sizeof(temp_map)); |
| 230 | } | 225 | } |
| 231 | ciaa.cra &= ~0x41; /* serial data in, turn off TA */ | 226 | ciaa.cra &= ~0x41; /* serial data in, turn off TA */ |
| 232 | if (request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", | 227 | err = request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", |
| 233 | amikbd_interrupt)) { | 228 | dev); |
| 234 | err = -EBUSY; | 229 | if (err) |
| 235 | goto fail2; | 230 | goto fail2; |
| 236 | } | ||
| 237 | 231 | ||
| 238 | err = input_register_device(amikbd_dev); | 232 | err = input_register_device(dev); |
| 239 | if (err) | 233 | if (err) |
| 240 | goto fail3; | 234 | goto fail3; |
| 241 | 235 | ||
| 236 | platform_set_drvdata(pdev, dev); | ||
| 237 | |||
| 242 | return 0; | 238 | return 0; |
| 243 | 239 | ||
| 244 | fail3: free_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt); | 240 | fail3: free_irq(IRQ_AMIGA_CIAA_SP, dev); |
| 245 | fail2: input_free_device(amikbd_dev); | 241 | fail2: input_free_device(dev); |
| 246 | fail1: release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100); | ||
| 247 | return err; | 242 | return err; |
| 248 | } | 243 | } |
| 249 | 244 | ||
| 250 | static void __exit amikbd_exit(void) | 245 | static int __exit amikbd_remove(struct platform_device *pdev) |
| 246 | { | ||
| 247 | struct input_dev *dev = platform_get_drvdata(pdev); | ||
| 248 | |||
| 249 | platform_set_drvdata(pdev, NULL); | ||
| 250 | free_irq(IRQ_AMIGA_CIAA_SP, dev); | ||
| 251 | input_unregister_device(dev); | ||
| 252 | return 0; | ||
| 253 | } | ||
| 254 | |||
| 255 | static struct platform_driver amikbd_driver = { | ||
| 256 | .remove = __exit_p(amikbd_remove), | ||
| 257 | .driver = { | ||
| 258 | .name = "amiga-keyboard", | ||
| 259 | .owner = THIS_MODULE, | ||
| 260 | }, | ||
| 261 | }; | ||
| 262 | |||
| 263 | static int __init amikbd_init(void) | ||
| 251 | { | 264 | { |
| 252 | free_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt); | 265 | return platform_driver_probe(&amikbd_driver, amikbd_probe); |
| 253 | input_unregister_device(amikbd_dev); | ||
| 254 | release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100); | ||
| 255 | } | 266 | } |
| 256 | 267 | ||
| 257 | module_init(amikbd_init); | 268 | module_init(amikbd_init); |
| 269 | |||
| 270 | static void __exit amikbd_exit(void) | ||
| 271 | { | ||
| 272 | platform_driver_unregister(&amikbd_driver); | ||
| 273 | } | ||
| 274 | |||
| 258 | module_exit(amikbd_exit); | 275 | module_exit(amikbd_exit); |
| 276 | |||
| 277 | MODULE_ALIAS("platform:amiga-keyboard"); | ||
