]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/input/joystick/psxpad-spi.c
blk-mq: Make it safe to quiesce and unquiesce from an interrupt handler
[karo-tx-linux.git] / drivers / input / joystick / psxpad-spi.c
1 /*
2  * PlayStation 1/2 joypads via SPI interface Driver
3  *
4  * Copyright (C) 2017 Tomohiro Yoshidomi <sylph23k@gmail.com>
5  * Licensed under the GPL-2 or later.
6  *
7  * PlayStation 1/2 joypad's plug (not socket)
8  *  123 456 789
9  * (...|...|...)
10  *
11  * 1: DAT -> MISO (pullup with 1k owm to 3.3V)
12  * 2: CMD -> MOSI
13  * 3: 9V (for motor, if not use N.C.)
14  * 4: GND
15  * 5: 3.3V
16  * 6: Attention -> CS(SS)
17  * 7: SCK -> SCK
18  * 8: N.C.
19  * 9: ACK -> N.C.
20  */
21
22 #include <linux/kernel.h>
23 #include <linux/device.h>
24 #include <linux/input.h>
25 #include <linux/input-polldev.h>
26 #include <linux/module.h>
27 #include <linux/spi/spi.h>
28 #include <linux/types.h>
29 #include <linux/pm.h>
30 #include <linux/pm_runtime.h>
31
32 #define REVERSE_BIT(x) ((((x) & 0x80) >> 7) | (((x) & 0x40) >> 5) | \
33         (((x) & 0x20) >> 3) | (((x) & 0x10) >> 1) | (((x) & 0x08) << 1) | \
34         (((x) & 0x04) << 3) | (((x) & 0x02) << 5) | (((x) & 0x01) << 7))
35
36 /* PlayStation 1/2 joypad command and response are LSBFIRST. */
37
38 /*
39  *      0x01, 0x42, 0x00, 0x00, 0x00,
40  *      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41  *      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
42  */
43 static const u8 PSX_CMD_POLL[] = {
44         0x80, 0x42, 0x00, 0x00, 0x00,
45         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
47 };
48 /*      0x01, 0x43, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 */
49 static const u8 PSX_CMD_ENTER_CFG[] = {
50         0x80, 0xC2, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00
51 };
52 /*      0x01, 0x43, 0x00, 0x00, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A */
53 static const u8 PSX_CMD_EXIT_CFG[] = {
54         0x80, 0xC2, 0x00, 0x00, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A
55 };
56 /*      0x01, 0x4D, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF */
57 static const u8 PSX_CMD_ENABLE_MOTOR[]  = {
58         0x80, 0xB2, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xFF
59 };
60
61 struct psxpad {
62         struct spi_device *spi;
63         struct input_polled_dev *pdev;
64         char phys[0x20];
65         bool motor1enable;
66         bool motor2enable;
67         u8 motor1level;
68         u8 motor2level;
69         u8 sendbuf[0x20] ____cacheline_aligned;
70         u8 response[sizeof(PSX_CMD_POLL)] ____cacheline_aligned;
71 };
72
73 static int psxpad_command(struct psxpad *pad, const u8 sendcmdlen)
74 {
75         struct spi_transfer xfers = {
76                 .tx_buf         = pad->sendbuf,
77                 .rx_buf         = pad->response,
78                 .len            = sendcmdlen,
79         };
80         int err;
81
82         err = spi_sync_transfer(pad->spi, &xfers, 1);
83         if (err) {
84                 dev_err(&pad->spi->dev,
85                         "%s: failed to SPI xfers mode: %d\n",
86                         __func__, err);
87                 return err;
88         }
89
90         return 0;
91 }
92
93 #ifdef CONFIG_JOYSTICK_PSXPAD_SPI_FF
94 static void psxpad_control_motor(struct psxpad *pad,
95                                  bool motor1enable, bool motor2enable)
96 {
97         int err;
98
99         pad->motor1enable = motor1enable;
100         pad->motor2enable = motor2enable;
101
102         memcpy(pad->sendbuf, PSX_CMD_ENTER_CFG, sizeof(PSX_CMD_ENTER_CFG));
103         err = psxpad_command(pad, sizeof(PSX_CMD_ENTER_CFG));
104         if (err) {
105                 dev_err(&pad->spi->dev,
106                         "%s: failed to enter config mode: %d\n",
107                         __func__, err);
108                 return;
109         }
110
111         memcpy(pad->sendbuf, PSX_CMD_ENABLE_MOTOR,
112                sizeof(PSX_CMD_ENABLE_MOTOR));
113         pad->sendbuf[3] = pad->motor1enable ? 0x00 : 0xFF;
114         pad->sendbuf[4] = pad->motor2enable ? 0x80 : 0xFF;
115         err = psxpad_command(pad, sizeof(PSX_CMD_ENABLE_MOTOR));
116         if (err) {
117                 dev_err(&pad->spi->dev,
118                         "%s: failed to enable motor mode: %d\n",
119                         __func__, err);
120                 return;
121         }
122
123         memcpy(pad->sendbuf, PSX_CMD_EXIT_CFG, sizeof(PSX_CMD_EXIT_CFG));
124         err = psxpad_command(pad, sizeof(PSX_CMD_EXIT_CFG));
125         if (err) {
126                 dev_err(&pad->spi->dev,
127                         "%s: failed to exit config mode: %d\n",
128                         __func__, err);
129                 return;
130         }
131 }
132
133 static void psxpad_set_motor_level(struct psxpad *pad,
134                                    u8 motor1level, u8 motor2level)
135 {
136         pad->motor1level = motor1level ? 0xFF : 0x00;
137         pad->motor2level = REVERSE_BIT(motor2level);
138 }
139
140 static int psxpad_spi_play_effect(struct input_dev *idev,
141                                   void *data, struct ff_effect *effect)
142 {
143         struct input_polled_dev *pdev = input_get_drvdata(idev);
144         struct psxpad *pad = pdev->private;
145
146         switch (effect->type) {
147         case FF_RUMBLE:
148                 psxpad_set_motor_level(pad,
149                         (effect->u.rumble.weak_magnitude >> 8) & 0xFFU,
150                         (effect->u.rumble.strong_magnitude >> 8) & 0xFFU);
151                 break;
152         }
153
154         return 0;
155 }
156
157 static int psxpad_spi_init_ff(struct psxpad *pad)
158 {
159         int err;
160
161         input_set_capability(pad->pdev->input, EV_FF, FF_RUMBLE);
162
163         err = input_ff_create_memless(pad->pdev->input, NULL,
164                                       psxpad_spi_play_effect);
165         if (err) {
166                 dev_err(&pad->spi->dev,
167                         "input_ff_create_memless() failed: %d\n", err);
168                 return err;
169         }
170
171         return 0;
172 }
173
174 #else   /* CONFIG_JOYSTICK_PSXPAD_SPI_FF */
175
176 static void psxpad_control_motor(struct psxpad *pad,
177                                  bool motor1enable, bool motor2enable)
178 {
179 }
180
181 static void psxpad_set_motor_level(struct psxpad *pad,
182                                    u8 motor1level, u8 motor2level)
183 {
184 }
185
186 static inline int psxpad_spi_init_ff(struct psxpad *pad)
187 {
188         return 0;
189 }
190 #endif  /* CONFIG_JOYSTICK_PSXPAD_SPI_FF */
191
192 static void psxpad_spi_poll_open(struct input_polled_dev *pdev)
193 {
194         struct psxpad *pad = pdev->private;
195
196         pm_runtime_get_sync(&pad->spi->dev);
197 }
198
199 static void psxpad_spi_poll_close(struct input_polled_dev *pdev)
200 {
201         struct psxpad *pad = pdev->private;
202
203         pm_runtime_put_sync(&pad->spi->dev);
204 }
205
206 static void psxpad_spi_poll(struct input_polled_dev *pdev)
207 {
208         struct psxpad *pad = pdev->private;
209         struct input_dev *input = pdev->input;
210         u8 b_rsp3, b_rsp4;
211         int err;
212
213         psxpad_control_motor(pad, true, true);
214
215         memcpy(pad->sendbuf, PSX_CMD_POLL, sizeof(PSX_CMD_POLL));
216         pad->sendbuf[3] = pad->motor1enable ? pad->motor1level : 0x00;
217         pad->sendbuf[4] = pad->motor2enable ? pad->motor2level : 0x00;
218         err = psxpad_command(pad, sizeof(PSX_CMD_POLL));
219         if (err) {
220                 dev_err(&pad->spi->dev,
221                         "%s: poll command failed mode: %d\n", __func__, err);
222                 return;
223         }
224
225         switch (pad->response[1]) {
226         case 0xCE:      /* 0x73 : analog 1 */
227                 /* button data is inverted */
228                 b_rsp3 = ~pad->response[3];
229                 b_rsp4 = ~pad->response[4];
230
231                 input_report_abs(input, ABS_X, REVERSE_BIT(pad->response[7]));
232                 input_report_abs(input, ABS_Y, REVERSE_BIT(pad->response[8]));
233                 input_report_abs(input, ABS_RX, REVERSE_BIT(pad->response[5]));
234                 input_report_abs(input, ABS_RY, REVERSE_BIT(pad->response[6]));
235                 input_report_key(input, BTN_DPAD_UP, b_rsp3 & BIT(3));
236                 input_report_key(input, BTN_DPAD_DOWN, b_rsp3 & BIT(1));
237                 input_report_key(input, BTN_DPAD_LEFT, b_rsp3 & BIT(0));
238                 input_report_key(input, BTN_DPAD_RIGHT, b_rsp3 & BIT(2));
239                 input_report_key(input, BTN_X, b_rsp4 & BIT(3));
240                 input_report_key(input, BTN_A, b_rsp4 & BIT(2));
241                 input_report_key(input, BTN_B, b_rsp4 & BIT(1));
242                 input_report_key(input, BTN_Y, b_rsp4 & BIT(0));
243                 input_report_key(input, BTN_TL, b_rsp4 & BIT(5));
244                 input_report_key(input, BTN_TR, b_rsp4 & BIT(4));
245                 input_report_key(input, BTN_TL2, b_rsp4 & BIT(7));
246                 input_report_key(input, BTN_TR2, b_rsp4 & BIT(6));
247                 input_report_key(input, BTN_THUMBL, b_rsp3 & BIT(6));
248                 input_report_key(input, BTN_THUMBR, b_rsp3 & BIT(5));
249                 input_report_key(input, BTN_SELECT, b_rsp3 & BIT(7));
250                 input_report_key(input, BTN_START, b_rsp3 & BIT(4));
251                 break;
252
253         case 0x82:      /* 0x41 : digital */
254                 /* button data is inverted */
255                 b_rsp3 = ~pad->response[3];
256                 b_rsp4 = ~pad->response[4];
257
258                 input_report_abs(input, ABS_X, 0x80);
259                 input_report_abs(input, ABS_Y, 0x80);
260                 input_report_abs(input, ABS_RX, 0x80);
261                 input_report_abs(input, ABS_RY, 0x80);
262                 input_report_key(input, BTN_DPAD_UP, b_rsp3 & BIT(3));
263                 input_report_key(input, BTN_DPAD_DOWN, b_rsp3 & BIT(1));
264                 input_report_key(input, BTN_DPAD_LEFT, b_rsp3 & BIT(0));
265                 input_report_key(input, BTN_DPAD_RIGHT, b_rsp3 & BIT(2));
266                 input_report_key(input, BTN_X, b_rsp4 & BIT(3));
267                 input_report_key(input, BTN_A, b_rsp4 & BIT(2));
268                 input_report_key(input, BTN_B, b_rsp4 & BIT(1));
269                 input_report_key(input, BTN_Y, b_rsp4 & BIT(0));
270                 input_report_key(input, BTN_TL, b_rsp4 & BIT(5));
271                 input_report_key(input, BTN_TR, b_rsp4 & BIT(4));
272                 input_report_key(input, BTN_TL2, b_rsp4 & BIT(7));
273                 input_report_key(input, BTN_TR2, b_rsp4 & BIT(6));
274                 input_report_key(input, BTN_THUMBL, false);
275                 input_report_key(input, BTN_THUMBR, false);
276                 input_report_key(input, BTN_SELECT, b_rsp3 & BIT(7));
277                 input_report_key(input, BTN_START, b_rsp3 & BIT(4));
278                 break;
279         }
280
281         input_sync(input);
282 }
283
284 static int psxpad_spi_probe(struct spi_device *spi)
285 {
286         struct psxpad *pad;
287         struct input_polled_dev *pdev;
288         struct input_dev *idev;
289         int err;
290
291         pad = devm_kzalloc(&spi->dev, sizeof(struct psxpad), GFP_KERNEL);
292         if (!pad)
293                 return -ENOMEM;
294
295         pdev = input_allocate_polled_device();
296         if (!pdev) {
297                 dev_err(&spi->dev, "failed to allocate input device\n");
298                 return -ENOMEM;
299         }
300
301         /* input poll device settings */
302         pad->pdev = pdev;
303         pad->spi = spi;
304
305         pdev->private = pad;
306         pdev->open = psxpad_spi_poll_open;
307         pdev->close = psxpad_spi_poll_close;
308         pdev->poll = psxpad_spi_poll;
309         /* poll interval is about 60fps */
310         pdev->poll_interval = 16;
311         pdev->poll_interval_min = 8;
312         pdev->poll_interval_max = 32;
313
314         /* input device settings */
315         idev = pdev->input;
316         idev->name = "PlayStation 1/2 joypad";
317         snprintf(pad->phys, sizeof(pad->phys), "%s/input", dev_name(&spi->dev));
318         idev->id.bustype = BUS_SPI;
319
320         /* key/value map settings */
321         input_set_abs_params(idev, ABS_X, 0, 255, 0, 0);
322         input_set_abs_params(idev, ABS_Y, 0, 255, 0, 0);
323         input_set_abs_params(idev, ABS_RX, 0, 255, 0, 0);
324         input_set_abs_params(idev, ABS_RY, 0, 255, 0, 0);
325         input_set_capability(idev, EV_KEY, BTN_DPAD_UP);
326         input_set_capability(idev, EV_KEY, BTN_DPAD_DOWN);
327         input_set_capability(idev, EV_KEY, BTN_DPAD_LEFT);
328         input_set_capability(idev, EV_KEY, BTN_DPAD_RIGHT);
329         input_set_capability(idev, EV_KEY, BTN_A);
330         input_set_capability(idev, EV_KEY, BTN_B);
331         input_set_capability(idev, EV_KEY, BTN_X);
332         input_set_capability(idev, EV_KEY, BTN_Y);
333         input_set_capability(idev, EV_KEY, BTN_TL);
334         input_set_capability(idev, EV_KEY, BTN_TR);
335         input_set_capability(idev, EV_KEY, BTN_TL2);
336         input_set_capability(idev, EV_KEY, BTN_TR2);
337         input_set_capability(idev, EV_KEY, BTN_THUMBL);
338         input_set_capability(idev, EV_KEY, BTN_THUMBR);
339         input_set_capability(idev, EV_KEY, BTN_SELECT);
340         input_set_capability(idev, EV_KEY, BTN_START);
341
342         err = psxpad_spi_init_ff(pad);
343         if (err)
344                 return err;
345
346         /* SPI settings */
347         spi->mode = SPI_MODE_3;
348         spi->bits_per_word = 8;
349         /* (PlayStation 1/2 joypad might be possible works 250kHz/500kHz) */
350         spi->master->min_speed_hz = 125000;
351         spi->master->max_speed_hz = 125000;
352         spi_setup(spi);
353
354         /* pad settings */
355         psxpad_set_motor_level(pad, 0, 0);
356
357         /* register input poll device */
358         err = input_register_polled_device(pdev);
359         if (err) {
360                 dev_err(&spi->dev,
361                         "failed to register input poll device: %d\n", err);
362                 return err;
363         }
364
365         pm_runtime_enable(&spi->dev);
366
367         return 0;
368 }
369
370 static int __maybe_unused psxpad_spi_suspend(struct device *dev)
371 {
372         struct spi_device *spi = to_spi_device(dev);
373         struct psxpad *pad = spi_get_drvdata(spi);
374
375         psxpad_set_motor_level(pad, 0, 0);
376
377         return 0;
378 }
379
380 static SIMPLE_DEV_PM_OPS(psxpad_spi_pm, psxpad_spi_suspend, NULL);
381
382 static const struct spi_device_id psxpad_spi_id[] = {
383         { "psxpad-spi", 0 },
384         { }
385 };
386 MODULE_DEVICE_TABLE(spi, psxpad_spi_id);
387
388 static struct spi_driver psxpad_spi_driver = {
389         .driver = {
390                 .name = "psxpad-spi",
391                 .pm = &psxpad_spi_pm,
392         },
393         .id_table = psxpad_spi_id,
394         .probe   = psxpad_spi_probe,
395 };
396
397 module_spi_driver(psxpad_spi_driver);
398
399 MODULE_AUTHOR("Tomohiro Yoshidomi <sylph23k@gmail.com>");
400 MODULE_DESCRIPTION("PlayStation 1/2 joypads via SPI interface Driver");
401 MODULE_LICENSE("GPL");