From patchwork Tue Jun 14 23:45:54 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Herrmann X-Patchwork-Id: 880562 X-Patchwork-Delegate: jikos@jikos.cz Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p5ENjw6P019029 for ; Tue, 14 Jun 2011 23:46:37 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753644Ab1FNXq0 (ORCPT ); Tue, 14 Jun 2011 19:46:26 -0400 Received: from mail-fx0-f46.google.com ([209.85.161.46]:36667 "EHLO mail-fx0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752089Ab1FNXqZ (ORCPT ); Tue, 14 Jun 2011 19:46:25 -0400 Received: by mail-fx0-f46.google.com with SMTP id 17so41764fxm.19 for ; Tue, 14 Jun 2011 16:46:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=gamma; h=domainkey-signature:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references; bh=q2zeRfNkKaNZUqTk6ZTGRq7vVYpP5hnVz//qB+LxI1U=; b=OnEw2rRpHucmBi5BzWqLo3NWzOy80u3UCAigGeBg94z55bxoUtBkqGBkbmpmfLovj+ 68bG6/mjZ61yE5DdA+uCcWzo0PqvxMofasHLUkgXQ5pZQfuiGNy+kiicLGVoofe04JBR pzEPV1Ec43rRh93g13RQzidZ9lI8jjJdd6n9w= DomainKey-Signature: a=rsa-sha1; c=nofws; d=googlemail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=jdSlTAR2Sr4L6HyZzd1sbxXXTgfIqZToKG11zYe3SkPQJNDhlNdVwSBa2JF6E0QCiC wl69UshHGxWBRCU8O2ffjVRoS1VPDOXwrt8fIz7gahr8DJRTZ93AZUR2oyIrsKXhxgCh ERKCqeu1DI7NC8eaHx0+8CpsXW/ut8IeQgnvU= Received: by 10.223.37.153 with SMTP id x25mr585666fad.117.1308095185050; Tue, 14 Jun 2011 16:46:25 -0700 (PDT) Received: from localhost.localdomain (stgt-4d0383f8.pool.mediaWays.net [77.3.131.248]) by mx.google.com with ESMTPS id g7sm2963789fac.39.2011.06.14.16.46.23 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 14 Jun 2011 16:46:24 -0700 (PDT) From: David Herrmann To: linux-input@vger.kernel.org Cc: jkosina@suse.cz, padovan@profusion.mobi, dh.herrmann@googlemail.com Subject: [RFC 09/12] HID: wiimote: Add wiimote input button parser Date: Wed, 15 Jun 2011 01:45:54 +0200 Message-Id: <1308095157-4699-10-git-send-email-dh.herrmann@googlemail.com> X-Mailer: git-send-email 1.7.5.2 In-Reply-To: <1308095157-4699-1-git-send-email-dh.herrmann@googlemail.com> References: <1308095157-4699-1-git-send-email-dh.herrmann@googlemail.com> Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Tue, 14 Jun 2011 23:46:37 +0000 (UTC) Parse input report 0x30 from the wiimote as button input. We need to send events for all buttons on every input report because the wiimote does not send events for single buttons but always for all buttons to us. The input layer, however, filters redundant events. Signed-off-by: David Herrmann --- drivers/hid/hid-wiimote.c | 66 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 66 insertions(+), 0 deletions(-) diff --git a/drivers/hid/hid-wiimote.c b/drivers/hid/hid-wiimote.c index 0104e41..4c3f5eb 100644 --- a/drivers/hid/hid-wiimote.c +++ b/drivers/hid/hid-wiimote.c @@ -39,6 +39,39 @@ struct wiimote_data { struct work_struct worker; }; +enum wiiproto_reqs { + WIIPROTO_REQ_DRM_K = 0x30, +}; + +enum wiiproto_keys { + WIIPROTO_KEY_LEFT, + WIIPROTO_KEY_RIGHT, + WIIPROTO_KEY_UP, + WIIPROTO_KEY_DOWN, + WIIPROTO_KEY_PLUS, + WIIPROTO_KEY_MINUS, + WIIPROTO_KEY_ONE, + WIIPROTO_KEY_TWO, + WIIPROTO_KEY_A, + WIIPROTO_KEY_B, + WIIPROTO_KEY_HOME, + WIIPROTO_KEY_COUNT +}; + +static __u16 wiiproto_keymap[] = { + KEY_LEFT, /* WIIPROTO_KEY_LEFT */ + KEY_RIGHT, /* WIIPROTO_KEY_RIGHT */ + KEY_UP, /* WIIPROTO_KEY_UP */ + KEY_DOWN, /* WIIPROTO_KEY_DOWN */ + KEY_NEXT, /* WIIPROTO_KEY_PLUS */ + KEY_PREVIOUS, /* WIIPROTO_KEY_MINUS */ + BTN_1, /* WIIPROTO_KEY_ONE */ + BTN_2, /* WIIPROTO_KEY_TWO */ + BTN_A, /* WIIPROTO_KEY_A */ + BTN_B, /* WIIPROTO_KEY_B */ + BTN_MODE, /* WIIPROTO_KEY_HOME */ +}; + static ssize_t wiimote_hid_send(struct hid_device *hdev, __u8 *buffer, size_t count) { @@ -132,6 +165,33 @@ static int wiimote_input_event(struct input_dev *dev, unsigned int type, return 0; } +static void handler_keys(struct wiimote_data *wdata, const __u8 *payload) +{ + input_event(wdata->input, EV_KEY, wiiproto_keymap[WIIPROTO_KEY_LEFT], + !!(payload[0] & 0x01)); + input_event(wdata->input, EV_KEY, wiiproto_keymap[WIIPROTO_KEY_RIGHT], + !!(payload[0] & 0x02)); + input_event(wdata->input, EV_KEY, wiiproto_keymap[WIIPROTO_KEY_DOWN], + !!(payload[0] & 0x04)); + input_event(wdata->input, EV_KEY, wiiproto_keymap[WIIPROTO_KEY_UP], + !!(payload[0] & 0x08)); + input_event(wdata->input, EV_KEY, wiiproto_keymap[WIIPROTO_KEY_PLUS], + !!(payload[0] & 0x10)); + input_event(wdata->input, EV_KEY, wiiproto_keymap[WIIPROTO_KEY_TWO], + !!(payload[1] & 0x01)); + input_event(wdata->input, EV_KEY, wiiproto_keymap[WIIPROTO_KEY_ONE], + !!(payload[1] & 0x02)); + input_event(wdata->input, EV_KEY, wiiproto_keymap[WIIPROTO_KEY_B], + !!(payload[1] & 0x04)); + input_event(wdata->input, EV_KEY, wiiproto_keymap[WIIPROTO_KEY_A], + !!(payload[1] & 0x08)); + input_event(wdata->input, EV_KEY, wiiproto_keymap[WIIPROTO_KEY_MINUS], + !!(payload[1] & 0x10)); + input_event(wdata->input, EV_KEY, wiiproto_keymap[WIIPROTO_KEY_HOME], + !!(payload[1] & 0x80)); + input_event(wdata->input, EV_SYN, SYN_REPORT, 0); +} + struct wiiproto_handler { __u8 id; size_t size; @@ -139,6 +199,7 @@ struct wiiproto_handler { }; static struct wiiproto_handler handlers[] = { + { .id = WIIPROTO_REQ_DRM_K, .size = 2, .func = handler_keys }, { .id = 0 } }; @@ -167,6 +228,7 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report, static struct wiimote_data *wiimote_create(struct hid_device *hdev) { struct wiimote_data *wdata; + int i; wdata = kzalloc(sizeof(*wdata), GFP_KERNEL); if (!wdata) @@ -190,6 +252,10 @@ static struct wiimote_data *wiimote_create(struct hid_device *hdev) wdata->input->id.version = wdata->hdev->version; wdata->input->name = WIIMOTE_NAME; + set_bit(EV_KEY, wdata->input->evbit); + for (i = 0; i < WIIPROTO_KEY_COUNT; ++i) + set_bit(wiiproto_keymap[i], wdata->input->keybit); + spin_lock_init(&wdata->qlock); INIT_WORK(&wdata->worker, wiimote_worker);