From patchwork Fri Nov 1 20:16:18 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Herrmann X-Patchwork-Id: 3127611 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id C725C9F3C4 for ; Fri, 1 Nov 2013 20:16:59 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C70AE204AE for ; Fri, 1 Nov 2013 20:16:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B6E7B204C9 for ; Fri, 1 Nov 2013 20:16:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753243Ab3KAUQz (ORCPT ); Fri, 1 Nov 2013 16:16:55 -0400 Received: from mail-ee0-f48.google.com ([74.125.83.48]:40210 "EHLO mail-ee0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753223Ab3KAUQz (ORCPT ); Fri, 1 Nov 2013 16:16:55 -0400 Received: by mail-ee0-f48.google.com with SMTP id d49so4936eek.7 for ; Fri, 01 Nov 2013 13:16:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=nRmRXwbxlwOctFoGgr0KKY9B6CDGrcr5Kbl7PGyRS/4=; b=GPWBTERjGvCaQuTfkiVPrfqQrFP46S4pxxy5Mb2fhAZHkkl8YOsAeQFXmvhMXNBZcK MBU/MMhNAi0JO7OfgCHULVk4AA5hn2uEwPKUGjLYwF3yXDrfnaRieSa9TVDE3AM85FpB r19i+APkBPNENRRbN53cv3xVcxW/fEAUIwcNlkPW5XLjCsAhJ+9SCbmDEd7McI+pIxKe sGQUOKpv4sbjYW8mwJsfzpoGcLmqbJREv64fMP/1MFCkvqWv9tySjbVc1wfzSgTKoCyc eymtkxJne8ct+CZtK+EQO9j/SvUDxIlQwxQqbAjCcXB2nIRSlm9K0zbd7+qxF/Q+YfWc 3rUQ== X-Received: by 10.15.77.132 with SMTP id p4mr762903eey.95.1383337014004; Fri, 01 Nov 2013 13:16:54 -0700 (PDT) Received: from localhost.localdomain (stgt-5f719f65.pool.mediaWays.net. [95.113.159.101]) by mx.google.com with ESMTPSA id i1sm11797335eeg.0.2013.11.01.13.16.52 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 Nov 2013 13:16:53 -0700 (PDT) From: David Herrmann To: linux-input@vger.kernel.org Cc: Dmitry Torokhov , Jiri Kosina , Peter Hutterer , Benjamin Tissoires , David Herrmann Subject: [PATCH 07/13] HID: wiimote: map nunchuk as real gamepad Date: Fri, 1 Nov 2013 21:16:18 +0100 Message-Id: <1383336984-26601-8-git-send-email-dh.herrmann@gmail.com> X-Mailer: git-send-email 1.8.4.1 In-Reply-To: <1383336984-26601-1-git-send-email-dh.herrmann@gmail.com> References: <1383336984-26601-1-git-send-email-dh.herrmann@gmail.com> Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Spam-Status: No, score=-7.3 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The nunchuk device can easily be used as reduced gamepad. Add a new mapping according to linux gamepad rules. Note that we map it as gamepad with: - one analog-stick (left) - two trigger buttons (left upper+lower) - accelerometer Signed-off-by: David Herrmann --- drivers/hid/hid-wiimote-modules.c | 94 ++++++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 27 deletions(-) diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c index 372fec1..a02059c 100644 --- a/drivers/hid/hid-wiimote-modules.c +++ b/drivers/hid/hid-wiimote-modules.c @@ -839,15 +839,24 @@ enum wiimod_nunchuk_keys { WIIMOD_NUNCHUK_KEY_NUM, }; -static const __u16 wiimod_nunchuk_map[] = { +static const __u16 wiimod_nunchuk_map_legacy[] = { BTN_C, /* WIIMOD_NUNCHUK_KEY_C */ BTN_Z, /* WIIMOD_NUNCHUK_KEY_Z */ }; +static const __u16 wiimod_nunchuk_map[] = { + BTN_TL, /* WIIMOD_NUNCHUK_KEY_C */ + BTN_TL2, /* WIIMOD_NUNCHUK_KEY_Z */ +}; + static void wiimod_nunchuk_in_ext(struct wiimote_data *wdata, const __u8 *ext) { + const __u16 *map = wiimod_nunchuk_map; __s16 x, y, z, bx, by; + if (wdata->state.flags & WIIPROTO_FLAG_LEGACY) + map = wiimod_nunchuk_map_legacy; + /* Byte | 8 7 | 6 5 | 4 3 | 2 | 1 | * -----+----------+---------+---------+----+-----+ * 1 | Button X <7:0> | @@ -902,26 +911,35 @@ static void wiimod_nunchuk_in_ext(struct wiimote_data *wdata, const __u8 *ext) y -= 0x200; z -= 0x200; - input_report_abs(wdata->extension.input, ABS_HAT0X, bx); - input_report_abs(wdata->extension.input, ABS_HAT0Y, by); + if (wdata->state.flags & WIIPROTO_FLAG_LEGACY) { + input_report_abs(wdata->extension.input, ABS_HAT0X, bx); + input_report_abs(wdata->extension.input, ABS_HAT0Y, by); - input_report_abs(wdata->extension.input, ABS_RX, x); - input_report_abs(wdata->extension.input, ABS_RY, y); - input_report_abs(wdata->extension.input, ABS_RZ, z); + input_report_abs(wdata->extension.input, ABS_RX, x); + input_report_abs(wdata->extension.input, ABS_RY, y); + input_report_abs(wdata->extension.input, ABS_RZ, z); + } else { + input_report_abs(wdata->extension.input, ABS_X, bx); + input_report_abs(wdata->extension.input, ABS_Y, -by); + + input_report_abs(wdata->extension.input, ABS_ACCEL_X, x); + input_report_abs(wdata->extension.input, ABS_ACCEL_Y, y); + input_report_abs(wdata->extension.input, ABS_ACCEL_Z, z); + } if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) { input_report_key(wdata->extension.input, - wiimod_nunchuk_map[WIIMOD_NUNCHUK_KEY_Z], + map[WIIMOD_NUNCHUK_KEY_Z], !(ext[5] & 0x04)); input_report_key(wdata->extension.input, - wiimod_nunchuk_map[WIIMOD_NUNCHUK_KEY_C], + map[WIIMOD_NUNCHUK_KEY_C], !(ext[5] & 0x08)); } else { input_report_key(wdata->extension.input, - wiimod_nunchuk_map[WIIMOD_NUNCHUK_KEY_Z], + map[WIIMOD_NUNCHUK_KEY_Z], !(ext[5] & 0x01)); input_report_key(wdata->extension.input, - wiimod_nunchuk_map[WIIMOD_NUNCHUK_KEY_C], + map[WIIMOD_NUNCHUK_KEY_C], !(ext[5] & 0x02)); } @@ -955,12 +973,16 @@ static void wiimod_nunchuk_close(struct input_dev *dev) static int wiimod_nunchuk_probe(const struct wiimod_ops *ops, struct wiimote_data *wdata) { + const __u16 *map = wiimod_nunchuk_map; int ret, i; wdata->extension.input = input_allocate_device(); if (!wdata->extension.input) return -ENOMEM; + if (wdata->state.flags & WIIPROTO_FLAG_LEGACY) + map = wiimod_nunchuk_map_legacy; + input_set_drvdata(wdata->extension.input, wdata); wdata->extension.input->open = wiimod_nunchuk_open; wdata->extension.input->close = wiimod_nunchuk_close; @@ -973,25 +995,43 @@ static int wiimod_nunchuk_probe(const struct wiimod_ops *ops, set_bit(EV_KEY, wdata->extension.input->evbit); for (i = 0; i < WIIMOD_NUNCHUK_KEY_NUM; ++i) - set_bit(wiimod_nunchuk_map[i], - wdata->extension.input->keybit); + set_bit(map[i], wdata->extension.input->keybit); set_bit(EV_ABS, wdata->extension.input->evbit); - set_bit(ABS_HAT0X, wdata->extension.input->absbit); - set_bit(ABS_HAT0Y, wdata->extension.input->absbit); - input_set_abs_params(wdata->extension.input, - ABS_HAT0X, -120, 120, 2, 4); - input_set_abs_params(wdata->extension.input, - ABS_HAT0Y, -120, 120, 2, 4); - set_bit(ABS_RX, wdata->extension.input->absbit); - set_bit(ABS_RY, wdata->extension.input->absbit); - set_bit(ABS_RZ, wdata->extension.input->absbit); - input_set_abs_params(wdata->extension.input, - ABS_RX, -500, 500, 2, 4); - input_set_abs_params(wdata->extension.input, - ABS_RY, -500, 500, 2, 4); - input_set_abs_params(wdata->extension.input, - ABS_RZ, -500, 500, 2, 4); + + if (wdata->state.flags & WIIPROTO_FLAG_LEGACY) { + set_bit(ABS_HAT0X, wdata->extension.input->absbit); + set_bit(ABS_HAT0Y, wdata->extension.input->absbit); + input_set_abs_params(wdata->extension.input, + ABS_HAT0X, -120, 120, 2, 4); + input_set_abs_params(wdata->extension.input, + ABS_HAT0Y, -120, 120, 2, 4); + set_bit(ABS_RX, wdata->extension.input->absbit); + set_bit(ABS_RY, wdata->extension.input->absbit); + set_bit(ABS_RZ, wdata->extension.input->absbit); + input_set_abs_params(wdata->extension.input, + ABS_RX, -500, 500, 2, 4); + input_set_abs_params(wdata->extension.input, + ABS_RY, -500, 500, 2, 4); + input_set_abs_params(wdata->extension.input, + ABS_RZ, -500, 500, 2, 4); + } else { + set_bit(ABS_X, wdata->extension.input->absbit); + set_bit(ABS_Y, wdata->extension.input->absbit); + input_set_abs_params(wdata->extension.input, + ABS_X, -120, 120, 2, 4); + input_set_abs_params(wdata->extension.input, + ABS_Y, -120, 120, 2, 4); + set_bit(ABS_ACCEL_X, wdata->extension.input->absbit); + set_bit(ABS_ACCEL_Y, wdata->extension.input->absbit); + set_bit(ABS_ACCEL_Z, wdata->extension.input->absbit); + input_set_abs_params(wdata->extension.input, + ABS_ACCEL_X, -500, 500, 2, 4); + input_set_abs_params(wdata->extension.input, + ABS_ACCEL_Y, -500, 500, 2, 4); + input_set_abs_params(wdata->extension.input, + ABS_ACCEL_Z, -500, 500, 2, 4); + } ret = input_register_device(wdata->extension.input); if (ret)