psmouse-base.c

来自「优龙2410linux2.6.8内核源代码」· C语言 代码 · 共 801 行 · 第 1/2 页

C
801
字号
	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);	psmouse_command(psmouse, param, PSMOUSE_CMD_GETID);	return param[0] == 4;}/* * psmouse_extensions() probes for any extensions to the basic PS/2 protocol * the mouse may have. */static int psmouse_extensions(struct psmouse *psmouse,			      unsigned int max_proto, int set_properties){	int synaptics_hardware = 0;/* * Try Synaptics TouchPad */	if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse)) {		synaptics_hardware = 1;		if (set_properties) {			psmouse->vendor = "Synaptics";			psmouse->name = "TouchPad";		}		if (max_proto > PSMOUSE_IMEX) {			if (!set_properties || synaptics_init(psmouse) == 0)				return PSMOUSE_SYNAPTICS;/* * Some Synaptics touchpads can emulate extended protocols (like IMPS/2). * Unfortunately Logitech/Genius probes confuse some firmware versions so * we'll have to skip them. */			max_proto = PSMOUSE_IMEX;		}/* * Make sure that touchpad is in relative mode, gestures (taps) are enabled */		synaptics_reset(psmouse);	}	if (max_proto > PSMOUSE_IMEX && genius_detect(psmouse)) {		if (set_properties) {			set_bit(BTN_EXTRA, psmouse->dev.keybit);			set_bit(BTN_SIDE, psmouse->dev.keybit);			set_bit(REL_WHEEL, psmouse->dev.relbit);			psmouse->vendor = "Genius";			psmouse->name = "Wheel Mouse";		}		return PSMOUSE_GENPS;	}	if (max_proto > PSMOUSE_IMEX) {		int type = ps2pp_init(psmouse, set_properties);		if (type > PSMOUSE_PS2)			return type;	}	if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse)) {		if (set_properties) {			set_bit(REL_WHEEL, psmouse->dev.relbit);			set_bit(BTN_SIDE, psmouse->dev.keybit);			set_bit(BTN_EXTRA, psmouse->dev.keybit);			if (!psmouse->name)				psmouse->name = "Explorer Mouse";		}		return PSMOUSE_IMEX;	}	if (max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse)) {		if (set_properties) {			set_bit(REL_WHEEL, psmouse->dev.relbit);			if (!psmouse->name)				psmouse->name = "Wheel Mouse";		}		return PSMOUSE_IMPS;	}/* * Okay, all failed, we have a standard mouse here. The number of the buttons * is still a question, though. We assume 3. */	if (synaptics_hardware) {/* * We detected Synaptics hardware but it did not respond to IMPS/2 probes. * We need to reset the touchpad because if there is a track point on the * pass through port it could get disabled while probing for protocol * extensions. */		psmouse_reset(psmouse);		psmouse_command(psmouse, NULL, PSMOUSE_CMD_RESET_DIS);	}	return PSMOUSE_PS2;}/* * psmouse_probe() probes for a PS/2 mouse. */static int psmouse_probe(struct psmouse *psmouse){	unsigned char param[2];/* * First, we check if it's a mouse. It should send 0x00 or 0x03 * in case of an IntelliMouse in 4-byte mode or 0x04 for IM Explorer. */	param[0] = 0xa5;	if (psmouse_command(psmouse, param, PSMOUSE_CMD_GETID))		return -1;	if (param[0] != 0x00 && param[0] != 0x03 && param[0] != 0x04)		return -1;/* * Then we reset and disable the mouse so that it doesn't generate events. */	if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_RESET_DIS))		printk(KERN_WARNING "psmouse.c: Failed to reset mouse on %s\n", psmouse->serio->phys);	return 0;}/* * Here we set the mouse resolution. */static void psmouse_set_resolution(struct psmouse *psmouse){	unsigned char param[1];	if (psmouse->type == PSMOUSE_PS2PP && psmouse_resolution > 400) {		ps2pp_set_800dpi(psmouse);		return;	}	if (!psmouse_resolution || psmouse_resolution >= 200)		param[0] = 3;	else if (psmouse_resolution >= 100)		param[0] = 2;	else if (psmouse_resolution >= 50)		param[0] = 1;	else if (psmouse_resolution)		param[0] = 0;        psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);}/* * Here we set the mouse report rate. */static void psmouse_set_rate(struct psmouse *psmouse){	unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 };	int i = 0;	while (rates[i] > psmouse_rate) i++;	psmouse_command(psmouse, rates + i, PSMOUSE_CMD_SETRATE);}/* * psmouse_initialize() initializes the mouse to a sane state. */static void psmouse_initialize(struct psmouse *psmouse){	unsigned char param[2];/* * We set the mouse report rate, resolution and scaling. */	if (psmouse_max_proto != PSMOUSE_PS2) {		psmouse_set_rate(psmouse);		psmouse_set_resolution(psmouse);		psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);	}/* * We set the mouse into streaming mode. */	psmouse_command(psmouse, param, PSMOUSE_CMD_SETSTREAM);}/* * psmouse_activate() enables the mouse so that we get motion reports from it. */static void psmouse_activate(struct psmouse *psmouse){	if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_ENABLE))		printk(KERN_WARNING "psmouse.c: Failed to enable mouse on %s\n", psmouse->serio->phys);	psmouse->state = PSMOUSE_ACTIVATED;}/* * psmouse_cleanup() resets the mouse into power-on state. */static void psmouse_cleanup(struct serio *serio){	struct psmouse *psmouse = serio->private;	psmouse_reset(psmouse);}/* * psmouse_disconnect() closes and frees. */static void psmouse_disconnect(struct serio *serio){	struct psmouse *psmouse = serio->private;	psmouse->state = PSMOUSE_CMD_MODE;	if (psmouse->ptport) {		if (psmouse->ptport->deactivate)			psmouse->ptport->deactivate(psmouse);		__serio_unregister_port(&psmouse->ptport->serio); /* we have serio_sem */		kfree(psmouse->ptport);		psmouse->ptport = NULL;	}	if (psmouse->disconnect)		psmouse->disconnect(psmouse);	psmouse->state = PSMOUSE_IGNORE;	input_unregister_device(&psmouse->dev);	serio_close(serio);	kfree(psmouse);}/* * psmouse_connect() is a callback from the serio module when * an unhandled serio port is found. */static void psmouse_connect(struct serio *serio, struct serio_dev *dev){	struct psmouse *psmouse;	if ((serio->type & SERIO_TYPE) != SERIO_8042 &&	    (serio->type & SERIO_TYPE) != SERIO_PS_PSTHRU)		return;	if (!(psmouse = kmalloc(sizeof(struct psmouse), GFP_KERNEL)))		return;	memset(psmouse, 0, sizeof(struct psmouse));	init_input_dev(&psmouse->dev);	psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);	psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);	psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);	psmouse->state = PSMOUSE_CMD_MODE;	psmouse->serio = serio;	psmouse->dev.private = psmouse;	serio->private = psmouse;	if (serio_open(serio, dev)) {		kfree(psmouse);		serio->private = NULL;		return;	}	if (psmouse_probe(psmouse) < 0) {		serio_close(serio);		kfree(psmouse);		serio->private = NULL;		return;	}	psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1);	if (!psmouse->vendor)		psmouse->vendor = "Generic";	if (!psmouse->name)		psmouse->name = "Mouse";	if (!psmouse->protocol_handler)		psmouse->protocol_handler = psmouse_process_byte;	sprintf(psmouse->devname, "%s %s %s",		psmouse_protocols[psmouse->type], psmouse->vendor, psmouse->name);	sprintf(psmouse->phys, "%s/input0",		serio->phys);	psmouse->dev.name = psmouse->devname;	psmouse->dev.phys = psmouse->phys;	psmouse->dev.id.bustype = BUS_I8042;	psmouse->dev.id.vendor = 0x0002;	psmouse->dev.id.product = psmouse->type;	psmouse->dev.id.version = psmouse->model;	input_register_device(&psmouse->dev);	printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys);	psmouse_initialize(psmouse);	if (psmouse->ptport) {		printk(KERN_INFO "serio: %s port at %s\n", psmouse->ptport->serio.name, psmouse->phys);		__serio_register_port(&psmouse->ptport->serio); /* we have serio_sem */		if (psmouse->ptport->activate)			psmouse->ptport->activate(psmouse);	}	psmouse_activate(psmouse);}static int psmouse_reconnect(struct serio *serio){	struct psmouse *psmouse = serio->private;	struct serio_dev *dev = serio->dev;	if (!dev || !psmouse) {		printk(KERN_DEBUG "psmouse: reconnect request, but serio is disconnected, ignoring...\n");		return -1;	}	psmouse->state = PSMOUSE_CMD_MODE;	psmouse->acking = psmouse->cmdcnt = psmouse->pktcnt = psmouse->out_of_sync = 0;	if (psmouse->reconnect) {	       if (psmouse->reconnect(psmouse))			return -1;	} else if (psmouse_probe(psmouse) < 0 ||		   psmouse->type != psmouse_extensions(psmouse, psmouse_max_proto, 0))		return -1;	/* ok, the device type (and capabilities) match the old one,	 * we can continue using it, complete intialization	 */	psmouse_initialize(psmouse);	if (psmouse->ptport) {       		if (psmouse_reconnect(&psmouse->ptport->serio)) {			__serio_unregister_port(&psmouse->ptport->serio);			__serio_register_port(&psmouse->ptport->serio);			if (psmouse->ptport->activate)				psmouse->ptport->activate(psmouse);		}	}	psmouse_activate(psmouse);	return 0;}static struct serio_dev psmouse_dev = {	.interrupt =	psmouse_interrupt,	.connect =	psmouse_connect,	.reconnect =	psmouse_reconnect,	.disconnect =	psmouse_disconnect,	.cleanup =	psmouse_cleanup,};static inline void psmouse_parse_proto(void){	if (psmouse_proto) {		if (!strcmp(psmouse_proto, "bare"))			psmouse_max_proto = PSMOUSE_PS2;		else if (!strcmp(psmouse_proto, "imps"))			psmouse_max_proto = PSMOUSE_IMPS;		else if (!strcmp(psmouse_proto, "exps"))			psmouse_max_proto = PSMOUSE_IMEX;		else			printk(KERN_ERR "psmouse: unknown protocol type '%s'\n", psmouse_proto);	}}int __init psmouse_init(void){	psmouse_parse_proto();	serio_register_device(&psmouse_dev);	return 0;}void __exit psmouse_exit(void){	serio_unregister_device(&psmouse_dev);}module_init(psmouse_init);module_exit(psmouse_exit);

⌨️ 快捷键说明

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