aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@googlemail.com>2011-09-06 07:50:30 -0400
committerJiri Kosina <jkosina@suse.cz>2011-09-07 07:25:16 -0400
commitf363e4f6ab71168cbdaadeef974b515512b41636 (patch)
treeca8a6a0e7347ea850d329e5c30a97dad038379a5
parentefcf91887419ec37ca564073a9fe30db49fe6c7c (diff)
HID: wiimote: Add IR input device
The IR cam of the wiimote reports 4 trackable lights as absolute values. Since we can turn the IR cam on and off, we register a separate input device so we can react on open/close callbacks to save wiimote battery power when IR cam is not needed. The cam can be in four states: off, basic, extended and full The DRM chooser automatically selects a proper DRM that includes all required IR data so no information is lost. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-wiimote.c71
1 files changed, 67 insertions, 4 deletions
diff --git a/drivers/hid/hid-wiimote.c b/drivers/hid/hid-wiimote.c
index de9aadf9218d..4cdaaf6e0307 100644
--- a/drivers/hid/hid-wiimote.c
+++ b/drivers/hid/hid-wiimote.c
@@ -38,6 +38,7 @@ struct wiimote_data {
38 struct input_dev *input; 38 struct input_dev *input;
39 struct led_classdev *leds[4]; 39 struct led_classdev *leds[4];
40 struct input_dev *accel; 40 struct input_dev *accel;
41 struct input_dev *ir;
41 42
42 spinlock_t qlock; 43 spinlock_t qlock;
43 __u8 head; 44 __u8 head;
@@ -54,8 +55,13 @@ struct wiimote_data {
54#define WIIPROTO_FLAG_LED4 0x08 55#define WIIPROTO_FLAG_LED4 0x08
55#define WIIPROTO_FLAG_RUMBLE 0x10 56#define WIIPROTO_FLAG_RUMBLE 0x10
56#define WIIPROTO_FLAG_ACCEL 0x20 57#define WIIPROTO_FLAG_ACCEL 0x20
58#define WIIPROTO_FLAG_IR_BASIC 0x40
59#define WIIPROTO_FLAG_IR_EXT 0x80
60#define WIIPROTO_FLAG_IR_FULL 0xc0 /* IR_BASIC | IR_EXT */
57#define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \ 61#define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \
58 WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4) 62 WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4)
63#define WIIPROTO_FLAGS_IR (WIIPROTO_FLAG_IR_BASIC | WIIPROTO_FLAG_IR_EXT | \
64 WIIPROTO_FLAG_IR_FULL)
59 65
60/* return flag for led \num */ 66/* return flag for led \num */
61#define WIIPROTO_FLAG_LED(num) (WIIPROTO_FLAG_LED1 << (num - 1)) 67#define WIIPROTO_FLAG_LED(num) (WIIPROTO_FLAG_LED1 << (num - 1))
@@ -71,6 +77,7 @@ enum wiiproto_reqs {
71 WIIPROTO_REQ_DRM_KA = 0x31, 77 WIIPROTO_REQ_DRM_KA = 0x31,
72 WIIPROTO_REQ_DRM_KAI = 0x33, 78 WIIPROTO_REQ_DRM_KAI = 0x33,
73 WIIPROTO_REQ_DRM_KAE = 0x35, 79 WIIPROTO_REQ_DRM_KAE = 0x35,
80 WIIPROTO_REQ_DRM_KIE = 0x36,
74 WIIPROTO_REQ_DRM_KAIE = 0x37, 81 WIIPROTO_REQ_DRM_KAIE = 0x37,
75 WIIPROTO_REQ_DRM_SKAI1 = 0x3e, 82 WIIPROTO_REQ_DRM_SKAI1 = 0x3e,
76 WIIPROTO_REQ_DRM_SKAI2 = 0x3f, 83 WIIPROTO_REQ_DRM_SKAI2 = 0x3f,
@@ -248,10 +255,23 @@ static void wiiproto_req_leds(struct wiimote_data *wdata, int leds)
248 */ 255 */
249static __u8 select_drm(struct wiimote_data *wdata) 256static __u8 select_drm(struct wiimote_data *wdata)
250{ 257{
251 if (wdata->state.flags & WIIPROTO_FLAG_ACCEL) 258 __u8 ir = wdata->state.flags & WIIPROTO_FLAGS_IR;
252 return WIIPROTO_REQ_DRM_KA; 259
253 else 260 if (ir == WIIPROTO_FLAG_IR_BASIC) {
254 return WIIPROTO_REQ_DRM_K; 261 if (wdata->state.flags & WIIPROTO_FLAG_ACCEL)
262 return WIIPROTO_REQ_DRM_KAIE;
263 else
264 return WIIPROTO_REQ_DRM_KIE;
265 } else if (ir == WIIPROTO_FLAG_IR_EXT) {
266 return WIIPROTO_REQ_DRM_KAI;
267 } else if (ir == WIIPROTO_FLAG_IR_FULL) {
268 return WIIPROTO_REQ_DRM_SKAI1;
269 } else {
270 if (wdata->state.flags & WIIPROTO_FLAG_ACCEL)
271 return WIIPROTO_REQ_DRM_KA;
272 else
273 return WIIPROTO_REQ_DRM_K;
274 }
255} 275}
256 276
257static void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm) 277static void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm)
@@ -681,6 +701,36 @@ static struct wiimote_data *wiimote_create(struct hid_device *hdev)
681 input_set_abs_params(wdata->accel, ABS_RY, -500, 500, 2, 4); 701 input_set_abs_params(wdata->accel, ABS_RY, -500, 500, 2, 4);
682 input_set_abs_params(wdata->accel, ABS_RZ, -500, 500, 2, 4); 702 input_set_abs_params(wdata->accel, ABS_RZ, -500, 500, 2, 4);
683 703
704 wdata->ir = input_allocate_device();
705 if (!wdata->ir)
706 goto err_ir;
707
708 input_set_drvdata(wdata->ir, wdata);
709 wdata->ir->dev.parent = &wdata->hdev->dev;
710 wdata->ir->id.bustype = wdata->hdev->bus;
711 wdata->ir->id.vendor = wdata->hdev->vendor;
712 wdata->ir->id.product = wdata->hdev->product;
713 wdata->ir->id.version = wdata->hdev->version;
714 wdata->ir->name = WIIMOTE_NAME " IR";
715
716 set_bit(EV_ABS, wdata->ir->evbit);
717 set_bit(ABS_HAT0X, wdata->ir->absbit);
718 set_bit(ABS_HAT0Y, wdata->ir->absbit);
719 set_bit(ABS_HAT1X, wdata->ir->absbit);
720 set_bit(ABS_HAT1Y, wdata->ir->absbit);
721 set_bit(ABS_HAT2X, wdata->ir->absbit);
722 set_bit(ABS_HAT2Y, wdata->ir->absbit);
723 set_bit(ABS_HAT3X, wdata->ir->absbit);
724 set_bit(ABS_HAT3Y, wdata->ir->absbit);
725 input_set_abs_params(wdata->ir, ABS_HAT0X, 0, 1023, 2, 4);
726 input_set_abs_params(wdata->ir, ABS_HAT0Y, 0, 767, 2, 4);
727 input_set_abs_params(wdata->ir, ABS_HAT1X, 0, 1023, 2, 4);
728 input_set_abs_params(wdata->ir, ABS_HAT1Y, 0, 767, 2, 4);
729 input_set_abs_params(wdata->ir, ABS_HAT2X, 0, 1023, 2, 4);
730 input_set_abs_params(wdata->ir, ABS_HAT2Y, 0, 767, 2, 4);
731 input_set_abs_params(wdata->ir, ABS_HAT3X, 0, 1023, 2, 4);
732 input_set_abs_params(wdata->ir, ABS_HAT3Y, 0, 767, 2, 4);
733
684 spin_lock_init(&wdata->qlock); 734 spin_lock_init(&wdata->qlock);
685 INIT_WORK(&wdata->worker, wiimote_worker); 735 INIT_WORK(&wdata->worker, wiimote_worker);
686 736
@@ -688,6 +738,8 @@ static struct wiimote_data *wiimote_create(struct hid_device *hdev)
688 738
689 return wdata; 739 return wdata;
690 740
741err_ir:
742 input_free_device(wdata->accel);
691err_input: 743err_input:
692 input_free_device(wdata->input); 744 input_free_device(wdata->input);
693err: 745err:
@@ -700,6 +752,7 @@ static void wiimote_destroy(struct wiimote_data *wdata)
700 wiimote_leds_destroy(wdata); 752 wiimote_leds_destroy(wdata);
701 753
702 input_unregister_device(wdata->accel); 754 input_unregister_device(wdata->accel);
755 input_unregister_device(wdata->ir);
703 input_unregister_device(wdata->input); 756 input_unregister_device(wdata->input);
704 cancel_work_sync(&wdata->worker); 757 cancel_work_sync(&wdata->worker);
705 hid_hw_stop(wdata->hdev); 758 hid_hw_stop(wdata->hdev);
@@ -737,6 +790,12 @@ static int wiimote_hid_probe(struct hid_device *hdev,
737 goto err_stop; 790 goto err_stop;
738 } 791 }
739 792
793 ret = input_register_device(wdata->ir);
794 if (ret) {
795 hid_err(hdev, "Cannot register input device\n");
796 goto err_ir;
797 }
798
740 ret = input_register_device(wdata->input); 799 ret = input_register_device(wdata->input);
741 if (ret) { 800 if (ret) {
742 hid_err(hdev, "Cannot register input device\n"); 801 hid_err(hdev, "Cannot register input device\n");
@@ -761,11 +820,15 @@ err_free:
761 return ret; 820 return ret;
762 821
763err_input: 822err_input:
823 input_unregister_device(wdata->ir);
824 wdata->ir = NULL;
825err_ir:
764 input_unregister_device(wdata->accel); 826 input_unregister_device(wdata->accel);
765 wdata->accel = NULL; 827 wdata->accel = NULL;
766err_stop: 828err_stop:
767 hid_hw_stop(hdev); 829 hid_hw_stop(hdev);
768err: 830err:
831 input_free_device(wdata->ir);
769 input_free_device(wdata->accel); 832 input_free_device(wdata->accel);
770 input_free_device(wdata->input); 833 input_free_device(wdata->input);
771 kfree(wdata); 834 kfree(wdata);