| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * PlayStation 1/2 joypads via SPI interface Driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2017 Tomohiro Yoshidomi <sylph23k@gmail.com> |
|---|
| 5 | | - * Licensed under the GPL-2 or later. |
|---|
| 6 | 6 | * |
|---|
| 7 | 7 | * PlayStation 1/2 joypad's plug (not socket) |
|---|
| 8 | 8 | * 123 456 789 |
|---|
| .. | .. |
|---|
| 22 | 22 | #include <linux/kernel.h> |
|---|
| 23 | 23 | #include <linux/device.h> |
|---|
| 24 | 24 | #include <linux/input.h> |
|---|
| 25 | | -#include <linux/input-polldev.h> |
|---|
| 26 | 25 | #include <linux/module.h> |
|---|
| 27 | 26 | #include <linux/spi/spi.h> |
|---|
| 28 | 27 | #include <linux/types.h> |
|---|
| .. | .. |
|---|
| 60 | 59 | |
|---|
| 61 | 60 | struct psxpad { |
|---|
| 62 | 61 | struct spi_device *spi; |
|---|
| 63 | | - struct input_polled_dev *pdev; |
|---|
| 62 | + struct input_dev *idev; |
|---|
| 64 | 63 | char phys[0x20]; |
|---|
| 65 | 64 | bool motor1enable; |
|---|
| 66 | 65 | bool motor2enable; |
|---|
| .. | .. |
|---|
| 140 | 139 | static int psxpad_spi_play_effect(struct input_dev *idev, |
|---|
| 141 | 140 | void *data, struct ff_effect *effect) |
|---|
| 142 | 141 | { |
|---|
| 143 | | - struct input_polled_dev *pdev = input_get_drvdata(idev); |
|---|
| 144 | | - struct psxpad *pad = pdev->private; |
|---|
| 142 | + struct psxpad *pad = input_get_drvdata(idev); |
|---|
| 145 | 143 | |
|---|
| 146 | 144 | switch (effect->type) { |
|---|
| 147 | 145 | case FF_RUMBLE: |
|---|
| .. | .. |
|---|
| 158 | 156 | { |
|---|
| 159 | 157 | int err; |
|---|
| 160 | 158 | |
|---|
| 161 | | - input_set_capability(pad->pdev->input, EV_FF, FF_RUMBLE); |
|---|
| 159 | + input_set_capability(pad->idev, EV_FF, FF_RUMBLE); |
|---|
| 162 | 160 | |
|---|
| 163 | | - err = input_ff_create_memless(pad->pdev->input, NULL, |
|---|
| 164 | | - psxpad_spi_play_effect); |
|---|
| 161 | + err = input_ff_create_memless(pad->idev, NULL, psxpad_spi_play_effect); |
|---|
| 165 | 162 | if (err) { |
|---|
| 166 | 163 | dev_err(&pad->spi->dev, |
|---|
| 167 | 164 | "input_ff_create_memless() failed: %d\n", err); |
|---|
| .. | .. |
|---|
| 189 | 186 | } |
|---|
| 190 | 187 | #endif /* CONFIG_JOYSTICK_PSXPAD_SPI_FF */ |
|---|
| 191 | 188 | |
|---|
| 192 | | -static void psxpad_spi_poll_open(struct input_polled_dev *pdev) |
|---|
| 189 | +static int psxpad_spi_poll_open(struct input_dev *input) |
|---|
| 193 | 190 | { |
|---|
| 194 | | - struct psxpad *pad = pdev->private; |
|---|
| 191 | + struct psxpad *pad = input_get_drvdata(input); |
|---|
| 195 | 192 | |
|---|
| 196 | 193 | pm_runtime_get_sync(&pad->spi->dev); |
|---|
| 194 | + |
|---|
| 195 | + return 0; |
|---|
| 197 | 196 | } |
|---|
| 198 | 197 | |
|---|
| 199 | | -static void psxpad_spi_poll_close(struct input_polled_dev *pdev) |
|---|
| 198 | +static void psxpad_spi_poll_close(struct input_dev *input) |
|---|
| 200 | 199 | { |
|---|
| 201 | | - struct psxpad *pad = pdev->private; |
|---|
| 200 | + struct psxpad *pad = input_get_drvdata(input); |
|---|
| 202 | 201 | |
|---|
| 203 | 202 | pm_runtime_put_sync(&pad->spi->dev); |
|---|
| 204 | 203 | } |
|---|
| 205 | 204 | |
|---|
| 206 | | -static void psxpad_spi_poll(struct input_polled_dev *pdev) |
|---|
| 205 | +static void psxpad_spi_poll(struct input_dev *input) |
|---|
| 207 | 206 | { |
|---|
| 208 | | - struct psxpad *pad = pdev->private; |
|---|
| 209 | | - struct input_dev *input = pdev->input; |
|---|
| 207 | + struct psxpad *pad = input_get_drvdata(input); |
|---|
| 210 | 208 | u8 b_rsp3, b_rsp4; |
|---|
| 211 | 209 | int err; |
|---|
| 212 | 210 | |
|---|
| .. | .. |
|---|
| 284 | 282 | static int psxpad_spi_probe(struct spi_device *spi) |
|---|
| 285 | 283 | { |
|---|
| 286 | 284 | struct psxpad *pad; |
|---|
| 287 | | - struct input_polled_dev *pdev; |
|---|
| 288 | 285 | struct input_dev *idev; |
|---|
| 289 | 286 | int err; |
|---|
| 290 | 287 | |
|---|
| .. | .. |
|---|
| 292 | 289 | if (!pad) |
|---|
| 293 | 290 | return -ENOMEM; |
|---|
| 294 | 291 | |
|---|
| 295 | | - pdev = devm_input_allocate_polled_device(&spi->dev); |
|---|
| 296 | | - if (!pdev) { |
|---|
| 292 | + idev = devm_input_allocate_device(&spi->dev); |
|---|
| 293 | + if (!idev) { |
|---|
| 297 | 294 | dev_err(&spi->dev, "failed to allocate input device\n"); |
|---|
| 298 | 295 | return -ENOMEM; |
|---|
| 299 | 296 | } |
|---|
| 300 | 297 | |
|---|
| 301 | 298 | /* input poll device settings */ |
|---|
| 302 | | - pad->pdev = pdev; |
|---|
| 299 | + pad->idev = idev; |
|---|
| 303 | 300 | pad->spi = spi; |
|---|
| 304 | 301 | |
|---|
| 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 | 302 | /* input device settings */ |
|---|
| 315 | | - idev = pdev->input; |
|---|
| 303 | + input_set_drvdata(idev, pad); |
|---|
| 304 | + |
|---|
| 316 | 305 | idev->name = "PlayStation 1/2 joypad"; |
|---|
| 317 | 306 | snprintf(pad->phys, sizeof(pad->phys), "%s/input", dev_name(&spi->dev)); |
|---|
| 318 | 307 | idev->id.bustype = BUS_SPI; |
|---|
| 308 | + |
|---|
| 309 | + idev->open = psxpad_spi_poll_open; |
|---|
| 310 | + idev->close = psxpad_spi_poll_close; |
|---|
| 319 | 311 | |
|---|
| 320 | 312 | /* key/value map settings */ |
|---|
| 321 | 313 | input_set_abs_params(idev, ABS_X, 0, 255, 0, 0); |
|---|
| .. | .. |
|---|
| 354 | 346 | /* pad settings */ |
|---|
| 355 | 347 | psxpad_set_motor_level(pad, 0, 0); |
|---|
| 356 | 348 | |
|---|
| 349 | + |
|---|
| 350 | + err = input_setup_polling(idev, psxpad_spi_poll); |
|---|
| 351 | + if (err) { |
|---|
| 352 | + dev_err(&spi->dev, "failed to set up polling: %d\n", err); |
|---|
| 353 | + return err; |
|---|
| 354 | + } |
|---|
| 355 | + |
|---|
| 356 | + /* poll interval is about 60fps */ |
|---|
| 357 | + input_set_poll_interval(idev, 16); |
|---|
| 358 | + input_set_min_poll_interval(idev, 8); |
|---|
| 359 | + input_set_max_poll_interval(idev, 32); |
|---|
| 360 | + |
|---|
| 357 | 361 | /* register input poll device */ |
|---|
| 358 | | - err = input_register_polled_device(pdev); |
|---|
| 362 | + err = input_register_device(idev); |
|---|
| 359 | 363 | if (err) { |
|---|
| 360 | 364 | dev_err(&spi->dev, |
|---|
| 361 | | - "failed to register input poll device: %d\n", err); |
|---|
| 365 | + "failed to register input device: %d\n", err); |
|---|
| 362 | 366 | return err; |
|---|
| 363 | 367 | } |
|---|
| 364 | 368 | |
|---|