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

📄 grip_mp.c

📁 linux-2.6.15.6
💻 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){	struct grip_port *port;	u32 packet;	int joytype = 0;	int slot;	/* 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;	port = grip->port[slot];	/*	 * 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 (port->registered) {			printk(KERN_INFO "grip_mp: removing %s, slot %d\n",			       grip_name[port->mode], slot);			input_unregister_device(port->dev);			port->registered = 0;		}		dbg("Reset: grip multiport slot %d\n", slot);		port->mode = 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 */		port->buttons = (~packet) & 0xff;		port->yaxes = ((axis_map[dir] >> 2) & 3) - 1;		port->xaxes = (axis_map[dir] & 3) - 1;		port->dirty = 1;		if (port->mode == GRIP_MODE_RESET)			flags |= IO_SLOT_CHANGE;		port->mode = GRIP_MODE_GP;		if (!port->registered) {			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->port[slot]->mode == GRIP_MODE_RESET)			invalid = 1;		if (grip->port[slot]->mode != 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 activated.\n");	else {		dbg("multiport_init(): unable to activate 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 grip_port *port = grip->port[slot];	int i;	/* Store button states with linux input driver */	for (i = 0; i < 8; i++)		input_report_key(port->dev, grip_btn_gp[i], (port->buttons >> i) & 1);	/* Store axis states with linux driver */	input_report_abs(port->dev, ABS_X, port->xaxes);	input_report_abs(port->dev, ABS_Y, port->yaxes);	/* Tell the receiver of the events to process them */	input_sync(port->dev);	port->dirty = 0;}/* * Get the multiport state. */static void grip_poll(struct gameport *gameport){	struct grip_mp *grip = gameport_get_drvdata(gameport);	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->port[i]->dirty)			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;	gameport_start_polling(grip->gameport);	return 0;}/* * Called when a joystick device file is closed */static void grip_close(struct input_dev *dev){	struct grip_mp *grip = dev->private;	gameport_start_polling(grip->gameport);}/* * Tell the linux input layer about a newly plugged-in gamepad. */static int register_slot(int slot, struct grip_mp *grip){	struct grip_port *port = grip->port[slot];	struct input_dev *input_dev;	int j, t;	port->dev = input_dev = input_allocate_device();	if (!input_dev)		return -ENOMEM;	input_dev->name = grip_name[port->mode];	input_dev->id.bustype = BUS_GAMEPORT;	input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;	input_dev->id.product = 0x0100 + port->mode;	input_dev->id.version = 0x0100;	input_dev->cdev.dev = &grip->gameport->dev;	input_dev->private = grip;	input_dev->open = grip_open;	input_dev->close = grip_close;	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);	for (j = 0; (t = grip_abs[port->mode][j]) >= 0; j++)		input_set_abs_params(input_dev, t, -1, 1, 0, 0);	for (j = 0; (t = grip_btn[port->mode][j]) >= 0; j++)		if (t > 0)			set_bit(t, input_dev->keybit);	input_register_device(port->dev);	port->registered = 1;	if (port->dirty)	            /* report initial state, if any */		report_slot(grip, slot);	return 0;}static int grip_connect(struct gameport *gameport, struct gameport_driver *drv){	struct grip_mp *grip;	int err;	if (!(grip = kzalloc(sizeof(struct grip_mp), GFP_KERNEL)))		return -ENOMEM;	grip->gameport = gameport;	gameport_set_drvdata(gameport, grip);	err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW);	if (err)		goto fail1;	gameport_set_poll_handler(gameport, grip_poll);	gameport_set_poll_interval(gameport, 20);	if (!multiport_init(grip)) {		err = -ENODEV;		goto fail2;	}	if (!grip->port[0]->mode && !grip->port[1]->mode && !grip->port[2]->mode && !grip->port[3]->mode) {		/* nothing plugged in */		err = -ENODEV;		goto fail2;	}	return 0;fail2:	gameport_close(gameport);fail1:	gameport_set_drvdata(gameport, NULL);	kfree(grip);	return err;}static void grip_disconnect(struct gameport *gameport){	struct grip_mp *grip = gameport_get_drvdata(gameport);	int i;	for (i = 0; i < 4; i++)		if (grip->port[i]->registered)			input_unregister_device(grip->port[i]->dev);	gameport_close(gameport);	gameport_set_drvdata(gameport, NULL);	kfree(grip);}static struct gameport_driver grip_drv = {	.driver		= {		.name	= "grip_mp",	},	.description	= DRIVER_DESC,	.connect	= grip_connect,	.disconnect	= grip_disconnect,};static int __init grip_init(void){	gameport_register_driver(&grip_drv);	return 0;}static void __exit grip_exit(void){	gameport_unregister_driver(&grip_drv);}module_init(grip_init);module_exit(grip_exit);

⌨️ 快捷键说明

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