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/version.h>
13 #include <linux/module.h>
14 #include <linux/platform_device.h>
15 #include <linux/input-polldev.h>
16 #include <linux/gpio_mouse.h>
21 * Timer function which is run every scan_ms ms when the device is opened.
22 * The dev input varaible is set to the the input_dev pointer.
24 static void gpio_mouse_scan(struct input_polled_dev
*dev
)
26 struct gpio_mouse_platform_data
*gpio
= dev
->private;
27 struct input_dev
*input
= dev
->input
;
31 input_report_key(input
, BTN_LEFT
,
32 gpio_get_value(gpio
->bleft
) ^ gpio
->polarity
);
33 if (gpio
->bmiddle
>= 0)
34 input_report_key(input
, BTN_MIDDLE
,
35 gpio_get_value(gpio
->bmiddle
) ^ gpio
->polarity
);
36 if (gpio
->bright
>= 0)
37 input_report_key(input
, BTN_RIGHT
,
38 gpio_get_value(gpio
->bright
) ^ gpio
->polarity
);
40 x
= (gpio_get_value(gpio
->right
) ^ gpio
->polarity
)
41 - (gpio_get_value(gpio
->left
) ^ gpio
->polarity
);
42 y
= (gpio_get_value(gpio
->down
) ^ gpio
->polarity
)
43 - (gpio_get_value(gpio
->up
) ^ gpio
->polarity
);
45 input_report_rel(input
, REL_X
, x
);
46 input_report_rel(input
, REL_Y
, y
);
50 static int __init
gpio_mouse_probe(struct platform_device
*pdev
)
52 struct gpio_mouse_platform_data
*pdata
= pdev
->dev
.platform_data
;
53 struct input_polled_dev
*input_poll
;
54 struct input_dev
*input
;
59 dev_err(&pdev
->dev
, "no platform data\n");
64 if (pdata
->scan_ms
< 0) {
65 dev_err(&pdev
->dev
, "invalid scan time\n");
70 for (i
= 0; i
< GPIO_MOUSE_PIN_MAX
; i
++) {
75 if (i
<= GPIO_MOUSE_PIN_RIGHT
) {
76 /* Mouse direction is required. */
78 "missing GPIO for directions\n");
83 if (i
== GPIO_MOUSE_PIN_BLEFT
)
84 dev_dbg(&pdev
->dev
, "no left button defined\n");
87 error
= gpio_request(pin
, "gpio_mouse");
89 dev_err(&pdev
->dev
, "fail %d pin (%d idx)\n",
94 gpio_direction_input(pin
);
98 input_poll
= input_allocate_polled_device();
100 dev_err(&pdev
->dev
, "not enough memory for input device\n");
105 platform_set_drvdata(pdev
, input_poll
);
107 /* set input-polldev handlers */
108 input_poll
->private = pdata
;
109 input_poll
->poll
= gpio_mouse_scan
;
110 input_poll
->poll_interval
= pdata
->scan_ms
;
112 input
= input_poll
->input
;
113 input
->name
= pdev
->name
;
114 input
->id
.bustype
= BUS_HOST
;
115 input
->dev
.parent
= &pdev
->dev
;
117 input_set_capability(input
, EV_REL
, REL_X
);
118 input_set_capability(input
, EV_REL
, REL_Y
);
119 if (pdata
->bleft
>= 0)
120 input_set_capability(input
, EV_KEY
, BTN_LEFT
);
121 if (pdata
->bmiddle
>= 0)
122 input_set_capability(input
, EV_KEY
, BTN_MIDDLE
);
123 if (pdata
->bright
>= 0)
124 input_set_capability(input
, EV_KEY
, BTN_RIGHT
);
126 error
= input_register_polled_device(input_poll
);
128 dev_err(&pdev
->dev
, "could not register input device\n");
129 goto out_free_polldev
;
132 dev_dbg(&pdev
->dev
, "%d ms scan time, buttons: %s%s%s\n",
134 pdata
->bleft
< 0 ? "" : "left ",
135 pdata
->bmiddle
< 0 ? "" : "middle ",
136 pdata
->bright
< 0 ? "" : "right");
141 input_free_polled_device(input_poll
);
142 platform_set_drvdata(pdev
, NULL
);
146 pin
= pdata
->pins
[i
];
154 static int __devexit
gpio_mouse_remove(struct platform_device
*pdev
)
156 struct input_polled_dev
*input
= platform_get_drvdata(pdev
);
157 struct gpio_mouse_platform_data
*pdata
= input
->private;
160 input_unregister_polled_device(input
);
161 input_free_polled_device(input
);
163 for (i
= 0; i
< GPIO_MOUSE_PIN_MAX
; i
++) {
164 pin
= pdata
->pins
[i
];
169 platform_set_drvdata(pdev
, NULL
);
174 struct platform_driver gpio_mouse_device_driver
= {
175 .remove
= __devexit_p(gpio_mouse_remove
),
177 .name
= "gpio_mouse",
181 static int __init
gpio_mouse_init(void)
183 return platform_driver_probe(&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");