drivers/input/joystick/adi.c
Source file repositories/reference/linux-study-clean/drivers/input/joystick/adi.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/input/joystick/adi.c- Extension
.c- Size
- 13157 bytes
- Lines
- 549
- 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/delay.hlinux/kernel.hlinux/module.hlinux/string.hlinux/slab.hlinux/input.hlinux/gameport.hlinux/jiffies.h
Detected Declarations
struct adistruct adi_portfunction adi_read_packetfunction adi_move_bitsfunction adi_get_bitsfunction adi_decodefunction adi_readfunction adi_pollfunction adi_openfunction adi_closefunction adi_init_digitalfunction adi_id_decodefunction adi_init_inputfunction adi_init_centerfunction adi_connectfunction adi_disconnect
Annotated Snippet
struct adi {
struct input_dev *dev;
int length;
int ret;
int idx;
unsigned char id;
char buttons;
char axes10;
char axes8;
signed char pad;
char hats;
char *abs;
short *key;
char name[ADI_MAX_NAME_LENGTH];
char cname[ADI_MAX_CNAME_LENGTH];
char phys[ADI_MAX_PHYS_LENGTH];
unsigned char data[ADI_MAX_LENGTH];
};
struct adi_port {
struct gameport *gameport;
struct adi adi[2];
int bad;
int reads;
};
/*
* adi_read_packet() reads a Logitech ADI packet.
*/
static void adi_read_packet(struct adi_port *port)
{
struct adi *adi = port->adi;
struct gameport *gameport = port->gameport;
unsigned char u, v, w, x;
int t[2], s[2], i;
unsigned long flags;
for (i = 0; i < 2; i++) {
adi[i].ret = -1;
t[i] = gameport_time(gameport, ADI_MAX_START);
s[i] = 0;
}
local_irq_save(flags);
gameport_trigger(gameport);
v = gameport_read(gameport);
do {
u = v;
w = u ^ (v = x = gameport_read(gameport));
for (i = 0; i < 2; i++, w >>= 2, x >>= 2) {
t[i]--;
if ((w & 0x30) && s[i]) {
if ((w & 0x30) < 0x30 && adi[i].ret < ADI_MAX_LENGTH && t[i] > 0) {
adi[i].data[++adi[i].ret] = w;
t[i] = gameport_time(gameport, ADI_MAX_STROBE);
} else t[i] = 0;
} else if (!(x & 0x30)) s[i] = 1;
}
} while (t[0] > 0 || t[1] > 0);
local_irq_restore(flags);
return;
}
/*
* adi_move_bits() detects a possible 2-stream mode, and moves
* the bits accordingly.
*/
static void adi_move_bits(struct adi_port *port, int length)
{
int i;
struct adi *adi = port->adi;
adi[0].idx = adi[1].idx = 0;
if (adi[0].ret <= 0 || adi[1].ret <= 0) return;
if (adi[0].data[0] & 0x20 || ~adi[1].data[0] & 0x20) return;
for (i = 1; i <= adi[1].ret; i++)
adi[0].data[((length - 1) >> 1) + i + 1] = adi[1].data[i];
adi[0].ret += adi[1].ret;
adi[1].ret = -1;
}
Annotation
- Immediate include surface: `linux/delay.h`, `linux/kernel.h`, `linux/module.h`, `linux/string.h`, `linux/slab.h`, `linux/input.h`, `linux/gameport.h`, `linux/jiffies.h`.
- Detected declarations: `struct adi`, `struct adi_port`, `function adi_read_packet`, `function adi_move_bits`, `function adi_get_bits`, `function adi_decode`, `function adi_read`, `function adi_poll`, `function adi_open`, `function adi_close`.
- 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.