From patchwork Sat Mar 29 16:11:11 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?RGF2aWQgSMODwqRyZGVtYW4=?= X-Patchwork-Id: 3908731 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id CEBF8BF540 for ; Sat, 29 Mar 2014 16:11:37 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C836320357 for ; Sat, 29 Mar 2014 16:11:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C4D5920353 for ; Sat, 29 Mar 2014 16:11:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751891AbaC2QLb (ORCPT ); Sat, 29 Mar 2014 12:11:31 -0400 Received: from hardeman.nu ([95.142.160.32]:38303 "EHLO hardeman.nu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751844AbaC2QLN (ORCPT ); Sat, 29 Mar 2014 12:11:13 -0400 Received: from zeus.hardeman.nu (unknown [IPv6:2001:a60:16f7:7000:dc4d:e884:d412:90f0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by vader.hardeman.nu (Postfix) with ESMTPSA id 1138CC94; Sat, 29 Mar 2014 17:11:12 +0100 (CET) Received: by zeus.hardeman.nu (Postfix, from userid 1000) id 0FFA0C60364; Sat, 29 Mar 2014 17:11:11 +0100 (CET) Subject: [PATCH 05/11] rc-core: split dev->s_filter To: linux-media@vger.kernel.org From: David =?utf-8?b?SMOkcmRlbWFu?= Cc: james.hogan@imgtec.com, m.chehab@samsung.com Date: Sat, 29 Mar 2014 17:11:11 +0100 Message-ID: <20140329161111.13234.73883.stgit@zeus.muc.hardeman.nu> In-Reply-To: <20140329160705.13234.60349.stgit@zeus.muc.hardeman.nu> References: <20140329160705.13234.60349.stgit@zeus.muc.hardeman.nu> User-Agent: StGit/0.15 MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Spam-Status: No, score=-7.3 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, 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 Overloading dev->s_filter to do two different functions (set wakeup filters and generic hardware filters) makes it impossible to tell what the hardware actually supports, so create a separate dev->s_wakeup_filter and make the distinction explicit. Signed-off-by: David Härdeman --- drivers/media/rc/img-ir/img-ir-hw.c | 15 ++++++++++++++- drivers/media/rc/rc-main.c | 31 +++++++++++++++++++------------ include/media/rc-core.h | 6 ++++-- 3 files changed, 37 insertions(+), 15 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/media/rc/img-ir/img-ir-hw.c b/drivers/media/rc/img-ir/img-ir-hw.c index aec79f7..871a9b3 100644 --- a/drivers/media/rc/img-ir/img-ir-hw.c +++ b/drivers/media/rc/img-ir/img-ir-hw.c @@ -504,6 +504,18 @@ unlock: return ret; } +static int img_ir_set_normal_filter(struct rc_dev *dev, + struct rc_scancode_filter *sc_filter) +{ + return img_ir_set_filter(dev, RC_FILTER_NORMAL, sc_filter); +} + +static int img_ir_set_wakeup_filter(struct rc_dev *dev, + struct rc_scancode_filter *sc_filter) +{ + return img_ir_set_filter(dev, RC_FILTER_WAKEUP, sc_filter); +} + /** * img_ir_set_decoder() - Set the current decoder. * @priv: IR private data. @@ -988,7 +1000,8 @@ int img_ir_probe_hw(struct img_ir_priv *priv) rdev->map_name = RC_MAP_EMPTY; rc_set_allowed_protocols(rdev, img_ir_allowed_protos(priv)); rdev->input_name = "IMG Infrared Decoder"; - rdev->s_filter = img_ir_set_filter; + rdev->s_filter = img_ir_set_normal_filter; + rdev->s_wakeup_filter = img_ir_set_wakeup_filter; /* Register hardware decoder */ error = rc_register_device(rdev); diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index c0bfd50..ba955ac 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -929,6 +929,7 @@ static ssize_t store_protocols(struct device *device, int rc, i, count = 0; ssize_t ret; int (*change_protocol)(struct rc_dev *dev, u64 *rc_type); + int (*set_filter)(struct rc_dev *dev, struct rc_scancode_filter *filter); struct rc_scancode_filter local_filter, *filter; /* Device is being removed */ @@ -1013,24 +1014,27 @@ static ssize_t store_protocols(struct device *device, * Fall back to clearing the filter. */ filter = &dev->scancode_filters[fattr->type]; + set_filter = (fattr->type == RC_FILTER_NORMAL) + ? dev->s_filter : dev->s_wakeup_filter; + if (old_type != type && filter->mask) { local_filter = *filter; if (!type) { /* no protocol => clear filter */ ret = -1; - } else if (!dev->s_filter) { + } else if (!set_filter) { /* generic filtering => accept any filter */ ret = 0; } else { /* hardware filtering => try setting, otherwise clear */ - ret = dev->s_filter(dev, fattr->type, &local_filter); + ret = set_filter(dev, &local_filter); } if (ret < 0) { /* clear the filter */ local_filter.data = 0; local_filter.mask = 0; - if (dev->s_filter) - dev->s_filter(dev, fattr->type, &local_filter); + if (set_filter) + set_filter(dev, &local_filter); } /* commit the new filter */ @@ -1112,6 +1116,7 @@ static ssize_t store_filter(struct device *device, struct rc_scancode_filter local_filter, *filter; int ret; unsigned long val; + int (*set_filter)(struct rc_dev *dev, struct rc_scancode_filter *filter); /* Device is being removed */ if (!dev) @@ -1121,9 +1126,11 @@ static ssize_t store_filter(struct device *device, if (ret < 0) return ret; - /* Scancode filter not supported (but still accept 0) */ - if (!dev->s_filter && fattr->type != RC_FILTER_NORMAL) - return val ? -EINVAL : count; + /* Can the scancode filter be set? */ + set_filter = (fattr->type == RC_FILTER_NORMAL) + ? dev->s_filter : dev->s_wakeup_filter; + if (!set_filter) + return -EINVAL; mutex_lock(&dev->lock); @@ -1134,16 +1141,16 @@ static ssize_t store_filter(struct device *device, local_filter.mask = val; else local_filter.data = val; + if (!dev->enabled_protocols[fattr->type] && local_filter.mask) { /* refuse to set a filter unless a protocol is enabled */ ret = -EINVAL; goto unlock; } - if (dev->s_filter) { - ret = dev->s_filter(dev, fattr->type, &local_filter); - if (ret < 0) - goto unlock; - } + + ret = set_filter(dev, &local_filter); + if (ret < 0) + goto unlock; /* Success, commit the new filter */ *filter = local_filter; diff --git a/include/media/rc-core.h b/include/media/rc-core.h index dbbe63e..8c31e4a 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -113,7 +113,8 @@ enum rc_filter_type { * device doesn't interrupt host until it sees IR pulses * @s_learning_mode: enable wide band receiver used for learning * @s_carrier_report: enable carrier reports - * @s_filter: set the scancode filter of a given type + * @s_filter: set the scancode filter + * @s_wakeup_filter: set the wakeup scancode filter */ struct rc_dev { struct device dev; @@ -161,8 +162,9 @@ struct rc_dev { int (*s_learning_mode)(struct rc_dev *dev, int enable); int (*s_carrier_report) (struct rc_dev *dev, int enable); int (*s_filter)(struct rc_dev *dev, - enum rc_filter_type type, struct rc_scancode_filter *filter); + int (*s_wakeup_filter)(struct rc_dev *dev, + struct rc_scancode_filter *filter); }; #define to_rc_dev(d) container_of(d, struct rc_dev, dev)