⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 analog.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	GET_TIME(t2);	GET_TIME(t3);	local_irq_restore(flags);	port->speed = DELTA(t1, t2) - DELTA(t2, t3);	tx = ~0;	for (i = 0; i < 50; i++) {		local_irq_save(flags);		GET_TIME(t1);		for (t = 0; t < 50; t++) { gameport_read(gameport); GET_TIME(t2); }		GET_TIME(t3);		local_irq_restore(flags);		udelay(i);		t = DELTA(t1, t2) - DELTA(t2, t3);		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);	sprintf(analog->phys, "%s/input%d", port->gameport->phys, index);	analog->buttons = (analog->mask & ANALOG_GAMEPAD) ? analog_pad_btn : analog_joy_btn;	init_input_dev(&analog->dev);	analog->dev.name = analog->name;	analog->dev.phys = analog->phys;	analog->dev.id.bustype = BUS_GAMEPORT;	analog->dev.id.vendor = GAMEPORT_ID_VENDOR_ANALOG;	analog->dev.id.product = analog->mask >> 4;	analog->dev.id.version = 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: %s at %s", analog->name, port->gameport->phys);	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, %s), probably not analog joystick.\n",			port->mask, port->gameport->phys);		return -1;	}	i = analog_options[0]; /* FIXME !!! - need to specify options for different ports */	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);		msleep(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;			msleep(ANALOG_MAX_TIME);		}		u = v = 0;		msleep(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)) { /* FIXME - more than one port */			analog_options[0] |= /* FIXME - more than one port */				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 %s failed\n",		port->bads, port->reads, port->reads ? (port->bads * 100 / port->reads) : 0,		port->gameport->phys);	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 < js_nargs; 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,};int __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 + -