drivers/input/joystick/tmdc.c
Source file repositories/reference/linux-study-clean/drivers/input/joystick/tmdc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/input/joystick/tmdc.c- Extension
.c- Size
- 10158 bytes
- Lines
- 421
- 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/slab.hlinux/module.hlinux/gameport.hlinux/input.hlinux/jiffies.h
Detected Declarations
struct tmdc_portstruct tmdcfunction tmdc_read_packetfunction tmdc_parse_packetfunction tmdc_pollfunction tmdc_openfunction tmdc_closefunction tmdc_setup_portfunction tmdc_probefunction tmdc_disconnect
Annotated Snippet
struct tmdc_port {
struct input_dev *dev;
char name[64];
char phys[32];
int mode;
const signed char *abs;
const short *btn;
unsigned char absc;
unsigned char btnc[4];
unsigned char btno[4];
};
struct tmdc {
struct gameport *gameport;
struct tmdc_port *port[2];
#if 0
struct input_dev *dev[2];
char name[2][64];
char phys[2][32];
int mode[2];
signed char *abs[2];
short *btn[2];
unsigned char absc[2];
unsigned char btnc[2][4];
unsigned char btno[2][4];
#endif
int reads;
int bads;
unsigned char exists;
};
/*
* tmdc_read_packet() reads a ThrustMaster packet.
*/
static int tmdc_read_packet(struct gameport *gameport, unsigned char data[2][TMDC_MAX_LENGTH])
{
unsigned char u, v, w, x;
unsigned long flags;
int i[2], j[2], t[2], p, k;
p = gameport_time(gameport, TMDC_MAX_STROBE);
for (k = 0; k < 2; k++) {
t[k] = gameport_time(gameport, TMDC_MAX_START);
i[k] = j[k] = 0;
}
local_irq_save(flags);
gameport_trigger(gameport);
w = gameport_read(gameport) >> 4;
do {
x = w;
w = gameport_read(gameport) >> 4;
for (k = 0, v = w, u = x; k < 2; k++, v >>= 2, u >>= 2) {
if (~v & u & 2) {
if (t[k] <= 0 || i[k] >= TMDC_MAX_LENGTH) continue;
t[k] = p;
if (j[k] == 0) { /* Start bit */
if (~v & 1) t[k] = 0;
data[k][i[k]] = 0; j[k]++; continue;
}
if (j[k] == 9) { /* Stop bit */
if (v & 1) t[k] = 0;
j[k] = 0; i[k]++; continue;
}
data[k][i[k]] |= (~v & 1) << (j[k]++ - 1); /* Data bit */
}
t[k]--;
}
} while (t[0] > 0 || t[1] > 0);
local_irq_restore(flags);
return (i[0] == TMDC_MAX_LENGTH) | ((i[1] == TMDC_MAX_LENGTH) << 1);
}
static int tmdc_parse_packet(struct tmdc_port *port, unsigned char *data)
{
int i, k, l;
if (data[TMDC_BYTE_ID] != port->mode)
return -1;
for (i = 0; i < port->absc; i++) {
if (port->abs[i] < 0)
return 0;
Annotation
- Immediate include surface: `linux/delay.h`, `linux/kernel.h`, `linux/slab.h`, `linux/module.h`, `linux/gameport.h`, `linux/input.h`, `linux/jiffies.h`.
- Detected declarations: `struct tmdc_port`, `struct tmdc`, `function tmdc_read_packet`, `function tmdc_parse_packet`, `function tmdc_poll`, `function tmdc_open`, `function tmdc_close`, `function tmdc_setup_port`, `function tmdc_probe`, `function tmdc_disconnect`.
- 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.