?? analog.c
字號:
if (t < tx) tx = t; } port->loop = tx / 50;}/* * analog_name() constructs a name for an analog joystick. */static void analog_name(struct analog *analog){ sprintf(analog->name, "Analog %d-axis %d-button", hweight8(analog->mask & ANALOG_AXES_STD), hweight8(analog->mask & ANALOG_BTNS_STD) + !!(analog->mask & ANALOG_BTNS_CHF) * 2 + hweight16(analog->mask & ANALOG_BTNS_GAMEPAD) + !!(analog->mask & ANALOG_HBTN_CHF) * 4); if (analog->mask & ANALOG_HATS_ALL) sprintf(analog->name, "%s %d-hat", analog->name, hweight16(analog->mask & ANALOG_HATS_ALL)); if (analog->mask & ANALOG_HAT_FCS) strcat(analog->name, " FCS"); if (analog->mask & ANALOG_ANY_CHF) strcat(analog->name, (analog->mask & ANALOG_SAITEK) ? " Saitek" : " CHF"); strcat(analog->name, (analog->mask & ANALOG_GAMEPAD) ? " gamepad": " joystick");}/* * analog_init_device() */static void analog_init_device(struct analog_port *port, struct analog *analog, int index){ int i, j, t, v, w, x, y, z; analog_name(analog); analog->buttons = (analog->mask & ANALOG_GAMEPAD) ? analog_pad_btn : analog_joy_btn; analog->dev.name = analog->name; analog->dev.idbus = BUS_GAMEPORT; analog->dev.idvendor = GAMEPORT_ID_VENDOR_ANALOG; analog->dev.idproduct = analog->mask >> 4; analog->dev.idversion = 0x0100; analog->dev.open = analog_open; analog->dev.close = analog_close; analog->dev.private = port; analog->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (i = j = 0; i < 4; i++) if (analog->mask & (1 << i)) { t = analog_axes[j]; x = port->axes[i]; y = (port->axes[0] + port->axes[1]) >> 1; z = y - port->axes[i]; z = z > 0 ? z : -z; v = (x >> 3); w = (x >> 3); set_bit(t, analog->dev.absbit); if ((i == 2 || i == 3) && (j == 2 || j == 3) && (z > (y >> 3))) x = y; if (analog->mask & ANALOG_SAITEK) { if (i == 2) x = port->axes[i]; v = x - (x >> 2); w = (x >> 4); } analog->dev.absmax[t] = (x << 1) - v; analog->dev.absmin[t] = v; analog->dev.absfuzz[t] = port->fuzz; analog->dev.absflat[t] = w; j++; } for (i = j = 0; i < 3; i++) if (analog->mask & analog_exts[i]) for (x = 0; x < 2; x++) { t = analog_hats[j++]; set_bit(t, analog->dev.absbit); analog->dev.absmax[t] = 1; analog->dev.absmin[t] = -1; } for (i = j = 0; i < 4; i++) if (analog->mask & (0x10 << i)) set_bit(analog->buttons[j++], analog->dev.keybit); if (analog->mask & ANALOG_BTNS_CHF) for (i = 0; i < 2; i++) set_bit(analog->buttons[j++], analog->dev.keybit); if (analog->mask & ANALOG_HBTN_CHF) for (i = 0; i < 4; i++) set_bit(analog->buttons[j++], analog->dev.keybit); for (i = 0; i < 4; i++) if (analog->mask & (ANALOG_BTN_TL << i)) set_bit(analog_pads[i], analog->dev.keybit); analog_decode(analog, port->axes, port->initial, port->buttons); input_register_device(&analog->dev); printk(KERN_INFO "input%d: %s at gameport%d.%d", analog->dev.number, analog->name, port->gameport->number, index); if (port->cooked) printk(" [ADC port]\n"); else printk(" [%s timer, %d %sHz clock, %d ns res]\n", TIME_NAME, port->speed > 10000 ? (port->speed + 800) / 1000 : port->speed, port->speed > 10000 ? "M" : "k", port->speed > 10000 ? (port->loop * 1000) / (port->speed / 1000) : (port->loop * 1000000) / port->speed);}/* * analog_init_devices() sets up device-specific values and registers the input devices. */static int analog_init_masks(struct analog_port *port){ int i; struct analog *analog = port->analog; int max[4]; if (!port->mask) return -1; if ((port->mask & 3) != 3 && port->mask != 0xc) { printk(KERN_WARNING "analog.c: Unknown joystick device found " "(data=%#x, gameport%d), probably not analog joystick.\n", port->mask, port->gameport->number); return -1; } i = port->gameport->number < ANALOG_PORTS ? analog_options[port->gameport->number] : 0xff; analog[0].mask = i & 0xfffff; analog[0].mask &= ~(ANALOG_AXES_STD | ANALOG_HAT_FCS | ANALOG_BTNS_GAMEPAD) | port->mask | ((port->mask << 8) & ANALOG_HAT_FCS) | ((port->mask << 10) & ANALOG_BTNS_TLR) | ((port->mask << 12) & ANALOG_BTNS_TLR2); analog[0].mask &= ~(ANALOG_HAT2_CHF) | ((analog[0].mask & ANALOG_HBTN_CHF) ? 0 : ANALOG_HAT2_CHF); analog[0].mask &= ~(ANALOG_THROTTLE | ANALOG_BTN_TR | ANALOG_BTN_TR2) | ((~analog[0].mask & ANALOG_HAT_FCS) >> 8) | ((~analog[0].mask & ANALOG_HAT_FCS) << 2) | ((~analog[0].mask & ANALOG_HAT_FCS) << 4); analog[0].mask &= ~(ANALOG_THROTTLE | ANALOG_RUDDER) | (((~analog[0].mask & ANALOG_BTNS_TLR ) >> 10) & ((~analog[0].mask & ANALOG_BTNS_TLR2) >> 12)); analog[1].mask = ((i >> 20) & 0xff) | ((i >> 12) & 0xf0000); analog[1].mask &= (analog[0].mask & ANALOG_EXTENSIONS) ? ANALOG_GAMEPAD : (((ANALOG_BTNS_STD | port->mask) & ~analog[0].mask) | ANALOG_GAMEPAD); if (port->cooked) { for (i = 0; i < 4; i++) max[i] = port->axes[i] << 1; if ((analog[0].mask & 0x7) == 0x7) max[2] = (max[0] + max[1]) >> 1; if ((analog[0].mask & 0xb) == 0xb) max[3] = (max[0] + max[1]) >> 1; if ((analog[0].mask & ANALOG_BTN_TL) && !(analog[0].mask & ANALOG_BTN_TL2)) max[2] >>= 1; if ((analog[0].mask & ANALOG_BTN_TR) && !(analog[0].mask & ANALOG_BTN_TR2)) max[3] >>= 1; if ((analog[0].mask & ANALOG_HAT_FCS)) max[3] >>= 1; gameport_calibrate(port->gameport, port->axes, max); } for (i = 0; i < 4; i++) port->initial[i] = port->axes[i]; return -!(analog[0].mask || analog[1].mask); }static int analog_init_port(struct gameport *gameport, struct gameport_dev *dev, struct analog_port *port){ int i, t, u, v; gameport->private = port; port->gameport = gameport; init_timer(&port->timer); port->timer.data = (long) port; port->timer.function = analog_timer; if (!gameport_open(gameport, dev, GAMEPORT_MODE_RAW)) { analog_calibrate_timer(port); gameport_trigger(gameport); t = gameport_read(gameport); wait_ms(ANALOG_MAX_TIME); port->mask = (gameport_read(gameport) ^ t) & t & 0xf; port->fuzz = (port->speed * ANALOG_FUZZ_MAGIC) / port->loop / 1000 + ANALOG_FUZZ_BITS; for (i = 0; i < ANALOG_INIT_RETRIES; i++) { if (!analog_cooked_read(port)) break; wait_ms(ANALOG_MAX_TIME); } u = v = 0; wait_ms(ANALOG_MAX_TIME); t = gameport_time(gameport, ANALOG_MAX_TIME * 1000); gameport_trigger(gameport); while ((gameport_read(port->gameport) & port->mask) && (u < t)) u++; udelay(ANALOG_SAITEK_DELAY); t = gameport_time(gameport, ANALOG_SAITEK_TIME); gameport_trigger(gameport); while ((gameport_read(port->gameport) & port->mask) && (v < t)) v++; if (v < (u >> 1) && port->gameport->number < ANALOG_PORTS) { analog_options[port->gameport->number] |= ANALOG_SAITEK | ANALOG_BTNS_CHF | ANALOG_HBTN_CHF | ANALOG_HAT1_CHF; return 0; } gameport_close(gameport); } if (!gameport_open(gameport, dev, GAMEPORT_MODE_COOKED)) { for (i = 0; i < ANALOG_INIT_RETRIES; i++) if (!gameport_cooked_read(gameport, port->axes, &port->buttons)) break; for (i = 0; i < 4; i++) if (port->axes[i] != -1) port->mask |= 1 << i; port->fuzz = gameport->fuzz; port->cooked = 1; return 0; } if (!gameport_open(gameport, dev, GAMEPORT_MODE_RAW)) return 0; return -1;}static void analog_connect(struct gameport *gameport, struct gameport_dev *dev){ struct analog_port *port; int i; if (!(port = kmalloc(sizeof(struct analog_port), GFP_KERNEL))) return; memset(port, 0, sizeof(struct analog_port)); if (analog_init_port(gameport, dev, port)) { kfree(port); return; } if (analog_init_masks(port)) { gameport_close(gameport); kfree(port); return; } for (i = 0; i < 2; i++) if (port->analog[i].mask) analog_init_device(port, port->analog + i, i);}static void analog_disconnect(struct gameport *gameport){ int i; struct analog_port *port = gameport->private; for (i = 0; i < 2; i++) if (port->analog[i].mask) input_unregister_device(&port->analog[i].dev); gameport_close(gameport); printk(KERN_INFO "analog.c: %d out of %d reads (%d%%) on gameport%d failed\n", port->bads, port->reads, port->reads ? (port->bads * 100 / port->reads) : 0, port->gameport->number); kfree(port);}struct analog_types { char *name; int value;};struct analog_types analog_types[] = { { "none", 0x00000000 }, { "auto", 0x000000ff }, { "2btn", 0x0000003f }, { "y-joy", 0x0cc00033 }, { "y-pad", 0x8cc80033 }, { "fcs", 0x000008f7 }, { "chf", 0x000002ff }, { "fullchf", 0x000007ff }, { "gamepad", 0x000830f3 }, { "gamepad8", 0x0008f0f3 }, { NULL, 0 }};static void analog_parse_options(void){ int i, j; char *end; for (i = 0; i < ANALOG_PORTS && js[i]; i++) { for (j = 0; analog_types[j].name; j++) if (!strcmp(analog_types[j].name, js[i])) { analog_options[i] = analog_types[j].value; break; } if (analog_types[j].name) continue; analog_options[i] = simple_strtoul(js[i], &end, 0); if (end != js[i]) continue; analog_options[i] = 0xff; if (!strlen(js[i])) continue; printk(KERN_WARNING "analog.c: Bad config for port %d - \"%s\"\n", i, js[i]); } for (; i < ANALOG_PORTS; i++) analog_options[i] = 0xff;}/* * The gameport device structure. */static struct gameport_dev analog_dev = { connect: analog_connect, disconnect: analog_disconnect,};#ifndef MODULEstatic int __init analog_setup(char *str){ char *s = str; int i = 0; if (!str || !*str) return 0; while ((str = s) && (i < ANALOG_PORTS)) { if ((s = strchr(str,','))) *s++ = 0; js[i++] = str; } return 1;}__setup("js=", analog_setup);#endifint __init analog_init(void){ analog_parse_options(); gameport_register_device(&analog_dev); return 0;}void __exit analog_exit(void){ gameport_unregister_device(&analog_dev);}module_init(analog_init);module_exit(analog_exit);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -