2 * Raspberry Pi Sense HAT joystick driver
3 * http://raspberrypi.org
5 * Copyright (C) 2015 Raspberry Pi
7 * Author: Serge Schneider
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
16 #include <linux/module.h>
18 #include <linux/mfd/rpisense/joystick.h>
19 #include <linux/mfd/rpisense/core.h>
21 static struct rpisense *rpisense;
22 static unsigned char keymap[5] = {KEY_DOWN, KEY_RIGHT, KEY_UP, KEY_ENTER, KEY_LEFT,};
24 static void keys_work_fn(struct work_struct *work)
28 struct rpisense_js *rpisense_js = &rpisense->joystick;
29 s32 keys = rpisense_reg_read(rpisense, RPISENSE_KEYS);
30 s32 changes = keys ^ prev_keys;
33 for (i = 0; i < 5; i++) {
35 input_report_key(rpisense_js->keys_dev,
41 input_sync(rpisense_js->keys_dev);
44 static irqreturn_t keys_irq_handler(int irq, void *pdev)
46 struct rpisense_js *rpisense_js = &rpisense->joystick;
48 schedule_work(&rpisense_js->keys_work_s);
52 static int rpisense_js_probe(struct platform_device *pdev)
56 struct rpisense_js *rpisense_js;
58 rpisense = rpisense_get_dev();
59 rpisense_js = &rpisense->joystick;
61 INIT_WORK(&rpisense_js->keys_work_s, keys_work_fn);
63 rpisense_js->keys_dev = input_allocate_device();
64 if (!rpisense_js->keys_dev) {
65 dev_err(&pdev->dev, "Could not allocate input device.\n");
69 rpisense_js->keys_dev->evbit[0] = BIT_MASK(EV_KEY);
70 for (i = 0; i < ARRAY_SIZE(keymap); i++) {
72 rpisense_js->keys_dev->keybit);
75 rpisense_js->keys_dev->name = "Raspberry Pi Sense HAT Joystick";
76 rpisense_js->keys_dev->phys = "rpi-sense-joy/input0";
77 rpisense_js->keys_dev->id.bustype = BUS_I2C;
78 rpisense_js->keys_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
79 rpisense_js->keys_dev->keycode = keymap;
80 rpisense_js->keys_dev->keycodesize = sizeof(unsigned char);
81 rpisense_js->keys_dev->keycodemax = ARRAY_SIZE(keymap);
83 ret = input_register_device(rpisense_js->keys_dev);
85 dev_err(&pdev->dev, "Could not register input device.\n");
89 ret = gpiod_direction_input(rpisense_js->keys_desc);
91 dev_err(&pdev->dev, "Could not set keys-int direction.\n");
95 rpisense_js->keys_irq = gpiod_to_irq(rpisense_js->keys_desc);
96 if (rpisense_js->keys_irq < 0) {
97 dev_err(&pdev->dev, "Could not determine keys-int IRQ.\n");
98 ret = rpisense_js->keys_irq;
102 ret = devm_request_irq(&pdev->dev, rpisense_js->keys_irq,
103 keys_irq_handler, IRQF_TRIGGER_RISING,
106 dev_err(&pdev->dev, "IRQ request failed.\n");
111 input_unregister_device(rpisense_js->keys_dev);
113 input_free_device(rpisense_js->keys_dev);
117 static int rpisense_js_remove(struct platform_device *pdev)
119 struct rpisense_js *rpisense_js = &rpisense->joystick;
121 input_unregister_device(rpisense_js->keys_dev);
122 input_free_device(rpisense_js->keys_dev);
127 static const struct of_device_id rpisense_js_id[] = {
128 { .compatible = "rpi,rpi-sense-js" },
131 MODULE_DEVICE_TABLE(of, rpisense_js_id);
134 static struct platform_device_id rpisense_js_device_id[] = {
135 { .name = "rpi-sense-js" },
138 MODULE_DEVICE_TABLE(platform, rpisense_js_device_id);
140 static struct platform_driver rpisense_js_driver = {
141 .probe = rpisense_js_probe,
142 .remove = rpisense_js_remove,
144 .name = "rpi-sense-js",
145 .owner = THIS_MODULE,
149 module_platform_driver(rpisense_js_driver);
151 MODULE_DESCRIPTION("Raspberry Pi Sense HAT joystick driver");
152 MODULE_AUTHOR("Serge Schneider <serge@raspberrypi.org>");
153 MODULE_LICENSE("GPL");