2 * Driver for simulating a mouse on GPIO lines.
4 * Copyright (C) 2007 Atmel Corporation
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 #include <linux/init.h>
12 #include <linux/module.h>
13 #include <linux/platform_device.h>
14 #include <linux/input-polldev.h>
15 #include <linux/gpio_mouse.h>
20 * Timer function which is run every scan_ms ms when the device is opened.
21 * The dev input variable is set to the the input_dev pointer.
23 static void gpio_mouse_scan(struct input_polled_dev
*dev
)
25 struct gpio_mouse_platform_data
*gpio
= dev
->private;
26 struct input_dev
*input
= dev
->input
;
30 input_report_key(input
, BTN_LEFT
,
31 gpio_get_value(gpio
->bleft
) ^ gpio
->polarity
);
32 if (gpio
->bmiddle
>= 0)
33 input_report_key(input
, BTN_MIDDLE
,
34 gpio_get_value(gpio
->bmiddle
) ^ gpio
->polarity
);
35 if (gpio
->bright
>= 0)
36 input_report_key(input
, BTN_RIGHT
,
37 gpio_get_value(gpio
->bright
) ^ gpio
->polarity
);
39 x
= (gpio_get_value(gpio
->right
) ^ gpio
->polarity
)
40 - (gpio_get_value(gpio
->left
) ^ gpio
->polarity
);
41 y
= (gpio_get_value(gpio
->down
) ^ gpio
->polarity
)
42 - (gpio_get_value(gpio
->up
) ^ gpio
->polarity
);
44 input_report_rel(input
, REL_X
, x
);
45 input_report_rel(input
, REL_Y
, y
);
49 static int __devinit
gpio_mouse_probe(struct platform_device
*pdev
)
51 struct gpio_mouse_platform_data
*pdata
= pdev
->dev
.platform_data
;
52 struct input_polled_dev
*input_poll
;
53 struct input_dev
*input
;
58 dev_err(&pdev
->dev
, "no platform data\n");
63 if (pdata
->scan_ms
< 0) {
64 dev_err(&pdev
->dev
, "invalid scan time\n");
69 for (i
= 0; i
< GPIO_MOUSE_PIN_MAX
; i
++) {
74 if (i
<= GPIO_MOUSE_PIN_RIGHT
) {
75 /* Mouse direction is required. */
77 "missing GPIO for directions\n");
82 if (i
== GPIO_MOUSE_PIN_BLEFT
)
83 dev_dbg(&pdev
->dev
, "no left button defined\n");
86 error
= gpio_request(pin
, "gpio_mouse");
88 dev_err(&pdev
->dev
, "fail %d pin (%d idx)\n",
93 gpio_direction_input(pin
);
97 input_poll
= input_allocate_polled_device();
99 dev_err(&pdev
->dev
, "not enough memory for input device\n");
104 platform_set_drvdata(pdev
, input_poll
);
106 /* set input-polldev handlers */
107 input_poll
->private = pdata
;
108 input_poll
->poll
= gpio_mouse_scan
;
109 input_poll
->poll_interval
= pdata
->scan_ms
;
111 input
= input_poll
->input
;
112 input
->name
= pdev
->name
;
113 input
->id
.bustype
= BUS_HOST
;
114 input
->dev
.parent
= &pdev
->dev
;
116 input_set_capability(input
, EV_REL
, REL_X
);
117 input_set_capability(input
, EV_REL
, REL_Y
);
118 if (pdata
->bleft
>= 0)
119 input_set_capability(input
, EV_KEY
, BTN_LEFT
);
120 if (pdata
->bmiddle
>= 0)
121 input_set_capability(input
, EV_KEY
, BTN_MIDDLE
);
122 if (pdata
->bright
>= 0)
123 input_set_capability(input
, EV_KEY
, BTN_RIGHT
);
125 error
= input_register_polled_device(input_poll
);
127 dev_err(&pdev
->dev
, "could not register input device\n");
128 goto out_free_polldev
;
131 dev_dbg(&pdev
->dev
, "%d ms scan time, buttons: %s%s%s\n",
133 pdata
->bleft
< 0 ? "" : "left ",
134 pdata
->bmiddle
< 0 ? "" : "middle ",
135 pdata
->bright
< 0 ? "" : "right");
140 input_free_polled_device(input_poll
);
141 platform_set_drvdata(pdev
, NULL
);
145 pin
= pdata
->pins
[i
];
153 static int __devexit
gpio_mouse_remove(struct platform_device
*pdev
)
155 struct input_polled_dev
*input
= platform_get_drvdata(pdev
);
156 struct gpio_mouse_platform_data
*pdata
= input
->private;
159 input_unregister_polled_device(input
);
160 input_free_polled_device(input
);
162 for (i
= 0; i
< GPIO_MOUSE_PIN_MAX
; i
++) {
163 pin
= pdata
->pins
[i
];
168 platform_set_drvdata(pdev
, NULL
);
173 static struct platform_driver gpio_mouse_device_driver
= {
174 .probe
= gpio_mouse_probe
,
175 .remove
= __devexit_p(gpio_mouse_remove
),
177 .name
= "gpio_mouse",
178 .owner
= THIS_MODULE
,
182 static int __init
gpio_mouse_init(void)
184 return platform_driver_register(&gpio_mouse_device_driver
);
186 module_init(gpio_mouse_init
);
188 static void __exit
gpio_mouse_exit(void)
190 platform_driver_unregister(&gpio_mouse_device_driver
);
192 module_exit(gpio_mouse_exit
);
194 MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>");
195 MODULE_DESCRIPTION("GPIO mouse driver");
196 MODULE_LICENSE("GPL");
197 MODULE_ALIAS("platform:gpio_mouse"); /* work with hotplug and coldplug */