drivers/input/joystick/iforce/iforce-packets.c
Source file repositories/reference/linux-study-clean/drivers/input/joystick/iforce/iforce-packets.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/input/joystick/iforce/iforce-packets.c- Extension
.c- Size
- 5193 bytes
- Lines
- 206
- Domain
- Driver Families
- Bucket
- drivers/input
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/export.hlinux/unaligned.hiforce.h
Detected Declarations
function iforce_dump_packetfunction iforce_send_packetfunction iforce_control_playbackfunction mark_core_as_readyfunction iforce_report_hats_buttonsfunction iforce_process_packetexport iforce_send_packetexport iforce_process_packet
Annotated Snippet
if (CIRC_SPACE(head, tail, XMIT_SIZE) < n + 2) {
dev_warn(&iforce->dev->dev,
"not enough space in xmit buffer to send new packet\n");
return -1;
}
empty = head == tail;
XMIT_INC(iforce->xmit.head, n + 2);
/*
* Store packet in xmit buffer
*/
iforce->xmit.buf[head] = HI(cmd);
XMIT_INC(head, 1);
iforce->xmit.buf[head] = LO(cmd);
XMIT_INC(head, 1);
c = CIRC_SPACE_TO_END(head, tail, XMIT_SIZE);
if (n < c)
c = n;
memcpy(&iforce->xmit.buf[head], data, c);
if (n != c)
memcpy(&iforce->xmit.buf[0], data + c, n - c);
XMIT_INC(head, n);
}
/*
* If necessary, start the transmission
*/
if (empty)
iforce->xport_ops->xmit(iforce);
return 0;
}
EXPORT_SYMBOL(iforce_send_packet);
/* Start or stop an effect */
int iforce_control_playback(struct iforce* iforce, u16 id, unsigned int value)
{
unsigned char data[3];
data[0] = LO(id);
data[1] = (value > 0) ? ((value > 1) ? 0x41 : 0x01) : 0;
data[2] = LO(value);
return iforce_send_packet(iforce, FF_CMD_PLAY, data);
}
/* Mark an effect that was being updated as ready. That means it can be updated
* again */
static int mark_core_as_ready(struct iforce *iforce, unsigned short addr)
{
int i;
if (!iforce->dev->ff)
return 0;
for (i = 0; i < iforce->dev->ff->max_effects; ++i) {
if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) &&
(iforce->core_effects[i].mod1_chunk.start == addr ||
iforce->core_effects[i].mod2_chunk.start == addr)) {
clear_bit(FF_CORE_UPDATE, iforce->core_effects[i].flags);
return 0;
}
}
dev_warn(&iforce->dev->dev, "unused effect %04x updated !!!\n", addr);
return -1;
}
static void iforce_report_hats_buttons(struct iforce *iforce, u8 *data)
{
struct input_dev *dev = iforce->dev;
int i;
input_report_abs(dev, ABS_HAT0X, iforce_hat_to_axis[data[6] >> 4].x);
input_report_abs(dev, ABS_HAT0Y, iforce_hat_to_axis[data[6] >> 4].y);
for (i = 0; iforce->type->btn[i] >= 0; i++)
input_report_key(dev, iforce->type->btn[i],
data[(i >> 3) + 5] & (1 << (i & 7)));
/* If there are untouched bits left, interpret them as the second hat */
if (i <= 8) {
u8 btns = data[6];
if (test_bit(ABS_HAT1X, dev->absbit)) {
if (btns & BIT(3))
input_report_abs(dev, ABS_HAT1X, -1);
else if (btns & BIT(1))
Annotation
- Immediate include surface: `linux/export.h`, `linux/unaligned.h`, `iforce.h`.
- Detected declarations: `function iforce_dump_packet`, `function iforce_send_packet`, `function iforce_control_playback`, `function mark_core_as_ready`, `function iforce_report_hats_buttons`, `function iforce_process_packet`, `export iforce_send_packet`, `export iforce_process_packet`.
- Atlas domain: Driver Families / drivers/input.
- Implementation status: integration 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.