From patchwork Fri Jun 17 14:49:19 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Herrmann X-Patchwork-Id: 891802 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 p5HEsZCk010597 for ; Fri, 17 Jun 2011 14:54:37 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932446Ab1FQOyd (ORCPT ); Fri, 17 Jun 2011 10:54:33 -0400 Received: from mail-fx0-f46.google.com ([209.85.161.46]:35712 "EHLO mail-fx0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759252Ab1FQOu0 (ORCPT ); Fri, 17 Jun 2011 10:50:26 -0400 Received: by fxm17 with SMTP id 17so1796203fxm.19 for ; Fri, 17 Jun 2011 07:50: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=icyLt1gShbqagf5srEMyPAMmpgaJyanHnHcREClEFiY=; b=NxTXjL8qjp99gruvuVILHlP1M9/VWrEl53FAX6xvmrz8rRaBLTk3aRZxAu8kCXUrl2 QvAPyr2f0xMZab7IHX8YPElwTTeqxuNSbJdRMwtESBBlpH4/NPx1YKYsb9Lxe4YEp36B aapomPuV8pCWzBcawcgx67bDYTvHhi69SXhw0= 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=BodhsK03jn1HjXBWAIOpGSU3egE8ECRYTi7xoiWvWXrHLXVbyMd6nYLl9Ovbd5kB9b tYH9EoTC0Nqz0t+IJoHlkJdQEmnENgj9R5kP9Xoz028eI6oDlInQmcvVaLySNFfOQLmP sV0YEV3EP+RTpn6iwTGz+lfqh100FH518S0+Y= Received: by 10.223.6.198 with SMTP id a6mr2612503faa.130.1308322224961; Fri, 17 Jun 2011 07:50:24 -0700 (PDT) Received: from localhost.localdomain (stgt-4d039afc.pool.mediaWays.net [77.3.154.252]) by mx.google.com with ESMTPS id o10sm1378710fah.31.2011.06.17.07.50.23 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 17 Jun 2011 07:50:24 -0700 (PDT) From: David Herrmann To: linux-input@vger.kernel.org Cc: padovan@profusion.mobi, jkosina@suse.cz, oliver@neukum.org, dh.herrmann@googlemail.com Subject: [PATCH 09/12 v2] HID: wiimote: Add wiimote input button parser Date: Fri, 17 Jun 2011 16:49:19 +0200 Message-Id: <1308322162-13953-9-git-send-email-dh.herrmann@googlemail.com> X-Mailer: git-send-email 1.7.5.2 In-Reply-To: <1308322162-13953-1-git-send-email-dh.herrmann@googlemail.com> References: <1308322162-13953-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]); Fri, 17 Jun 2011 14:54: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 38e2cfe..9b1df8f 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) { @@ -143,6 +176,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; @@ -150,6 +210,7 @@ struct wiiproto_handler { }; static struct wiiproto_handler handlers[] = { + { .id = WIIPROTO_REQ_DRM_K, .size = 2, .func = handler_keys }, { .id = 0 } }; @@ -179,6 +240,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) @@ -202,6 +264,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);