From patchwork Tue Sep 6 11:50:26 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Herrmann X-Patchwork-Id: 1126032 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 p86BpCfu020984 for ; Tue, 6 Sep 2011 11:51:13 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753928Ab1IFLvM (ORCPT ); Tue, 6 Sep 2011 07:51:12 -0400 Received: from mail-fx0-f46.google.com ([209.85.161.46]:44212 "EHLO mail-fx0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754149Ab1IFLvM (ORCPT ); Tue, 6 Sep 2011 07:51:12 -0400 Received: by mail-fx0-f46.google.com with SMTP id 19so4508571fxh.19 for ; Tue, 06 Sep 2011 04:51:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=w5PekbOof+mvTNo6cvyxLnbSm1IPbVO0Od+nayAps/Y=; b=jixDMP1HxDmdV+fMKZNtDxRO4hIQduruaj9Tau5czUe5w4n1klVon29bHLBT9busCq 65rktiMLcZAMZwaG/OVbBFiOlGx0DsNq+XtG2trrFwQve537uiHgLkAGZBU1opu6Gmdj g6F8vhJxFaPRGRciHVM6MMmFkHiRGvKTRuzy4= Received: by 10.223.17.136 with SMTP id s8mr1032859faa.148.1315309871563; Tue, 06 Sep 2011 04:51:11 -0700 (PDT) Received: from localhost.localdomain (stgt-5f708ff4.pool.mediaWays.net [95.112.143.244]) by mx.google.com with ESMTPS id q23sm5071202fae.1.2011.09.06.04.51.09 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 06 Sep 2011 04:51:10 -0700 (PDT) From: David Herrmann To: linux-input@vger.kernel.org Cc: jkosina@suse.cz, David Herrmann Subject: [PATCH v2 01/15] HID: wiimote: Support rumble device Date: Tue, 6 Sep 2011 13:50:26 +0200 Message-Id: <1315309840-4664-2-git-send-email-dh.herrmann@googlemail.com> X-Mailer: git-send-email 1.7.6.1 In-Reply-To: <1315309840-4664-1-git-send-email-dh.herrmann@googlemail.com> References: <1315309840-4664-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, 06 Sep 2011 11:51:13 +0000 (UTC) This adds support for the wiimote's rumble device. Every output report can enable and disable the rumble motor. Hence, every output report must look up our new RUMBLE flag and make sure that it does not unintentionally toggle the rumble motor. Signed-off-by: David Herrmann --- drivers/hid/hid-wiimote.c | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 41 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-wiimote.c b/drivers/hid/hid-wiimote.c index 85a02e5..6809754 100644 --- a/drivers/hid/hid-wiimote.c +++ b/drivers/hid/hid-wiimote.c @@ -46,10 +46,11 @@ struct wiimote_data { struct wiimote_state state; }; -#define WIIPROTO_FLAG_LED1 0x01 -#define WIIPROTO_FLAG_LED2 0x02 -#define WIIPROTO_FLAG_LED3 0x04 -#define WIIPROTO_FLAG_LED4 0x08 +#define WIIPROTO_FLAG_LED1 0x01 +#define WIIPROTO_FLAG_LED2 0x02 +#define WIIPROTO_FLAG_LED3 0x04 +#define WIIPROTO_FLAG_LED4 0x08 +#define WIIPROTO_FLAG_RUMBLE 0x10 #define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \ WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4) @@ -58,6 +59,7 @@ struct wiimote_data { enum wiiproto_reqs { WIIPROTO_REQ_NULL = 0x0, + WIIPROTO_REQ_RUMBLE = 0x10, WIIPROTO_REQ_LED = 0x11, WIIPROTO_REQ_DRM = 0x12, WIIPROTO_REQ_STATUS = 0x20, @@ -172,6 +174,39 @@ static void wiimote_queue(struct wiimote_data *wdata, const __u8 *buffer, spin_unlock_irqrestore(&wdata->qlock, flags); } +/* + * This sets the rumble bit on the given output report if rumble is + * currently enabled. + * \cmd1 must point to the second byte in the output report => &cmd[1] + * This must be called on nearly every output report before passing it + * into the output queue! + */ +static inline void wiiproto_keep_rumble(struct wiimote_data *wdata, __u8 *cmd1) +{ + if (wdata->state.flags & WIIPROTO_FLAG_RUMBLE) + *cmd1 |= 0x01; +} + +static void wiiproto_req_rumble(struct wiimote_data *wdata, __u8 rumble) +{ + __u8 cmd[2]; + + rumble = !!rumble; + if (rumble == !!(wdata->state.flags & WIIPROTO_FLAG_RUMBLE)) + return; + + if (rumble) + wdata->state.flags |= WIIPROTO_FLAG_RUMBLE; + else + wdata->state.flags &= ~WIIPROTO_FLAG_RUMBLE; + + cmd[0] = WIIPROTO_REQ_RUMBLE; + cmd[1] = 0; + + wiiproto_keep_rumble(wdata, &cmd[1]); + wiimote_queue(wdata, cmd, sizeof(cmd)); +} + static void wiiproto_req_leds(struct wiimote_data *wdata, int leds) { __u8 cmd[2]; @@ -193,6 +228,7 @@ static void wiiproto_req_leds(struct wiimote_data *wdata, int leds) if (leds & WIIPROTO_FLAG_LED4) cmd[1] |= 0x80; + wiiproto_keep_rumble(wdata, &cmd[1]); wiimote_queue(wdata, cmd, sizeof(cmd)); } @@ -217,6 +253,7 @@ static void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm) cmd[1] = 0; cmd[2] = drm; + wiiproto_keep_rumble(wdata, &cmd[1]); wiimote_queue(wdata, cmd, sizeof(cmd)); }