diff options
Diffstat (limited to 'drivers/media/rc/ati_remote.c')
| -rw-r--r-- | drivers/media/rc/ati_remote.c | 144 | 
1 files changed, 52 insertions, 92 deletions
diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c index 303f22ea04c..baf907b3ce7 100644 --- a/drivers/media/rc/ati_remote.c +++ b/drivers/media/rc/ati_remote.c @@ -189,7 +189,7 @@ struct ati_remote {  	dma_addr_t inbuf_dma;  	dma_addr_t outbuf_dma; -	unsigned char old_data[2];  /* Detect duplicate events */ +	unsigned char old_data;     /* Detect duplicate events */  	unsigned long old_jiffies;  	unsigned long acc_jiffies;  /* handle acceleration */  	unsigned long first_jiffies; @@ -221,35 +221,35 @@ struct ati_remote {  /* Translation table from hardware messages to input events. */  static const struct {  	short kind; -	unsigned char data1, data2; +	unsigned char data;  	int type;  	unsigned int code;  	int value;  }  ati_remote_tbl[] = {  	/* Directional control pad axes */ -	{KIND_ACCEL,   0x35, 0x70, EV_REL, REL_X, -1},	 /* left */ -	{KIND_ACCEL,   0x36, 0x71, EV_REL, REL_X, 1},    /* right */ -	{KIND_ACCEL,   0x37, 0x72, EV_REL, REL_Y, -1},	 /* up */ -	{KIND_ACCEL,   0x38, 0x73, EV_REL, REL_Y, 1},    /* down */ +	{KIND_ACCEL,   0x70, EV_REL, REL_X, -1},   /* left */ +	{KIND_ACCEL,   0x71, EV_REL, REL_X, 1},    /* right */ +	{KIND_ACCEL,   0x72, EV_REL, REL_Y, -1},   /* up */ +	{KIND_ACCEL,   0x73, EV_REL, REL_Y, 1},    /* down */  	/* Directional control pad diagonals */ -	{KIND_LU,      0x39, 0x74, EV_REL, 0, 0},        /* left up */ -	{KIND_RU,      0x3a, 0x75, EV_REL, 0, 0},        /* right up */ -	{KIND_LD,      0x3c, 0x77, EV_REL, 0, 0},        /* left down */ -	{KIND_RD,      0x3b, 0x76, EV_REL, 0, 0},        /* right down */ +	{KIND_LU,      0x74, EV_REL, 0, 0},        /* left up */ +	{KIND_RU,      0x75, EV_REL, 0, 0},        /* right up */ +	{KIND_LD,      0x77, EV_REL, 0, 0},        /* left down */ +	{KIND_RD,      0x76, EV_REL, 0, 0},        /* right down */  	/* "Mouse button" buttons */ -	{KIND_LITERAL, 0x3d, 0x78, EV_KEY, BTN_LEFT, 1}, /* left btn down */ -	{KIND_LITERAL, 0x3e, 0x79, EV_KEY, BTN_LEFT, 0}, /* left btn up */ -	{KIND_LITERAL, 0x41, 0x7c, EV_KEY, BTN_RIGHT, 1},/* right btn down */ -	{KIND_LITERAL, 0x42, 0x7d, EV_KEY, BTN_RIGHT, 0},/* right btn up */ +	{KIND_LITERAL, 0x78, EV_KEY, BTN_LEFT, 1}, /* left btn down */ +	{KIND_LITERAL, 0x79, EV_KEY, BTN_LEFT, 0}, /* left btn up */ +	{KIND_LITERAL, 0x7c, EV_KEY, BTN_RIGHT, 1},/* right btn down */ +	{KIND_LITERAL, 0x7d, EV_KEY, BTN_RIGHT, 0},/* right btn up */  	/* Artificial "doubleclick" events are generated by the hardware.  	 * They are mapped to the "side" and "extra" mouse buttons here. */ -	{KIND_FILTERED, 0x3f, 0x7a, EV_KEY, BTN_SIDE, 1}, /* left dblclick */ -	{KIND_FILTERED, 0x43, 0x7e, EV_KEY, BTN_EXTRA, 1},/* right dblclick */ +	{KIND_FILTERED, 0x7a, EV_KEY, BTN_SIDE, 1}, /* left dblclick */ +	{KIND_FILTERED, 0x7e, EV_KEY, BTN_EXTRA, 1},/* right dblclick */  	/* Non-mouse events are handled by rc-core */ -	{KIND_END, 0x00, 0x00, EV_MAX + 1, 0, 0} +	{KIND_END, 0x00, EV_MAX + 1, 0, 0}  };  /* Local function prototypes */ @@ -397,25 +397,6 @@ static int ati_remote_sendpacket(struct ati_remote *ati_remote, u16 cmd, unsigne  }  /* - *	ati_remote_event_lookup - */ -static int ati_remote_event_lookup(int rem, unsigned char d1, unsigned char d2) -{ -	int i; - -	for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) { -		/* -		 * Decide if the table entry matches the remote input. -		 */ -		if (ati_remote_tbl[i].data1 == d1 && -		    ati_remote_tbl[i].data2 == d2) -			return i; - -	} -	return -1; -} - -/*   *	ati_remote_compute_accel   *   * Implements acceleration curve for directional control pad @@ -463,7 +444,15 @@ static void ati_remote_input_report(struct urb *urb)  	int index = -1;  	int acc;  	int remote_num; -	unsigned char scancode[2]; +	unsigned char scancode; +	int i; + +	/* +	 * data[0] = 0x14 +	 * data[1] = data[2] + data[3] + 0xd5 (a checksum byte) +	 * data[2] = the key code (with toggle bit in MSB with some models) +	 * data[3] = channel << 4 (the low 4 bits must be zero) +	 */  	/* Deal with strange looking inputs */  	if ( (urb->actual_length != 4) || (data[0] != 0x14) || @@ -472,6 +461,13 @@ static void ati_remote_input_report(struct urb *urb)  		return;  	} +	if (data[1] != ((data[2] + data[3] + 0xd5) & 0xff)) { +		dbginfo(&ati_remote->interface->dev, +			"wrong checksum in input: %02x %02x %02x %02x\n", +			data[0], data[1], data[2], data[3]); +		return; +	} +  	/* Mask unwanted remote channels.  */  	/* note: remote_num is 0-based, channel 1 on remote == 0 here */  	remote_num = (data[3] >> 4) & 0x0f; @@ -482,31 +478,30 @@ static void ati_remote_input_report(struct urb *urb)  		return;  	} -	scancode[0] = (((data[1] - ((remote_num + 1) << 4)) & 0xf0) | (data[1] & 0x0f)); -  	/* -	 * Some devices (e.g. SnapStream Firefly) use 8080 as toggle code, -	 * so we have to clear them. The first bit is a bit tricky as the -	 * "non-toggled" state depends on remote_num, so we xor it with the -	 * second bit which is only used for toggle. +	 * MSB is a toggle code, though only used by some devices +	 * (e.g. SnapStream Firefly)  	 */ -	scancode[0] ^= (data[2] & 0x80); +	scancode = data[2] & 0x7f; -	scancode[1] = data[2] & ~0x80; - -	/* Look up event code index in mouse translation table. */ -	index = ati_remote_event_lookup(remote_num, scancode[0], scancode[1]); +	/* Look up event code index in the mouse translation table. */ +	for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) { +		if (scancode == ati_remote_tbl[i].data) { +			index = i; +			break; +		} +	}  	if (index >= 0) {  		dbginfo(&ati_remote->interface->dev, -			"channel 0x%02x; mouse data %02x,%02x; index %d; keycode %d\n", -			remote_num, data[1], data[2], index, ati_remote_tbl[index].code); +			"channel 0x%02x; mouse data %02x; index %d; keycode %d\n", +			remote_num, data[2], index, ati_remote_tbl[index].code);  		if (!dev)  			return; /* no mouse device */  	} else  		dbginfo(&ati_remote->interface->dev, -			"channel 0x%02x; key data %02x,%02x, scancode %02x,%02x\n", -			remote_num, data[1], data[2], scancode[0], scancode[1]); +			"channel 0x%02x; key data %02x, scancode %02x\n", +			remote_num, data[2], scancode);  	if (index >= 0 && ati_remote_tbl[index].kind == KIND_LITERAL) { @@ -523,8 +518,7 @@ static void ati_remote_input_report(struct urb *urb)  		unsigned long now = jiffies;  		/* Filter duplicate events which happen "too close" together. */ -		if (ati_remote->old_data[0] == data[1] && -		    ati_remote->old_data[1] == data[2] && +		if (ati_remote->old_data == data[2] &&  		    time_before(now, ati_remote->old_jiffies +  				     msecs_to_jiffies(repeat_filter))) {  			ati_remote->repeat_count++; @@ -533,8 +527,7 @@ static void ati_remote_input_report(struct urb *urb)  			ati_remote->first_jiffies = now;  		} -		ati_remote->old_data[0] = data[1]; -		ati_remote->old_data[1] = data[2]; +		ati_remote->old_data = data[2];  		ati_remote->old_jiffies = now;  		/* Ensure we skip at least the 4 first duplicate events (generated @@ -549,14 +542,13 @@ static void ati_remote_input_report(struct urb *urb)  		if (index < 0) {  			/* Not a mouse event, hand it to rc-core. */ -			u32 rc_code = (scancode[0] << 8) | scancode[1];  			/*  			 * We don't use the rc-core repeat handling yet as  			 * it would cause ghost repeats which would be a  			 * regression for this driver.  			 */ -			rc_keydown_notimeout(ati_remote->rdev, rc_code, +			rc_keydown_notimeout(ati_remote->rdev, scancode,  					     data[2]);  			rc_keyup(ati_remote->rdev);  			return; @@ -607,8 +599,7 @@ static void ati_remote_input_report(struct urb *urb)  		input_sync(dev);  		ati_remote->old_jiffies = jiffies; -		ati_remote->old_data[0] = data[1]; -		ati_remote->old_data[1] = data[2]; +		ati_remote->old_data = data[2];  	}  } @@ -908,38 +899,7 @@ static void ati_remote_disconnect(struct usb_interface *interface)  	kfree(ati_remote);  } -/* - *	ati_remote_init - */ -static int __init ati_remote_init(void) -{ -	int result; - -	result = usb_register(&ati_remote_driver); -	if (result) -		printk(KERN_ERR KBUILD_MODNAME -		       ": usb_register error #%d\n", result); -	else -		printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" -		       DRIVER_DESC "\n"); - -	return result; -} - -/* - *	ati_remote_exit - */ -static void __exit ati_remote_exit(void) -{ -	usb_deregister(&ati_remote_driver); -} - -/* - *	module specification - */ - -module_init(ati_remote_init); -module_exit(ati_remote_exit); +module_usb_driver(ati_remote_driver);  MODULE_AUTHOR(DRIVER_AUTHOR);  MODULE_DESCRIPTION(DRIVER_DESC);  |