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

📄 grip_mp.c

📁 h内核
💻 C
📖 第 1 页 / 共 2 页
字号:
		else			bads++;	}	return 0;}/* * Packet structure: B0-B15   => gamepad state *                   B16-B20  => gamepad device type *                   B21-B24  => multiport slot index (1-4) * * Known device types: 0x1f (grip pad), 0x0 (no device).  Others may exist. * * Returns the packet status. */static int get_and_decode_packet(struct grip_mp *grip, int flags){	u32 packet;	int joytype = 0;	int slot = 0;	/* Get a packet and check for validity */	flags &= IO_RESET | IO_RETRY;	flags = multiport_io(grip->gameport, flags, 0, &packet);	grip->reads++;	if (packet & PACKET_MP_DONE)		flags |= IO_DONE;	if (flags && !(flags & IO_GOT_PACKET)) {		grip->bads++;		return flags;	}	/* Ignore non-gamepad packets, e.g. multiport hardware version */	slot = ((packet >> 21) & 0xf) - 1;	if ((slot < 0) || (slot > 3))		return flags;	/*	 * Handle "reset" packets, which occur at startup, and when gamepads	 * are removed or plugged in.  May contain configuration of a new gamepad.	 */	joytype = (packet >> 16) & 0x1f;	if (!joytype) {		if (grip->registered[slot]) {			printk(KERN_INFO "grip_mp: removing %s, slot %d\n",			       grip_name[grip->mode[slot]], slot);			input_unregister_device(grip->dev + slot);			grip->registered[slot] = 0;		}		dbg("Reset: grip multiport slot %d\n", slot);		grip->mode[slot] = GRIP_MODE_RESET;		flags |= IO_SLOT_CHANGE;		return flags;	}	/* Interpret a grip pad packet */	if (joytype == 0x1f) {		int dir = (packet >> 8) & 0xf;          /* eight way directional value */		grip->buttons[slot] = (~packet) & 0xff;		grip->yaxes[slot] = ((axis_map[dir] >> 2) & 3) - 1;		grip->xaxes[slot] = (axis_map[dir] & 3) - 1;		grip->dirty[slot] = 1;		if (grip->mode[slot] == GRIP_MODE_RESET)			flags |= IO_SLOT_CHANGE;		grip->mode[slot] = GRIP_MODE_GP;		if (!grip->registered[slot]) {			dbg("New Grip pad in multiport slot %d.\n", slot);			register_slot(slot, grip);		}		return flags;	}	/* Handle non-grip device codes.  For now, just print diagnostics. */	{		static int strange_code = 0;		if (strange_code != joytype) {			printk(KERN_INFO "Possible non-grip pad/joystick detected.\n");			printk(KERN_INFO "Got joy type 0x%x and packet 0x%x.\n", joytype, packet);			strange_code = joytype;		}	}	return flags;}/* * Returns true if all multiport slot states appear valid. */static int slots_valid(struct grip_mp *grip){	int flags, slot, invalid = 0, active = 0;	flags = get_and_decode_packet(grip, 0);	if (!(flags & IO_GOT_PACKET))		return 0;	for (slot = 0; slot < 4; slot++) {		if (grip->mode[slot] == GRIP_MODE_RESET)			invalid = 1;		if (grip->mode[slot] != GRIP_MODE_NONE)			active = 1;	}	/* Return true if no active slot but multiport sent all its data */	if (!active)		return (flags & IO_DONE) ? 1 : 0;	/* Return false if invalid device code received */	return invalid ? 0 : 1;}/* * Returns whether the multiport was placed into digital mode and * able to communicate its state successfully. */static int multiport_init(struct grip_mp *grip){	int dig_mode, initialized = 0, tries = 0;	u32 packet;	dig_mode = dig_mode_start(grip->gameport, &packet);	while (!dig_mode && tries < 4) {		dig_mode = dig_mode_start(grip->gameport, &packet);		tries++;	}	if (dig_mode)		dbg("multiport_init(): digital mode achieved.\n");	else {		dbg("multiport_init(): unable to achieve digital mode.\n");		return 0;	}	/* Get packets, store multiport state, and check state's validity */	for (tries = 0; tries < 4096; tries++) {		if ( slots_valid(grip) ) {			initialized = 1;			break;		}	}	dbg("multiport_init(): initialized == %d\n", initialized);	return initialized;}/* * Reports joystick state to the linux input layer. */static void report_slot(struct grip_mp *grip, int slot){	struct input_dev *dev = &(grip->dev[slot]);	int i, buttons = grip->buttons[slot];	/* Store button states with linux input driver */	for (i = 0; i < 8; i++)		input_report_key(dev, grip_btn_gp[i], (buttons >> i) & 1);	/* Store axis states with linux driver */	input_report_abs(dev, ABS_X, grip->xaxes[slot]);	input_report_abs(dev, ABS_Y, grip->yaxes[slot]);	/* Tell the receiver of the events to process them */	input_sync(dev);	grip->dirty[slot] = 0;}/* * Get the multiport state. */static void get_and_report_mp_state(struct grip_mp *grip){	int i, npkts, flags;	for (npkts = 0; npkts < 4; npkts++) {		flags = IO_RETRY;		for (i = 0; i < 32; i++) {			flags = get_and_decode_packet(grip, flags);			if ((flags & IO_GOT_PACKET) || !(flags & IO_RETRY))				break;		}		if (flags & IO_DONE)			break;	}	for (i = 0; i < 4; i++)		if (grip->dirty[i])			report_slot(grip, i);}/* * Called when a joystick device file is opened */static int grip_open(struct input_dev *dev){	struct grip_mp *grip = dev->private;	if (!grip->used++)		mod_timer(&grip->timer, jiffies + GRIP_REFRESH_TIME);	return 0;}/* * Called when a joystick device file is closed */static void grip_close(struct input_dev *dev){	struct grip_mp *grip = dev->private;	if (!--grip->used)		del_timer(&grip->timer);}/* * Tell the linux input layer about a newly plugged-in gamepad. */static void register_slot(int slot, struct grip_mp *grip){	int j, t;	grip->dev[slot].private = grip;	grip->dev[slot].open = grip_open;	grip->dev[slot].close = grip_close;	grip->dev[slot].name = grip_name[grip->mode[slot]];	grip->dev[slot].id.bustype = BUS_GAMEPORT;	grip->dev[slot].id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;	grip->dev[slot].id.product = 0x0100 + grip->mode[slot];	grip->dev[slot].id.version = 0x0100;	grip->dev[slot].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);	for (j = 0; (t = grip_abs[grip->mode[slot]][j]) >= 0; j++) {		set_bit(t, grip->dev[slot].absbit);		grip->dev[slot].absmin[t] = -1;		grip->dev[slot].absmax[t] = 1;	}	for (j = 0; (t = grip_btn[grip->mode[slot]][j]) >= 0; j++)		if (t > 0)			set_bit(t, grip->dev[slot].keybit);	input_register_device(grip->dev + slot);	grip->registered[slot] = 1;	if (grip->dirty[slot])	            /* report initial state, if any */		report_slot(grip, slot);	printk(KERN_INFO "grip_mp: added %s, slot %d\n",	       grip_name[grip->mode[slot]], slot);}/* * Repeatedly polls the multiport and generates events. */static void grip_timer(unsigned long private){	struct grip_mp *grip = (void*) private;	get_and_report_mp_state(grip);	mod_timer(&grip->timer, jiffies + GRIP_REFRESH_TIME);}static void grip_connect(struct gameport *gameport, struct gameport_dev *dev){	struct grip_mp *grip;	if (!(grip = kmalloc(sizeof(struct grip_mp), GFP_KERNEL)))		return;	memset(grip, 0, sizeof(struct grip_mp));	gameport->private = grip;	grip->gameport = gameport;	init_timer(&grip->timer);	grip->timer.data = (long) grip;	grip->timer.function = grip_timer;	if (gameport_open(gameport, dev, GAMEPORT_MODE_RAW))		goto fail1;	if (!multiport_init(grip))		goto fail2;	if (!grip->mode[0] && !grip->mode[1] &&   /* nothing plugged in */	    !grip->mode[2] && !grip->mode[3])		goto fail2;	return;fail2:	gameport_close(gameport);fail1:	kfree(grip);}static void grip_disconnect(struct gameport *gameport){	int i;	struct grip_mp *grip = gameport->private;	for (i = 0; i < 4; i++)		if (grip->registered[i])			input_unregister_device(grip->dev + i);	gameport_close(gameport);	kfree(grip);}static struct gameport_dev grip_dev = {	.connect	= grip_connect,	.disconnect	= grip_disconnect,};static int grip_init(void){	gameport_register_device(&grip_dev);	return 0;}static void grip_exit(void){	gameport_unregister_device(&grip_dev);}module_init(grip_init);module_exit(grip_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -