drivers/input/joystick/psxpad-spi.c
Source file repositories/reference/linux-study-clean/drivers/input/joystick/psxpad-spi.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/input/joystick/psxpad-spi.c- Extension
.c- Size
- 11425 bytes
- Lines
- 413
- Domain
- Driver Families
- Bucket
- drivers/input
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/device.hlinux/input.hlinux/module.hlinux/spi/spi.hlinux/types.hlinux/pm.hlinux/pm_runtime.h
Detected Declarations
struct psxpadfunction psxpad_commandfunction psxpad_control_motorfunction psxpad_set_motor_levelfunction psxpad_spi_play_effectfunction psxpad_spi_init_fffunction psxpad_control_motorfunction psxpad_spi_poll_openfunction psxpad_spi_poll_closefunction psxpad_spi_pollfunction psxpad_spi_probefunction psxpad_spi_suspend
Annotated Snippet
struct psxpad {
struct spi_device *spi;
struct input_dev *idev;
char phys[0x20];
bool motor1enable;
bool motor2enable;
u8 motor1level;
u8 motor2level;
u8 sendbuf[0x20] ____cacheline_aligned;
u8 response[sizeof(PSX_CMD_POLL)] ____cacheline_aligned;
};
static int psxpad_command(struct psxpad *pad, const u8 sendcmdlen)
{
struct spi_transfer xfers = {
.tx_buf = pad->sendbuf,
.rx_buf = pad->response,
.len = sendcmdlen,
};
int err;
err = spi_sync_transfer(pad->spi, &xfers, 1);
if (err) {
dev_err(&pad->spi->dev,
"%s: failed to SPI xfers mode: %d\n",
__func__, err);
return err;
}
return 0;
}
#ifdef CONFIG_JOYSTICK_PSXPAD_SPI_FF
static void psxpad_control_motor(struct psxpad *pad,
bool motor1enable, bool motor2enable)
{
int err;
pad->motor1enable = motor1enable;
pad->motor2enable = motor2enable;
memcpy(pad->sendbuf, PSX_CMD_ENTER_CFG, sizeof(PSX_CMD_ENTER_CFG));
err = psxpad_command(pad, sizeof(PSX_CMD_ENTER_CFG));
if (err) {
dev_err(&pad->spi->dev,
"%s: failed to enter config mode: %d\n",
__func__, err);
return;
}
memcpy(pad->sendbuf, PSX_CMD_ENABLE_MOTOR,
sizeof(PSX_CMD_ENABLE_MOTOR));
pad->sendbuf[3] = pad->motor1enable ? 0x00 : 0xFF;
pad->sendbuf[4] = pad->motor2enable ? 0x80 : 0xFF;
err = psxpad_command(pad, sizeof(PSX_CMD_ENABLE_MOTOR));
if (err) {
dev_err(&pad->spi->dev,
"%s: failed to enable motor mode: %d\n",
__func__, err);
return;
}
memcpy(pad->sendbuf, PSX_CMD_EXIT_CFG, sizeof(PSX_CMD_EXIT_CFG));
err = psxpad_command(pad, sizeof(PSX_CMD_EXIT_CFG));
if (err) {
dev_err(&pad->spi->dev,
"%s: failed to exit config mode: %d\n",
__func__, err);
return;
}
}
static void psxpad_set_motor_level(struct psxpad *pad,
u8 motor1level, u8 motor2level)
{
pad->motor1level = motor1level ? 0xFF : 0x00;
pad->motor2level = REVERSE_BIT(motor2level);
}
static int psxpad_spi_play_effect(struct input_dev *idev,
void *data, struct ff_effect *effect)
{
struct psxpad *pad = input_get_drvdata(idev);
switch (effect->type) {
case FF_RUMBLE:
psxpad_set_motor_level(pad,
(effect->u.rumble.weak_magnitude >> 8) & 0xFFU,
(effect->u.rumble.strong_magnitude >> 8) & 0xFFU);
break;
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/device.h`, `linux/input.h`, `linux/module.h`, `linux/spi/spi.h`, `linux/types.h`, `linux/pm.h`, `linux/pm_runtime.h`.
- Detected declarations: `struct psxpad`, `function psxpad_command`, `function psxpad_control_motor`, `function psxpad_set_motor_level`, `function psxpad_spi_play_effect`, `function psxpad_spi_init_ff`, `function psxpad_control_motor`, `function psxpad_spi_poll_open`, `function psxpad_spi_poll_close`, `function psxpad_spi_poll`.
- Atlas domain: Driver Families / drivers/input.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.