0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/module.h>
0010 #include <linux/platform_device.h>
0011 #include <linux/input.h>
0012 #include <linux/gpio/consumer.h>
0013 #include <linux/property.h>
0014 #include <linux/of.h>
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 struct gpio_mouse {
0032 u32 scan_ms;
0033 struct gpio_desc *up;
0034 struct gpio_desc *down;
0035 struct gpio_desc *left;
0036 struct gpio_desc *right;
0037 struct gpio_desc *bleft;
0038 struct gpio_desc *bmiddle;
0039 struct gpio_desc *bright;
0040 };
0041
0042
0043
0044
0045
0046 static void gpio_mouse_scan(struct input_dev *input)
0047 {
0048 struct gpio_mouse *gpio = input_get_drvdata(input);
0049 int x, y;
0050
0051 if (gpio->bleft)
0052 input_report_key(input, BTN_LEFT,
0053 gpiod_get_value(gpio->bleft));
0054 if (gpio->bmiddle)
0055 input_report_key(input, BTN_MIDDLE,
0056 gpiod_get_value(gpio->bmiddle));
0057 if (gpio->bright)
0058 input_report_key(input, BTN_RIGHT,
0059 gpiod_get_value(gpio->bright));
0060
0061 x = gpiod_get_value(gpio->right) - gpiod_get_value(gpio->left);
0062 y = gpiod_get_value(gpio->down) - gpiod_get_value(gpio->up);
0063
0064 input_report_rel(input, REL_X, x);
0065 input_report_rel(input, REL_Y, y);
0066 input_sync(input);
0067 }
0068
0069 static int gpio_mouse_probe(struct platform_device *pdev)
0070 {
0071 struct device *dev = &pdev->dev;
0072 struct gpio_mouse *gmouse;
0073 struct input_dev *input;
0074 int error;
0075
0076 gmouse = devm_kzalloc(dev, sizeof(*gmouse), GFP_KERNEL);
0077 if (!gmouse)
0078 return -ENOMEM;
0079
0080
0081 error = device_property_read_u32(dev, "scan-interval-ms",
0082 &gmouse->scan_ms);
0083 if (error || gmouse->scan_ms == 0) {
0084 dev_warn(dev, "invalid scan time, set to 50 ms\n");
0085 gmouse->scan_ms = 50;
0086 }
0087
0088 gmouse->up = devm_gpiod_get(dev, "up", GPIOD_IN);
0089 if (IS_ERR(gmouse->up))
0090 return PTR_ERR(gmouse->up);
0091 gmouse->down = devm_gpiod_get(dev, "down", GPIOD_IN);
0092 if (IS_ERR(gmouse->down))
0093 return PTR_ERR(gmouse->down);
0094 gmouse->left = devm_gpiod_get(dev, "left", GPIOD_IN);
0095 if (IS_ERR(gmouse->left))
0096 return PTR_ERR(gmouse->left);
0097 gmouse->right = devm_gpiod_get(dev, "right", GPIOD_IN);
0098 if (IS_ERR(gmouse->right))
0099 return PTR_ERR(gmouse->right);
0100
0101 gmouse->bleft = devm_gpiod_get_optional(dev, "button-left", GPIOD_IN);
0102 if (IS_ERR(gmouse->bleft))
0103 return PTR_ERR(gmouse->bleft);
0104 gmouse->bmiddle = devm_gpiod_get_optional(dev, "button-middle",
0105 GPIOD_IN);
0106 if (IS_ERR(gmouse->bmiddle))
0107 return PTR_ERR(gmouse->bmiddle);
0108 gmouse->bright = devm_gpiod_get_optional(dev, "button-right",
0109 GPIOD_IN);
0110 if (IS_ERR(gmouse->bright))
0111 return PTR_ERR(gmouse->bright);
0112
0113 input = devm_input_allocate_device(dev);
0114 if (!input)
0115 return -ENOMEM;
0116
0117 input->name = pdev->name;
0118 input->id.bustype = BUS_HOST;
0119
0120 input_set_drvdata(input, gmouse);
0121
0122 input_set_capability(input, EV_REL, REL_X);
0123 input_set_capability(input, EV_REL, REL_Y);
0124 if (gmouse->bleft)
0125 input_set_capability(input, EV_KEY, BTN_LEFT);
0126 if (gmouse->bmiddle)
0127 input_set_capability(input, EV_KEY, BTN_MIDDLE);
0128 if (gmouse->bright)
0129 input_set_capability(input, EV_KEY, BTN_RIGHT);
0130
0131 error = input_setup_polling(input, gpio_mouse_scan);
0132 if (error)
0133 return error;
0134
0135 input_set_poll_interval(input, gmouse->scan_ms);
0136
0137 error = input_register_device(input);
0138 if (error) {
0139 dev_err(dev, "could not register input device\n");
0140 return error;
0141 }
0142
0143 dev_dbg(dev, "%d ms scan time, buttons: %s%s%s\n",
0144 gmouse->scan_ms,
0145 gmouse->bleft ? "" : "left ",
0146 gmouse->bmiddle ? "" : "middle ",
0147 gmouse->bright ? "" : "right");
0148
0149 return 0;
0150 }
0151
0152 static const struct of_device_id gpio_mouse_of_match[] = {
0153 { .compatible = "gpio-mouse", },
0154 { },
0155 };
0156 MODULE_DEVICE_TABLE(of, gpio_mouse_of_match);
0157
0158 static struct platform_driver gpio_mouse_device_driver = {
0159 .probe = gpio_mouse_probe,
0160 .driver = {
0161 .name = "gpio_mouse",
0162 .of_match_table = gpio_mouse_of_match,
0163 }
0164 };
0165 module_platform_driver(gpio_mouse_device_driver);
0166
0167 MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");
0168 MODULE_DESCRIPTION("GPIO mouse driver");
0169 MODULE_LICENSE("GPL");
0170 MODULE_ALIAS("platform:gpio_mouse");