From patchwork Fri Jun 12 06:56:36 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dudley Du X-Patchwork-Id: 6595111 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.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id F41459F6E4 for ; Fri, 12 Jun 2015 07:19:43 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B5B6F20634 for ; Fri, 12 Jun 2015 07:19:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3AAD420425 for ; Fri, 12 Jun 2015 07:19:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932276AbbFLHSP (ORCPT ); Fri, 12 Jun 2015 03:18:15 -0400 Received: from smtp1.cypress.com ([157.95.67.100]:58008 "EHLO smtp1.cypress.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932072AbbFLHSM (ORCPT ); Fri, 12 Jun 2015 03:18:12 -0400 Received: from corpmail1.cypress.com (corpmail1.mis.cypress.com [172.16.5.228]) by smtp1.cypress.com (8.13.8/8.13.8) with ESMTP id t5C6vU5R016731; Thu, 11 Jun 2015 23:57:30 -0700 Received: from mailhost.mis.cypress.com (mailhost [172.16.2.5]) by corpmail1.cypress.com (8.14.4/8.14.4) with ESMTP id t5C6vUwB011129; Thu, 11 Jun 2015 23:57:30 -0700 Received: from localhost ([172.23.6.229]) by mailhost.mis.cypress.com (8.12.11/8.12.11) with ESMTP id t5C6vSUQ005708; Thu, 11 Jun 2015 23:57:29 -0700 (PDT) From: Dudley Du To: dmitry.torokhov@gmail.com, mark.rutland@arm.com, robh+dt@kernel.org, rydberg@euromail.se Cc: Dudley Du , bleung@google.com, jmmahler@gmail.com, devicetree@vger.kernel.org, linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 5/7] input: cyapa: add proximity and interrupt sysfs interfaces support Date: Fri, 12 Jun 2015 14:56:36 +0800 Message-Id: <1434092198-13018-6-git-send-email-dudl@cypress.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1434092198-13018-1-git-send-email-dudl@cypress.com> References: <1434092198-13018-1-git-send-email-dudl@cypress.com> MIME-Version: 1.0 X-Cypress-MailScanner-Information: Please contact the ISP for more information X-Cypress-MailScanner-ID: t5C6vU5R016731 X-Cypress-MailScanner-From: dudl@cypress.com X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add proximity and interrupt control interfaces in sysfs device node. The proximity interface is used to disable/enable proximity function in device. The interrupt interface is used to disbale/enable interrupt from device. TEST=test on Chromebook. Signed-off-by: Dudley Du --- drivers/input/mouse/cyapa.c | 101 +++++++++++++++++++++++++++++++++++++++ drivers/input/mouse/cyapa.h | 4 ++ drivers/input/mouse/cyapa_gen3.c | 1 + drivers/input/mouse/cyapa_gen5.c | 2 + drivers/input/mouse/cyapa_gen6.c | 14 ++++++ 5 files changed, 122 insertions(+) diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c index faead4d..86f2263 100644 --- a/drivers/input/mouse/cyapa.c +++ b/drivers/input/mouse/cyapa.c @@ -594,6 +594,7 @@ static int cyapa_initialize(struct cyapa *cyapa) cyapa->state = CYAPA_STATE_NO_DEVICE; cyapa->gen = CYAPA_GEN_UNKNOWN; + cyapa->interrupt = true; mutex_init(&cyapa->state_sync_lock); /* @@ -1217,12 +1218,110 @@ static ssize_t cyapa_show_mode(struct device *dev, return size; } +static ssize_t cyapa_show_interrupt(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct cyapa *cyapa = dev_get_drvdata(dev); + int size; + int error; + + error = mutex_lock_interruptible(&cyapa->state_sync_lock); + if (error) + return error; + + size = scnprintf(buf, PAGE_SIZE, "%d\n", cyapa->interrupt ? 1 : 0); + + mutex_unlock(&cyapa->state_sync_lock); + return size; +} + +static ssize_t cyapa_interrupt_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct cyapa *cyapa = dev_get_drvdata(dev); + u16 value; + int error; + + if (cyapa->gen < CYAPA_GEN6) + return -EOPNOTSUPP; + + if (kstrtou16(buf, 10, &value)) { + dev_err(dev, "invalid interrupt set parameter\n"); + return -EINVAL; + } + + error = mutex_lock_interruptible(&cyapa->state_sync_lock); + if (error) + return error; + + if (cyapa->operational) + error = cyapa->ops->set_interrupt(cyapa, + value ? true : false); + else + error = -EBUSY; /* Still running in bootloader mode. */ + + mutex_unlock(&cyapa->state_sync_lock); + return error < 0 ? error : count; +} + +static ssize_t cyapa_show_proximity(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct cyapa *cyapa = dev_get_drvdata(dev); + int size; + int error; + + error = mutex_lock_interruptible(&cyapa->state_sync_lock); + if (error) + return error; + + size = scnprintf(buf, PAGE_SIZE, "%d\n", cyapa->proximity ? 1 : 0); + + mutex_unlock(&cyapa->state_sync_lock); + return size; +} + +static ssize_t cyapa_proximity_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct cyapa *cyapa = dev_get_drvdata(dev); + u16 value; + int error; + + if (cyapa->gen < CYAPA_GEN5) + return -EOPNOTSUPP; + + if (kstrtou16(buf, 10, &value)) { + dev_err(dev, "invalid set value of proximity\n"); + return -EINVAL; + } + + error = mutex_lock_interruptible(&cyapa->state_sync_lock); + if (error) + return error; + + if (cyapa->operational) + error = cyapa->ops->set_proximity(cyapa, + value ? true : false); + else + error = -EBUSY; /* Still running in bootloader mode. */ + + mutex_unlock(&cyapa->state_sync_lock); + return error < 0 ? error : count; +} + static DEVICE_ATTR(firmware_version, S_IRUGO, cyapa_show_fm_ver, NULL); static DEVICE_ATTR(product_id, S_IRUGO, cyapa_show_product_id, NULL); static DEVICE_ATTR(update_fw, S_IWUSR, NULL, cyapa_update_fw_store); static DEVICE_ATTR(baseline, S_IRUGO, cyapa_show_baseline, NULL); static DEVICE_ATTR(calibrate, S_IWUSR, NULL, cyapa_calibrate_store); static DEVICE_ATTR(mode, S_IRUGO, cyapa_show_mode, NULL); +static DEVICE_ATTR(interrupt, S_IRUGO | S_IWUSR, + cyapa_show_interrupt, cyapa_interrupt_store); +static DEVICE_ATTR(proximity, S_IRUGO | S_IWUSR, + cyapa_show_proximity, cyapa_proximity_store); static struct attribute *cyapa_sysfs_entries[] = { &dev_attr_firmware_version.attr, @@ -1231,6 +1330,8 @@ static struct attribute *cyapa_sysfs_entries[] = { &dev_attr_baseline.attr, &dev_attr_calibrate.attr, &dev_attr_mode.attr, + &dev_attr_interrupt.attr, + &dev_attr_proximity.attr, NULL, }; diff --git a/drivers/input/mouse/cyapa.h b/drivers/input/mouse/cyapa.h index cc30367..0ce66c5 100644 --- a/drivers/input/mouse/cyapa.h +++ b/drivers/input/mouse/cyapa.h @@ -275,6 +275,7 @@ struct cyapa_dev_ops { int (*set_power_mode)(struct cyapa *, u8, u16, bool); + int (*set_interrupt)(struct cyapa *, bool); int (*set_proximity)(struct cyapa *, bool); }; @@ -365,6 +366,9 @@ struct cyapa { */ struct mutex state_sync_lock; + bool interrupt; + bool proximity; + const struct cyapa_dev_ops *ops; union cyapa_cmd_states cmd_states; diff --git a/drivers/input/mouse/cyapa_gen3.c b/drivers/input/mouse/cyapa_gen3.c index 2d077e5..41c40b5 100644 --- a/drivers/input/mouse/cyapa_gen3.c +++ b/drivers/input/mouse/cyapa_gen3.c @@ -1244,5 +1244,6 @@ const struct cyapa_dev_ops cyapa_gen3_ops = { .sort_empty_output_data = cyapa_gen3_empty_output_data, .set_power_mode = cyapa_gen3_set_power_mode, + .set_interrupt = cyapa_set_not_supported, .set_proximity = cyapa_set_not_supported, }; diff --git a/drivers/input/mouse/cyapa_gen5.c b/drivers/input/mouse/cyapa_gen5.c index 5ab0cd2..c388540 100644 --- a/drivers/input/mouse/cyapa_gen5.c +++ b/drivers/input/mouse/cyapa_gen5.c @@ -1544,6 +1544,7 @@ int cyapa_pip_set_proximity(struct cyapa *cyapa, bool enable) return error < 0 ? error : -EINVAL; } + cyapa->proximity = enable; return 0; } @@ -2835,5 +2836,6 @@ const struct cyapa_dev_ops cyapa_gen5_ops = { .sort_empty_output_data = cyapa_empty_pip_output_data, .set_power_mode = cyapa_gen5_set_power_mode, + .set_interrupt = cyapa_set_not_supported, .set_proximity = cyapa_pip_set_proximity, }; diff --git a/drivers/input/mouse/cyapa_gen6.c b/drivers/input/mouse/cyapa_gen6.c index 9d76715..6e18c5c 100644 --- a/drivers/input/mouse/cyapa_gen6.c +++ b/drivers/input/mouse/cyapa_gen6.c @@ -309,9 +309,22 @@ static int cyapa_gen6_config_dev_irq(struct cyapa *cyapa, u8 cmd_code) ) return error < 0 ? error : -EINVAL; + if (cmd_code == GEN6_ENABLE_DEV_IRQ) + cyapa->interrupt = true; + else if (cmd_code == GEN6_DISABLE_DEV_IRQ) + cyapa->interrupt = false; + return 0; } +static int cyapa_gen6_set_interrupt(struct cyapa *cyapa, bool enable) +{ + if (enable) + return cyapa_gen6_config_dev_irq(cyapa, GEN6_ENABLE_DEV_IRQ); + else + return cyapa_gen6_config_dev_irq(cyapa, GEN6_DISABLE_DEV_IRQ); +} + static int cyapa_gen6_set_proximity(struct cyapa *cyapa, bool enable) { int error; @@ -744,5 +757,6 @@ const struct cyapa_dev_ops cyapa_gen6_ops = { .sort_empty_output_data = cyapa_empty_pip_output_data, .set_power_mode = cyapa_gen6_set_power_mode, + .set_interrupt = cyapa_gen6_set_interrupt, .set_proximity = cyapa_gen6_set_proximity, };