From patchwork Tue Apr 2 06:30:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Breathitt Gray X-Patchwork-Id: 10881067 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B757F1669 for ; Tue, 2 Apr 2019 06:30:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 96A0D286D5 for ; Tue, 2 Apr 2019 06:30:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 89149286EE; Tue, 2 Apr 2019 06:30:47 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6338D286D5 for ; Tue, 2 Apr 2019 06:30:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Qro5A0Q0nPnm+AcY+mipov5xlm+MDzY/ivcoEMMfp+w=; b=P2MJsJx/r78IMU ZHLM3tjw/bkKBPr+JbFnIe8Na24huP+quGSNo9vPjw69nT4FsDvDbamWmQDZJL9gntCiT2uRJC0zl vVnD17mgNswO+NnnShb+5fIh8PxDNjCRpSFF0lrKimv1Vw4PaRmHxrJCF99pnWUR/OwJTgohWkV+J 3VjE8aJSySizW/2D9kC+cHtzEUxa80R0mQYCY+s45vxPSML48A9EixF/ei/ZWbH0q1dK4KHD28mXr inYQMuO/WOtj8IFe1+ixiX374R0tHw57J6xgekdCJJWYZZYG8dOS6yBjgV9yDqfFu101qS8VuZNa9 ZphsfOWhWHkmyFH1MSAQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCwU-000883-CM; Tue, 02 Apr 2019 06:30:42 +0000 Received: from mail-pf1-x442.google.com ([2607:f8b0:4864:20::442]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCwA-0007lm-Rp for linux-arm-kernel@lists.infradead.org; Tue, 02 Apr 2019 06:30:40 +0000 Received: by mail-pf1-x442.google.com with SMTP id b3so5834563pfd.1 for ; Mon, 01 Apr 2019 23:30:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=8JdZnA7sCFwx4YD2hF0Sf9LT7tcz/uSFvWr5rljxoVM=; b=hPMERnP15ZNe7Wj663VRYWR7PjVBGI1s2MOj/QyFiFcxKuX1JIS4utNEI5SfAiAcs7 hpTXncHw3i/l52rONX7EgmVGA8RYcWhsNwiOYos5Xc+2KGqlZvuTJLNrGIfcbHCJstO0 wRNkKA3TzdNkEIPGqA5l9omZq0zMoqoMzc+sfI8bWubzQY/aH+FqVRlsV9K1iuF8jeoU ekyA3s4RmGy0gkqWIiqz/5wLNXWCPXhPx0z01LykQ3R5Qp3jiiy+YdkGfauuadBLYtFt JuJEIrOz20nOc+IJJcRDhntZqzoMrJX9zC6imYlnc4UmlcqjEPetCp1yyXOpaL2FOx/I ps0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=8JdZnA7sCFwx4YD2hF0Sf9LT7tcz/uSFvWr5rljxoVM=; b=EVaL9cii89V7Kxf9ig3BgprfxuuxPnF3Q8yGxhAbCrkSCjpgLdUr33PlDC/AISaI8y mPeqfw/dEs9ycvpzNZ3KRKM2Yxyse0HicF5dytiiQ+yC6kF+veq7iRXBGR6CByok6FN5 sm/o/vkAbeVQuA+TuFO+jvK/moWUmtoTsWhluRg5B9i+3qF8ur16MBmwxt4GJlYE+nHA HcmjAJE0I2fFd3SlNJ/b66m5gh/BnaLO0jZWZoUfazfSEQgl/5P7WmCh5hGicLz4sDz6 QBZXCasYL+axO2fHLrjV9Nqn2g4hj7bMHtQHO/JTizFTcMg3R8ymbPaPc+kMnJLgnKjI YtXg== X-Gm-Message-State: APjAAAWZs93Eh2U9zkYZs5mmxnIc6DrpY+E+dPqWBOOciQ14KEDpXwkg Qw90Vg10BY2WwkZZ5jsOmy8= X-Google-Smtp-Source: APXvYqwisUoeZGDMXDYuoBDQfJ7ZFZC4l05G6tg6mrEsmwuYe3hG9lVvtTs3/TbEH/bp1BeIqjI7eA== X-Received: by 2002:aa7:8212:: with SMTP id k18mr11475470pfi.50.1554186621447; Mon, 01 Apr 2019 23:30:21 -0700 (PDT) Received: from localhost.localdomain ([2001:268:c0a5:4ce0:c70:4af9:86e2:2]) by smtp.gmail.com with ESMTPSA id a17sm19327289pfj.123.2019.04.01.23.30.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Apr 2019 23:30:20 -0700 (PDT) From: William Breathitt Gray To: gregkh@linuxfoundation.org Subject: [PATCH v10 01/18] counter: Introduce the Generic Counter interface Date: Tue, 2 Apr 2019 15:30:36 +0900 Message-Id: X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190401_233022_979576_5756B44A X-CRM114-Status: GOOD ( 20.66 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, benjamin.gaignard@st.com, linux-pwm@vger.kernel.org, linux-iio@vger.kernel.org, patrick.havelange@essensium.com, thierry.reding@gmail.com, pmeerw@pmeerw.net, lars@metafoo.de, daniel.lezcano@linaro.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, david@lechnology.com, William Breathitt Gray , robh+dt@kernel.org, Jonathan Cameron , tglx@linutronix.de, fabrice.gasnier@st.com, esben@haabendal.dk, shawnguo@kernel.org, linux-kernel@vger.kernel.org, leoyang.li@nxp.com, knaack.h@gmx.de, akpm@linux-foundation.org, linuxppc-dev@lists.ozlabs.org, jic23@kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP This patch introduces the Generic Counter interface for supporting counter devices. In the context of the Generic Counter interface, a counter is defined as a device that reports one or more "counts" based on the state changes of one or more "signals" as evaluated by a defined "count function." Driver callbacks should be provided to communicate with the device: to read and write various Signals and Counts, and to set and get the "action mode" and "count function" for various Synapses and Counts respectively. To support a counter device, a driver must first allocate the available Counter Signals via counter_signal structures. These Signals should be stored as an array and set to the signals array member of an allocated counter_device structure before the Counter is registered to the system. Counter Counts may be allocated via counter_count structures, and respective Counter Signal associations (Synapses) made via counter_synapse structures. Associated counter_synapse structures are stored as an array and set to the the synapses array member of the respective counter_count structure. These counter_count structures are set to the counts array member of an allocated counter_device structure before the Counter is registered to the system. A counter device is registered to the system by passing the respective initialized counter_device structure to the counter_register function; similarly, the counter_unregister function unregisters the respective Counter. The devm_counter_register and devm_counter_unregister functions serve as device memory-managed versions of the counter_register and counter_unregister functions respectively. Reviewed-by: Jonathan Cameron Signed-off-by: William Breathitt Gray --- MAINTAINERS | 8 + drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/counter/Kconfig | 10 + drivers/counter/Makefile | 5 + drivers/counter/counter.c | 1567 ++++++++++++++++++++++++++++++++++ include/linux/counter.h | 510 +++++++++++ include/linux/counter_enum.h | 45 + 8 files changed, 2148 insertions(+) create mode 100644 drivers/counter/Kconfig create mode 100644 drivers/counter/Makefile create mode 100644 drivers/counter/counter.c create mode 100644 include/linux/counter.h create mode 100644 include/linux/counter_enum.h diff --git a/MAINTAINERS b/MAINTAINERS index ff2c2f2e6da3..ef497d470501 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3966,6 +3966,14 @@ W: http://www.fi.muni.cz/~kas/cosa/ S: Maintained F: drivers/net/wan/cosa* +COUNTER SUBSYSTEM +M: William Breathitt Gray +L: linux-iio@vger.kernel.org +S: Maintained +F: drivers/counter/ +F: include/linux/counter.h +F: include/linux/counter_enum.h + CPMAC ETHERNET DRIVER M: Florian Fainelli L: netdev@vger.kernel.org diff --git a/drivers/Kconfig b/drivers/Kconfig index 4f9f99057ff8..e1fd5d783e39 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -228,4 +228,6 @@ source "drivers/siox/Kconfig" source "drivers/slimbus/Kconfig" +source "drivers/counter/Kconfig" + endmenu diff --git a/drivers/Makefile b/drivers/Makefile index e1ce029d28fd..7ea509ad6d43 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -186,3 +186,4 @@ obj-$(CONFIG_MULTIPLEXER) += mux/ obj-$(CONFIG_UNISYS_VISORBUS) += visorbus/ obj-$(CONFIG_SIOX) += siox/ obj-$(CONFIG_GNSS) += gnss/ +obj-$(CONFIG_COUNTER) += counter/ diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig new file mode 100644 index 000000000000..a74998400282 --- /dev/null +++ b/drivers/counter/Kconfig @@ -0,0 +1,10 @@ +# +# Counter devices +# + +menuconfig COUNTER + tristate "Counter support" + help + This enables counter device support through the Generic Counter + interface. You only need to enable this, if you also want to enable + one or more of the counter device drivers below. diff --git a/drivers/counter/Makefile b/drivers/counter/Makefile new file mode 100644 index 000000000000..b1464604bdbe --- /dev/null +++ b/drivers/counter/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for Counter devices +# + +obj-$(CONFIG_COUNTER) += counter.o diff --git a/drivers/counter/counter.c b/drivers/counter/counter.c new file mode 100644 index 000000000000..106bc7180cd8 --- /dev/null +++ b/drivers/counter/counter.c @@ -0,0 +1,1567 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Generic Counter interface + * Copyright (C) 2018 William Breathitt Gray + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const char *const counter_count_direction_str[2] = { + [COUNTER_COUNT_DIRECTION_FORWARD] = "forward", + [COUNTER_COUNT_DIRECTION_BACKWARD] = "backward" +}; +EXPORT_SYMBOL_GPL(counter_count_direction_str); + +const char *const counter_count_mode_str[4] = { + [COUNTER_COUNT_MODE_NORMAL] = "normal", + [COUNTER_COUNT_MODE_RANGE_LIMIT] = "range limit", + [COUNTER_COUNT_MODE_NON_RECYCLE] = "non-recycle", + [COUNTER_COUNT_MODE_MODULO_N] = "modulo-n" +}; +EXPORT_SYMBOL_GPL(counter_count_mode_str); + +ssize_t counter_signal_enum_read(struct counter_device *counter, + struct counter_signal *signal, void *priv, + char *buf) +{ + const struct counter_signal_enum_ext *const e = priv; + int err; + size_t index; + + if (!e->get) + return -EINVAL; + + err = e->get(counter, signal, &index); + if (err) + return err; + + if (index >= e->num_items) + return -EINVAL; + + return sprintf(buf, "%s\n", e->items[index]); +} +EXPORT_SYMBOL_GPL(counter_signal_enum_read); + +ssize_t counter_signal_enum_write(struct counter_device *counter, + struct counter_signal *signal, void *priv, + const char *buf, size_t len) +{ + const struct counter_signal_enum_ext *const e = priv; + ssize_t index; + int err; + + if (!e->set) + return -EINVAL; + + index = __sysfs_match_string(e->items, e->num_items, buf); + if (index < 0) + return index; + + err = e->set(counter, signal, index); + if (err) + return err; + + return len; +} +EXPORT_SYMBOL_GPL(counter_signal_enum_write); + +ssize_t counter_signal_enum_available_read(struct counter_device *counter, + struct counter_signal *signal, + void *priv, char *buf) +{ + const struct counter_signal_enum_ext *const e = priv; + size_t i; + size_t len = 0; + + if (!e->num_items) + return 0; + + for (i = 0; i < e->num_items; i++) + len += sprintf(buf + len, "%s\n", e->items[i]); + + return len; +} +EXPORT_SYMBOL_GPL(counter_signal_enum_available_read); + +ssize_t counter_count_enum_read(struct counter_device *counter, + struct counter_count *count, void *priv, + char *buf) +{ + const struct counter_count_enum_ext *const e = priv; + int err; + size_t index; + + if (!e->get) + return -EINVAL; + + err = e->get(counter, count, &index); + if (err) + return err; + + if (index >= e->num_items) + return -EINVAL; + + return sprintf(buf, "%s\n", e->items[index]); +} +EXPORT_SYMBOL_GPL(counter_count_enum_read); + +ssize_t counter_count_enum_write(struct counter_device *counter, + struct counter_count *count, void *priv, + const char *buf, size_t len) +{ + const struct counter_count_enum_ext *const e = priv; + ssize_t index; + int err; + + if (!e->set) + return -EINVAL; + + index = __sysfs_match_string(e->items, e->num_items, buf); + if (index < 0) + return index; + + err = e->set(counter, count, index); + if (err) + return err; + + return len; +} +EXPORT_SYMBOL_GPL(counter_count_enum_write); + +ssize_t counter_count_enum_available_read(struct counter_device *counter, + struct counter_count *count, + void *priv, char *buf) +{ + const struct counter_count_enum_ext *const e = priv; + size_t i; + size_t len = 0; + + if (!e->num_items) + return 0; + + for (i = 0; i < e->num_items; i++) + len += sprintf(buf + len, "%s\n", e->items[i]); + + return len; +} +EXPORT_SYMBOL_GPL(counter_count_enum_available_read); + +ssize_t counter_device_enum_read(struct counter_device *counter, void *priv, + char *buf) +{ + const struct counter_device_enum_ext *const e = priv; + int err; + size_t index; + + if (!e->get) + return -EINVAL; + + err = e->get(counter, &index); + if (err) + return err; + + if (index >= e->num_items) + return -EINVAL; + + return sprintf(buf, "%s\n", e->items[index]); +} +EXPORT_SYMBOL_GPL(counter_device_enum_read); + +ssize_t counter_device_enum_write(struct counter_device *counter, void *priv, + const char *buf, size_t len) +{ + const struct counter_device_enum_ext *const e = priv; + ssize_t index; + int err; + + if (!e->set) + return -EINVAL; + + index = __sysfs_match_string(e->items, e->num_items, buf); + if (index < 0) + return index; + + err = e->set(counter, index); + if (err) + return err; + + return len; +} +EXPORT_SYMBOL_GPL(counter_device_enum_write); + +ssize_t counter_device_enum_available_read(struct counter_device *counter, + void *priv, char *buf) +{ + const struct counter_device_enum_ext *const e = priv; + size_t i; + size_t len = 0; + + if (!e->num_items) + return 0; + + for (i = 0; i < e->num_items; i++) + len += sprintf(buf + len, "%s\n", e->items[i]); + + return len; +} +EXPORT_SYMBOL_GPL(counter_device_enum_available_read); + +static const char *const counter_signal_level_str[] = { + [COUNTER_SIGNAL_LEVEL_LOW] = "low", + [COUNTER_SIGNAL_LEVEL_HIGH] = "high" +}; + +/** + * counter_signal_read_value_set - set counter_signal_read_value data + * @val: counter_signal_read_value structure to set + * @type: property Signal data represents + * @data: Signal data + * + * This function sets an opaque counter_signal_read_value structure with the + * provided Signal data. + */ +void counter_signal_read_value_set(struct counter_signal_read_value *const val, + const enum counter_signal_value_type type, + void *const data) +{ + if (type == COUNTER_SIGNAL_LEVEL) + val->len = sprintf(val->buf, "%s\n", + counter_signal_level_str[*(enum counter_signal_level *)data]); + else + val->len = 0; +} +EXPORT_SYMBOL_GPL(counter_signal_read_value_set); + +/** + * counter_count_read_value_set - set counter_count_read_value data + * @val: counter_count_read_value structure to set + * @type: property Count data represents + * @data: Count data + * + * This function sets an opaque counter_count_read_value structure with the + * provided Count data. + */ +void counter_count_read_value_set(struct counter_count_read_value *const val, + const enum counter_count_value_type type, + void *const data) +{ + switch (type) { + case COUNTER_COUNT_POSITION: + val->len = sprintf(val->buf, "%lu\n", *(unsigned long *)data); + break; + default: + val->len = 0; + } +} +EXPORT_SYMBOL_GPL(counter_count_read_value_set); + +/** + * counter_count_write_value_get - get counter_count_write_value data + * @data: Count data + * @type: property Count data represents + * @val: counter_count_write_value structure containing data + * + * This function extracts Count data from the provided opaque + * counter_count_write_value structure and stores it at the address provided by + * @data. + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int counter_count_write_value_get(void *const data, + const enum counter_count_value_type type, + const struct counter_count_write_value *const val) +{ + int err; + + switch (type) { + case COUNTER_COUNT_POSITION: + err = kstrtoul(val->buf, 0, data); + if (err) + return err; + break; + } + + return 0; +} +EXPORT_SYMBOL_GPL(counter_count_write_value_get); + +struct counter_attr_parm { + struct counter_device_attr_group *group; + const char *prefix; + const char *name; + ssize_t (*show)(struct device *dev, struct device_attribute *attr, + char *buf); + ssize_t (*store)(struct device *dev, struct device_attribute *attr, + const char *buf, size_t len); + void *component; +}; + +struct counter_device_attr { + struct device_attribute dev_attr; + struct list_head l; + void *component; +}; + +static int counter_attribute_create(const struct counter_attr_parm *const parm) +{ + struct counter_device_attr *counter_attr; + struct device_attribute *dev_attr; + int err; + struct list_head *const attr_list = &parm->group->attr_list; + + /* Allocate a Counter device attribute */ + counter_attr = kzalloc(sizeof(*counter_attr), GFP_KERNEL); + if (!counter_attr) + return -ENOMEM; + dev_attr = &counter_attr->dev_attr; + + sysfs_attr_init(&dev_attr->attr); + + /* Configure device attribute */ + dev_attr->attr.name = kasprintf(GFP_KERNEL, "%s%s", parm->prefix, + parm->name); + if (!dev_attr->attr.name) { + err = -ENOMEM; + goto err_free_counter_attr; + } + if (parm->show) { + dev_attr->attr.mode |= 0444; + dev_attr->show = parm->show; + } + if (parm->store) { + dev_attr->attr.mode |= 0200; + dev_attr->store = parm->store; + } + + /* Store associated Counter component with attribute */ + counter_attr->component = parm->component; + + /* Keep track of the attribute for later cleanup */ + list_add(&counter_attr->l, attr_list); + parm->group->num_attr++; + + return 0; + +err_free_counter_attr: + kfree(counter_attr); + return err; +} + +#define to_counter_attr(_dev_attr) \ + container_of(_dev_attr, struct counter_device_attr, dev_attr) + +struct counter_signal_unit { + struct counter_signal *signal; +}; + +static ssize_t counter_signal_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct counter_device *const counter = dev_get_drvdata(dev); + const struct counter_device_attr *const devattr = to_counter_attr(attr); + const struct counter_signal_unit *const component = devattr->component; + struct counter_signal *const signal = component->signal; + int err; + struct counter_signal_read_value val = { .buf = buf }; + + err = counter->ops->signal_read(counter, signal, &val); + if (err) + return err; + + return val.len; +} + +struct counter_name_unit { + const char *name; +}; + +static ssize_t counter_device_attr_name_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + const struct counter_name_unit *const comp = to_counter_attr(attr)->component; + + return sprintf(buf, "%s\n", comp->name); +} + +static int counter_name_attribute_create( + struct counter_device_attr_group *const group, + const char *const name) +{ + struct counter_name_unit *name_comp; + struct counter_attr_parm parm; + int err; + + /* Skip if no name */ + if (!name) + return 0; + + /* Allocate name attribute component */ + name_comp = kmalloc(sizeof(*name_comp), GFP_KERNEL); + if (!name_comp) + return -ENOMEM; + name_comp->name = name; + + /* Allocate Signal name attribute */ + parm.group = group; + parm.prefix = ""; + parm.name = "name"; + parm.show = counter_device_attr_name_show; + parm.store = NULL; + parm.component = name_comp; + err = counter_attribute_create(&parm); + if (err) + goto err_free_name_comp; + + return 0; + +err_free_name_comp: + kfree(name_comp); + return err; +} + +struct counter_signal_ext_unit { + struct counter_signal *signal; + const struct counter_signal_ext *ext; +}; + +static ssize_t counter_signal_ext_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + const struct counter_device_attr *const devattr = to_counter_attr(attr); + const struct counter_signal_ext_unit *const comp = devattr->component; + const struct counter_signal_ext *const ext = comp->ext; + + return ext->read(dev_get_drvdata(dev), comp->signal, ext->priv, buf); +} + +static ssize_t counter_signal_ext_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + const struct counter_device_attr *const devattr = to_counter_attr(attr); + const struct counter_signal_ext_unit *const comp = devattr->component; + const struct counter_signal_ext *const ext = comp->ext; + + return ext->write(dev_get_drvdata(dev), comp->signal, ext->priv, buf, + len); +} + +static void counter_device_attr_list_free(struct list_head *attr_list) +{ + struct counter_device_attr *p, *n; + + list_for_each_entry_safe(p, n, attr_list, l) { + /* free attribute name and associated component memory */ + kfree(p->dev_attr.attr.name); + kfree(p->component); + list_del(&p->l); + kfree(p); + } +} + +static int counter_signal_ext_register( + struct counter_device_attr_group *const group, + struct counter_signal *const signal) +{ + const size_t num_ext = signal->num_ext; + size_t i; + const struct counter_signal_ext *ext; + struct counter_signal_ext_unit *signal_ext_comp; + struct counter_attr_parm parm; + int err; + + /* Create an attribute for each extension */ + for (i = 0 ; i < num_ext; i++) { + ext = signal->ext + i; + + /* Allocate signal_ext attribute component */ + signal_ext_comp = kmalloc(sizeof(*signal_ext_comp), GFP_KERNEL); + if (!signal_ext_comp) { + err = -ENOMEM; + goto err_free_attr_list; + } + signal_ext_comp->signal = signal; + signal_ext_comp->ext = ext; + + /* Allocate a Counter device attribute */ + parm.group = group; + parm.prefix = ""; + parm.name = ext->name; + parm.show = (ext->read) ? counter_signal_ext_show : NULL; + parm.store = (ext->write) ? counter_signal_ext_store : NULL; + parm.component = signal_ext_comp; + err = counter_attribute_create(&parm); + if (err) { + kfree(signal_ext_comp); + goto err_free_attr_list; + } + } + + return 0; + +err_free_attr_list: + counter_device_attr_list_free(&group->attr_list); + return err; +} + +static int counter_signal_attributes_create( + struct counter_device_attr_group *const group, + const struct counter_device *const counter, + struct counter_signal *const signal) +{ + struct counter_signal_unit *signal_comp; + struct counter_attr_parm parm; + int err; + + /* Allocate Signal attribute component */ + signal_comp = kmalloc(sizeof(*signal_comp), GFP_KERNEL); + if (!signal_comp) + return -ENOMEM; + signal_comp->signal = signal; + + /* Create main Signal attribute */ + parm.group = group; + parm.prefix = ""; + parm.name = "signal"; + parm.show = (counter->ops->signal_read) ? counter_signal_show : NULL; + parm.store = NULL; + parm.component = signal_comp; + err = counter_attribute_create(&parm); + if (err) { + kfree(signal_comp); + return err; + } + + /* Create Signal name attribute */ + err = counter_name_attribute_create(group, signal->name); + if (err) + goto err_free_attr_list; + + /* Register Signal extension attributes */ + err = counter_signal_ext_register(group, signal); + if (err) + goto err_free_attr_list; + + return 0; + +err_free_attr_list: + counter_device_attr_list_free(&group->attr_list); + return err; +} + +static int counter_signals_register( + struct counter_device_attr_group *const groups_list, + const struct counter_device *const counter) +{ + const size_t num_signals = counter->num_signals; + size_t i; + struct counter_signal *signal; + const char *name; + int err; + + /* Register each Signal */ + for (i = 0; i < num_signals; i++) { + signal = counter->signals + i; + + /* Generate Signal attribute directory name */ + name = kasprintf(GFP_KERNEL, "signal%d", signal->id); + if (!name) { + err = -ENOMEM; + goto err_free_attr_groups; + } + groups_list[i].attr_group.name = name; + + /* Create all attributes associated with Signal */ + err = counter_signal_attributes_create(groups_list + i, counter, + signal); + if (err) + goto err_free_attr_groups; + } + + return 0; + +err_free_attr_groups: + do { + kfree(groups_list[i].attr_group.name); + counter_device_attr_list_free(&groups_list[i].attr_list); + } while (i--); + return err; +} + +static const char *const counter_synapse_action_str[] = { + [COUNTER_SYNAPSE_ACTION_NONE] = "none", + [COUNTER_SYNAPSE_ACTION_RISING_EDGE] = "rising edge", + [COUNTER_SYNAPSE_ACTION_FALLING_EDGE] = "falling edge", + [COUNTER_SYNAPSE_ACTION_BOTH_EDGES] = "both edges" +}; + +struct counter_action_unit { + struct counter_synapse *synapse; + struct counter_count *count; +}; + +static ssize_t counter_action_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + const struct counter_device_attr *const devattr = to_counter_attr(attr); + int err; + struct counter_device *const counter = dev_get_drvdata(dev); + const struct counter_action_unit *const component = devattr->component; + struct counter_count *const count = component->count; + struct counter_synapse *const synapse = component->synapse; + size_t action_index; + enum counter_synapse_action action; + + err = counter->ops->action_get(counter, count, synapse, &action_index); + if (err) + return err; + + synapse->action = action_index; + + action = synapse->actions_list[action_index]; + return sprintf(buf, "%s\n", counter_synapse_action_str[action]); +} + +static ssize_t counter_action_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + const struct counter_device_attr *const devattr = to_counter_attr(attr); + const struct counter_action_unit *const component = devattr->component; + struct counter_synapse *const synapse = component->synapse; + size_t action_index; + const size_t num_actions = synapse->num_actions; + enum counter_synapse_action action; + int err; + struct counter_device *const counter = dev_get_drvdata(dev); + struct counter_count *const count = component->count; + + /* Find requested action mode */ + for (action_index = 0; action_index < num_actions; action_index++) { + action = synapse->actions_list[action_index]; + if (sysfs_streq(buf, counter_synapse_action_str[action])) + break; + } + /* If requested action mode not found */ + if (action_index >= num_actions) + return -EINVAL; + + err = counter->ops->action_set(counter, count, synapse, action_index); + if (err) + return err; + + synapse->action = action_index; + + return len; +} + +struct counter_action_avail_unit { + const enum counter_synapse_action *actions_list; + size_t num_actions; +}; + +static ssize_t counter_synapse_action_available_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + const struct counter_device_attr *const devattr = to_counter_attr(attr); + const struct counter_action_avail_unit *const component = devattr->component; + size_t i; + enum counter_synapse_action action; + ssize_t len = 0; + + for (i = 0; i < component->num_actions; i++) { + action = component->actions_list[i]; + len += sprintf(buf + len, "%s\n", + counter_synapse_action_str[action]); + } + + return len; +} + +static int counter_synapses_register( + struct counter_device_attr_group *const group, + const struct counter_device *const counter, + struct counter_count *const count, const char *const count_attr_name) +{ + size_t i; + struct counter_synapse *synapse; + const char *prefix; + struct counter_action_unit *action_comp; + struct counter_attr_parm parm; + int err; + struct counter_action_avail_unit *avail_comp; + + /* Register each Synapse */ + for (i = 0; i < count->num_synapses; i++) { + synapse = count->synapses + i; + + /* Generate attribute prefix */ + prefix = kasprintf(GFP_KERNEL, "signal%d_", + synapse->signal->id); + if (!prefix) { + err = -ENOMEM; + goto err_free_attr_list; + } + + /* Allocate action attribute component */ + action_comp = kmalloc(sizeof(*action_comp), GFP_KERNEL); + if (!action_comp) { + err = -ENOMEM; + goto err_free_prefix; + } + action_comp->synapse = synapse; + action_comp->count = count; + + /* Create action attribute */ + parm.group = group; + parm.prefix = prefix; + parm.name = "action"; + parm.show = (counter->ops->action_get) ? counter_action_show : NULL; + parm.store = (counter->ops->action_set) ? counter_action_store : NULL; + parm.component = action_comp; + err = counter_attribute_create(&parm); + if (err) { + kfree(action_comp); + goto err_free_prefix; + } + + /* Allocate action available attribute component */ + avail_comp = kmalloc(sizeof(*avail_comp), GFP_KERNEL); + if (!avail_comp) { + err = -ENOMEM; + goto err_free_prefix; + } + avail_comp->actions_list = synapse->actions_list; + avail_comp->num_actions = synapse->num_actions; + + /* Create action_available attribute */ + parm.group = group; + parm.prefix = prefix; + parm.name = "action_available"; + parm.show = counter_synapse_action_available_show; + parm.store = NULL; + parm.component = avail_comp; + err = counter_attribute_create(&parm); + if (err) { + kfree(avail_comp); + goto err_free_prefix; + } + + kfree(prefix); + } + + return 0; + +err_free_prefix: + kfree(prefix); +err_free_attr_list: + counter_device_attr_list_free(&group->attr_list); + return err; +} + +struct counter_count_unit { + struct counter_count *count; +}; + +static ssize_t counter_count_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct counter_device *const counter = dev_get_drvdata(dev); + const struct counter_device_attr *const devattr = to_counter_attr(attr); + const struct counter_count_unit *const component = devattr->component; + struct counter_count *const count = component->count; + int err; + struct counter_count_read_value val = { .buf = buf }; + + err = counter->ops->count_read(counter, count, &val); + if (err) + return err; + + return val.len; +} + +static ssize_t counter_count_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct counter_device *const counter = dev_get_drvdata(dev); + const struct counter_device_attr *const devattr = to_counter_attr(attr); + const struct counter_count_unit *const component = devattr->component; + struct counter_count *const count = component->count; + int err; + struct counter_count_write_value val = { .buf = buf }; + + err = counter->ops->count_write(counter, count, &val); + if (err) + return err; + + return len; +} + +static const char *const counter_count_function_str[] = { + [COUNTER_COUNT_FUNCTION_INCREASE] = "increase", + [COUNTER_COUNT_FUNCTION_DECREASE] = "decrease", + [COUNTER_COUNT_FUNCTION_PULSE_DIRECTION] = "pulse-direction", + [COUNTER_COUNT_FUNCTION_QUADRATURE_X1_A] = "quadrature x1 a", + [COUNTER_COUNT_FUNCTION_QUADRATURE_X1_B] = "quadrature x1 b", + [COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A] = "quadrature x2 a", + [COUNTER_COUNT_FUNCTION_QUADRATURE_X2_B] = "quadrature x2 b", + [COUNTER_COUNT_FUNCTION_QUADRATURE_X4] = "quadrature x4" +}; + +static ssize_t counter_function_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int err; + struct counter_device *const counter = dev_get_drvdata(dev); + const struct counter_device_attr *const devattr = to_counter_attr(attr); + const struct counter_count_unit *const component = devattr->component; + struct counter_count *const count = component->count; + size_t func_index; + enum counter_count_function function; + + err = counter->ops->function_get(counter, count, &func_index); + if (err) + return err; + + count->function = func_index; + + function = count->functions_list[func_index]; + return sprintf(buf, "%s\n", counter_count_function_str[function]); +} + +static ssize_t counter_function_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + const struct counter_device_attr *const devattr = to_counter_attr(attr); + const struct counter_count_unit *const component = devattr->component; + struct counter_count *const count = component->count; + const size_t num_functions = count->num_functions; + size_t func_index; + enum counter_count_function function; + int err; + struct counter_device *const counter = dev_get_drvdata(dev); + + /* Find requested Count function mode */ + for (func_index = 0; func_index < num_functions; func_index++) { + function = count->functions_list[func_index]; + if (sysfs_streq(buf, counter_count_function_str[function])) + break; + } + /* Return error if requested Count function mode not found */ + if (func_index >= num_functions) + return -EINVAL; + + err = counter->ops->function_set(counter, count, func_index); + if (err) + return err; + + count->function = func_index; + + return len; +} + +struct counter_count_ext_unit { + struct counter_count *count; + const struct counter_count_ext *ext; +}; + +static ssize_t counter_count_ext_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + const struct counter_device_attr *const devattr = to_counter_attr(attr); + const struct counter_count_ext_unit *const comp = devattr->component; + const struct counter_count_ext *const ext = comp->ext; + + return ext->read(dev_get_drvdata(dev), comp->count, ext->priv, buf); +} + +static ssize_t counter_count_ext_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + const struct counter_device_attr *const devattr = to_counter_attr(attr); + const struct counter_count_ext_unit *const comp = devattr->component; + const struct counter_count_ext *const ext = comp->ext; + + return ext->write(dev_get_drvdata(dev), comp->count, ext->priv, buf, + len); +} + +static int counter_count_ext_register( + struct counter_device_attr_group *const group, + struct counter_count *const count) +{ + size_t i; + const struct counter_count_ext *ext; + struct counter_count_ext_unit *count_ext_comp; + struct counter_attr_parm parm; + int err; + + /* Create an attribute for each extension */ + for (i = 0 ; i < count->num_ext; i++) { + ext = count->ext + i; + + /* Allocate count_ext attribute component */ + count_ext_comp = kmalloc(sizeof(*count_ext_comp), GFP_KERNEL); + if (!count_ext_comp) { + err = -ENOMEM; + goto err_free_attr_list; + } + count_ext_comp->count = count; + count_ext_comp->ext = ext; + + /* Allocate count_ext attribute */ + parm.group = group; + parm.prefix = ""; + parm.name = ext->name; + parm.show = (ext->read) ? counter_count_ext_show : NULL; + parm.store = (ext->write) ? counter_count_ext_store : NULL; + parm.component = count_ext_comp; + err = counter_attribute_create(&parm); + if (err) { + kfree(count_ext_comp); + goto err_free_attr_list; + } + } + + return 0; + +err_free_attr_list: + counter_device_attr_list_free(&group->attr_list); + return err; +} + +struct counter_func_avail_unit { + const enum counter_count_function *functions_list; + size_t num_functions; +}; + +static ssize_t counter_count_function_available_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + const struct counter_device_attr *const devattr = to_counter_attr(attr); + const struct counter_func_avail_unit *const component = devattr->component; + const enum counter_count_function *const func_list = component->functions_list; + const size_t num_functions = component->num_functions; + size_t i; + enum counter_count_function function; + ssize_t len = 0; + + for (i = 0; i < num_functions; i++) { + function = func_list[i]; + len += sprintf(buf + len, "%s\n", + counter_count_function_str[function]); + } + + return len; +} + +static int counter_count_attributes_create( + struct counter_device_attr_group *const group, + const struct counter_device *const counter, + struct counter_count *const count) +{ + struct counter_count_unit *count_comp; + struct counter_attr_parm parm; + int err; + struct counter_count_unit *func_comp; + struct counter_func_avail_unit *avail_comp; + + /* Allocate count attribute component */ + count_comp = kmalloc(sizeof(*count_comp), GFP_KERNEL); + if (!count_comp) + return -ENOMEM; + count_comp->count = count; + + /* Create main Count attribute */ + parm.group = group; + parm.prefix = ""; + parm.name = "count"; + parm.show = (counter->ops->count_read) ? counter_count_show : NULL; + parm.store = (counter->ops->count_write) ? counter_count_store : NULL; + parm.component = count_comp; + err = counter_attribute_create(&parm); + if (err) { + kfree(count_comp); + return err; + } + + /* Allocate function attribute component */ + func_comp = kmalloc(sizeof(*func_comp), GFP_KERNEL); + if (!func_comp) { + err = -ENOMEM; + goto err_free_attr_list; + } + func_comp->count = count; + + /* Create Count function attribute */ + parm.group = group; + parm.prefix = ""; + parm.name = "function"; + parm.show = (counter->ops->function_get) ? counter_function_show : NULL; + parm.store = (counter->ops->function_set) ? counter_function_store : NULL; + parm.component = func_comp; + err = counter_attribute_create(&parm); + if (err) { + kfree(func_comp); + goto err_free_attr_list; + } + + /* Allocate function available attribute component */ + avail_comp = kmalloc(sizeof(*avail_comp), GFP_KERNEL); + if (!avail_comp) { + err = -ENOMEM; + goto err_free_attr_list; + } + avail_comp->functions_list = count->functions_list; + avail_comp->num_functions = count->num_functions; + + /* Create Count function_available attribute */ + parm.group = group; + parm.prefix = ""; + parm.name = "function_available"; + parm.show = counter_count_function_available_show; + parm.store = NULL; + parm.component = avail_comp; + err = counter_attribute_create(&parm); + if (err) { + kfree(avail_comp); + goto err_free_attr_list; + } + + /* Create Count name attribute */ + err = counter_name_attribute_create(group, count->name); + if (err) + goto err_free_attr_list; + + /* Register Count extension attributes */ + err = counter_count_ext_register(group, count); + if (err) + goto err_free_attr_list; + + return 0; + +err_free_attr_list: + counter_device_attr_list_free(&group->attr_list); + return err; +} + +static int counter_counts_register( + struct counter_device_attr_group *const groups_list, + const struct counter_device *const counter) +{ + size_t i; + struct counter_count *count; + const char *name; + int err; + + /* Register each Count */ + for (i = 0; i < counter->num_counts; i++) { + count = counter->counts + i; + + /* Generate Count attribute directory name */ + name = kasprintf(GFP_KERNEL, "count%d", count->id); + if (!name) { + err = -ENOMEM; + goto err_free_attr_groups; + } + groups_list[i].attr_group.name = name; + + /* Register the Synapses associated with each Count */ + err = counter_synapses_register(groups_list + i, counter, count, + name); + if (err) + goto err_free_attr_groups; + + /* Create all attributes associated with Count */ + err = counter_count_attributes_create(groups_list + i, counter, + count); + if (err) + goto err_free_attr_groups; + } + + return 0; + +err_free_attr_groups: + do { + kfree(groups_list[i].attr_group.name); + counter_device_attr_list_free(&groups_list[i].attr_list); + } while (i--); + return err; +} + +struct counter_size_unit { + size_t size; +}; + +static ssize_t counter_device_attr_size_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + const struct counter_size_unit *const comp = to_counter_attr(attr)->component; + + return sprintf(buf, "%zu\n", comp->size); +} + +static int counter_size_attribute_create( + struct counter_device_attr_group *const group, + const size_t size, const char *const name) +{ + struct counter_size_unit *size_comp; + struct counter_attr_parm parm; + int err; + + /* Allocate size attribute component */ + size_comp = kmalloc(sizeof(*size_comp), GFP_KERNEL); + if (!size_comp) + return -ENOMEM; + size_comp->size = size; + + parm.group = group; + parm.prefix = ""; + parm.name = name; + parm.show = counter_device_attr_size_show; + parm.store = NULL; + parm.component = size_comp; + err = counter_attribute_create(&parm); + if (err) + goto err_free_size_comp; + + return 0; + +err_free_size_comp: + kfree(size_comp); + return err; +} + +struct counter_ext_unit { + const struct counter_device_ext *ext; +}; + +static ssize_t counter_device_ext_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + const struct counter_device_attr *const devattr = to_counter_attr(attr); + const struct counter_ext_unit *const component = devattr->component; + const struct counter_device_ext *const ext = component->ext; + + return ext->read(dev_get_drvdata(dev), ext->priv, buf); +} + +static ssize_t counter_device_ext_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + const struct counter_device_attr *const devattr = to_counter_attr(attr); + const struct counter_ext_unit *const component = devattr->component; + const struct counter_device_ext *const ext = component->ext; + + return ext->write(dev_get_drvdata(dev), ext->priv, buf, len); +} + +static int counter_device_ext_register( + struct counter_device_attr_group *const group, + struct counter_device *const counter) +{ + size_t i; + struct counter_ext_unit *ext_comp; + struct counter_attr_parm parm; + int err; + + /* Create an attribute for each extension */ + for (i = 0 ; i < counter->num_ext; i++) { + /* Allocate extension attribute component */ + ext_comp = kmalloc(sizeof(*ext_comp), GFP_KERNEL); + if (!ext_comp) { + err = -ENOMEM; + goto err_free_attr_list; + } + + ext_comp->ext = counter->ext + i; + + /* Allocate extension attribute */ + parm.group = group; + parm.prefix = ""; + parm.name = counter->ext[i].name; + parm.show = (counter->ext[i].read) ? counter_device_ext_show : NULL; + parm.store = (counter->ext[i].write) ? counter_device_ext_store : NULL; + parm.component = ext_comp; + err = counter_attribute_create(&parm); + if (err) { + kfree(ext_comp); + goto err_free_attr_list; + } + } + + return 0; + +err_free_attr_list: + counter_device_attr_list_free(&group->attr_list); + return err; +} + +static int counter_global_attr_register( + struct counter_device_attr_group *const group, + struct counter_device *const counter) +{ + int err; + + /* Create name attribute */ + err = counter_name_attribute_create(group, counter->name); + if (err) + return err; + + /* Create num_counts attribute */ + err = counter_size_attribute_create(group, counter->num_counts, + "num_counts"); + if (err) + goto err_free_attr_list; + + /* Create num_signals attribute */ + err = counter_size_attribute_create(group, counter->num_signals, + "num_signals"); + if (err) + goto err_free_attr_list; + + /* Register Counter device extension attributes */ + err = counter_device_ext_register(group, counter); + if (err) + goto err_free_attr_list; + + return 0; + +err_free_attr_list: + counter_device_attr_list_free(&group->attr_list); + return err; +} + +static void counter_device_groups_list_free( + struct counter_device_attr_group *const groups_list, + const size_t num_groups) +{ + struct counter_device_attr_group *group; + size_t i; + + /* loop through all attribute groups (signals, counts, global, etc.) */ + for (i = 0; i < num_groups; i++) { + group = groups_list + i; + + /* free all attribute group and associated attributes memory */ + kfree(group->attr_group.name); + kfree(group->attr_group.attrs); + counter_device_attr_list_free(&group->attr_list); + } + + kfree(groups_list); +} + +static int counter_device_groups_list_prepare( + struct counter_device *const counter) +{ + const size_t total_num_groups = + counter->num_signals + counter->num_counts + 1; + struct counter_device_attr_group *groups_list; + size_t i; + int err; + size_t num_groups = 0; + + /* Allocate space for attribute groups (signals, counts, and ext) */ + groups_list = kcalloc(total_num_groups, sizeof(*groups_list), + GFP_KERNEL); + if (!groups_list) + return -ENOMEM; + + /* Initialize attribute lists */ + for (i = 0; i < total_num_groups; i++) + INIT_LIST_HEAD(&groups_list[i].attr_list); + + /* Register Signals */ + err = counter_signals_register(groups_list, counter); + if (err) + goto err_free_groups_list; + num_groups += counter->num_signals; + + /* Register Counts and respective Synapses */ + err = counter_counts_register(groups_list + num_groups, counter); + if (err) + goto err_free_groups_list; + num_groups += counter->num_counts; + + /* Register Counter global attributes */ + err = counter_global_attr_register(groups_list + num_groups, counter); + if (err) + goto err_free_groups_list; + num_groups++; + + /* Store groups_list in device_state */ + counter->device_state->groups_list = groups_list; + counter->device_state->num_groups = num_groups; + + return 0; + +err_free_groups_list: + counter_device_groups_list_free(groups_list, num_groups); + return err; +} + +static int counter_device_groups_prepare( + struct counter_device_state *const device_state) +{ + size_t i, j; + struct counter_device_attr_group *group; + int err; + struct counter_device_attr *p; + + /* Allocate attribute groups for association with device */ + device_state->groups = kcalloc(device_state->num_groups + 1, + sizeof(*device_state->groups), + GFP_KERNEL); + if (!device_state->groups) + return -ENOMEM; + + /* Prepare each group of attributes for association */ + for (i = 0; i < device_state->num_groups; i++) { + group = device_state->groups_list + i; + + /* Allocate space for attribute pointers in attribute group */ + group->attr_group.attrs = kcalloc(group->num_attr + 1, + sizeof(*group->attr_group.attrs), GFP_KERNEL); + if (!group->attr_group.attrs) { + err = -ENOMEM; + goto err_free_groups; + } + + /* Add attribute pointers to attribute group */ + j = 0; + list_for_each_entry(p, &group->attr_list, l) + group->attr_group.attrs[j++] = &p->dev_attr.attr; + + /* Group attributes in attribute group */ + device_state->groups[i] = &group->attr_group; + } + /* Associate attributes with device */ + device_state->dev.groups = device_state->groups; + + return 0; + +err_free_groups: + do { + group = device_state->groups_list + i; + kfree(group->attr_group.attrs); + group->attr_group.attrs = NULL; + } while (i--); + kfree(device_state->groups); + return err; +} + +/* Provides a unique ID for each counter device */ +static DEFINE_IDA(counter_ida); + +static void counter_device_release(struct device *dev) +{ + struct counter_device *const counter = dev_get_drvdata(dev); + struct counter_device_state *const device_state = counter->device_state; + + kfree(device_state->groups); + counter_device_groups_list_free(device_state->groups_list, + device_state->num_groups); + ida_simple_remove(&counter_ida, device_state->id); + kfree(device_state); +} + +static struct device_type counter_device_type = { + .name = "counter_device", + .release = counter_device_release +}; + +static struct bus_type counter_bus_type = { + .name = "counter" +}; + +/** + * counter_register - register Counter to the system + * @counter: pointer to Counter to register + * + * This function registers a Counter to the system. A sysfs "counter" directory + * will be created and populated with sysfs attributes correlating with the + * Counter Signals, Synapses, and Counts respectively. + */ +int counter_register(struct counter_device *const counter) +{ + struct counter_device_state *device_state; + int err; + + /* Allocate internal state container for Counter device */ + device_state = kzalloc(sizeof(*device_state), GFP_KERNEL); + if (!device_state) + return -ENOMEM; + counter->device_state = device_state; + + /* Acquire unique ID */ + device_state->id = ida_simple_get(&counter_ida, 0, 0, GFP_KERNEL); + if (device_state->id < 0) { + err = device_state->id; + goto err_free_device_state; + } + + /* Configure device structure for Counter */ + device_state->dev.type = &counter_device_type; + device_state->dev.bus = &counter_bus_type; + if (counter->parent) { + device_state->dev.parent = counter->parent; + device_state->dev.of_node = counter->parent->of_node; + } + dev_set_name(&device_state->dev, "counter%d", device_state->id); + device_initialize(&device_state->dev); + dev_set_drvdata(&device_state->dev, counter); + + /* Prepare device attributes */ + err = counter_device_groups_list_prepare(counter); + if (err) + goto err_free_id; + + /* Organize device attributes to groups and match to device */ + err = counter_device_groups_prepare(device_state); + if (err) + goto err_free_groups_list; + + /* Add device to system */ + err = device_add(&device_state->dev); + if (err) + goto err_free_groups; + + return 0; + +err_free_groups: + kfree(device_state->groups); +err_free_groups_list: + counter_device_groups_list_free(device_state->groups_list, + device_state->num_groups); +err_free_id: + ida_simple_remove(&counter_ida, device_state->id); +err_free_device_state: + kfree(device_state); + return err; +} +EXPORT_SYMBOL_GPL(counter_register); + +/** + * counter_unregister - unregister Counter from the system + * @counter: pointer to Counter to unregister + * + * The Counter is unregistered from the system; all allocated memory is freed. + */ +void counter_unregister(struct counter_device *const counter) +{ + if (counter) + device_del(&counter->device_state->dev); +} +EXPORT_SYMBOL_GPL(counter_unregister); + +static void devm_counter_unreg(struct device *dev, void *res) +{ + counter_unregister(*(struct counter_device **)res); +} + +/** + * devm_counter_register - Resource-managed counter_register + * @dev: device to allocate counter_device for + * @counter: pointer to Counter to register + * + * Managed counter_register. The Counter registered with this function is + * automatically unregistered on driver detach. This function calls + * counter_register internally. Refer to that function for more information. + * + * If an Counter registered with this function needs to be unregistered + * separately, devm_counter_unregister must be used. + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int devm_counter_register(struct device *dev, + struct counter_device *const counter) +{ + struct counter_device **ptr; + int ret; + + ptr = devres_alloc(devm_counter_unreg, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return -ENOMEM; + + ret = counter_register(counter); + if (!ret) { + *ptr = counter; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return ret; +} +EXPORT_SYMBOL_GPL(devm_counter_register); + +static int devm_counter_match(struct device *dev, void *res, void *data) +{ + struct counter_device **r = res; + + if (!r || !*r) { + WARN_ON(!r || !*r); + return 0; + } + + return *r == data; +} + +/** + * devm_counter_unregister - Resource-managed counter_unregister + * @dev: device this counter_device belongs to + * @counter: pointer to Counter associated with the device + * + * Unregister Counter registered with devm_counter_register. + */ +void devm_counter_unregister(struct device *dev, + struct counter_device *const counter) +{ + int rc; + + rc = devres_release(dev, devm_counter_unreg, devm_counter_match, + counter); + WARN_ON(rc); +} +EXPORT_SYMBOL_GPL(devm_counter_unregister); + +static int __init counter_init(void) +{ + return bus_register(&counter_bus_type); +} + +static void __exit counter_exit(void) +{ + bus_unregister(&counter_bus_type); +} + +subsys_initcall(counter_init); +module_exit(counter_exit); + +MODULE_AUTHOR("William Breathitt Gray "); +MODULE_DESCRIPTION("Generic Counter interface"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/counter.h b/include/linux/counter.h new file mode 100644 index 000000000000..a061cdcdef7c --- /dev/null +++ b/include/linux/counter.h @@ -0,0 +1,510 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Counter interface + * Copyright (C) 2018 William Breathitt Gray + */ +#ifndef _COUNTER_H_ +#define _COUNTER_H_ + +#include +#include +#include + +enum counter_count_direction { + COUNTER_COUNT_DIRECTION_FORWARD = 0, + COUNTER_COUNT_DIRECTION_BACKWARD +}; +extern const char *const counter_count_direction_str[2]; + +enum counter_count_mode { + COUNTER_COUNT_MODE_NORMAL = 0, + COUNTER_COUNT_MODE_RANGE_LIMIT, + COUNTER_COUNT_MODE_NON_RECYCLE, + COUNTER_COUNT_MODE_MODULO_N +}; +extern const char *const counter_count_mode_str[4]; + +struct counter_device; +struct counter_signal; + +/** + * struct counter_signal_ext - Counter Signal extensions + * @name: attribute name + * @read: read callback for this attribute; may be NULL + * @write: write callback for this attribute; may be NULL + * @priv: data private to the driver + */ +struct counter_signal_ext { + const char *name; + ssize_t (*read)(struct counter_device *counter, + struct counter_signal *signal, void *priv, char *buf); + ssize_t (*write)(struct counter_device *counter, + struct counter_signal *signal, void *priv, + const char *buf, size_t len); + void *priv; +}; + +/** + * struct counter_signal - Counter Signal node + * @id: unique ID used to identify signal + * @name: device-specific Signal name; ideally, this should match the name + * as it appears in the datasheet documentation + * @ext: optional array of Counter Signal extensions + * @num_ext: number of Counter Signal extensions specified in @ext + * @priv: optional private data supplied by driver + */ +struct counter_signal { + int id; + const char *name; + + const struct counter_signal_ext *ext; + size_t num_ext; + + void *priv; +}; + +/** + * struct counter_signal_enum_ext - Signal enum extension attribute + * @items: Array of strings + * @num_items: Number of items specified in @items + * @set: Set callback function; may be NULL + * @get: Get callback function; may be NULL + * + * The counter_signal_enum_ext structure can be used to implement enum style + * Signal extension attributes. Enum style attributes are those which have a set + * of strings that map to unsigned integer values. The Generic Counter Signal + * enum extension helper code takes care of mapping between value and string, as + * well as generating a "_available" file which contains a list of all available + * items. The get callback is used to query the currently active item; the index + * of the item within the respective items array is returned via the 'item' + * parameter. The set callback is called when the attribute is updated; the + * 'item' parameter contains the index of the newly activated item within the + * respective items array. + */ +struct counter_signal_enum_ext { + const char * const *items; + size_t num_items; + int (*get)(struct counter_device *counter, + struct counter_signal *signal, size_t *item); + int (*set)(struct counter_device *counter, + struct counter_signal *signal, size_t item); +}; + +/** + * COUNTER_SIGNAL_ENUM() - Initialize Signal enum extension + * @_name: Attribute name + * @_e: Pointer to a counter_signal_enum_ext structure + * + * This should usually be used together with COUNTER_SIGNAL_ENUM_AVAILABLE() + */ +#define COUNTER_SIGNAL_ENUM(_name, _e) \ +{ \ + .name = (_name), \ + .read = counter_signal_enum_read, \ + .write = counter_signal_enum_write, \ + .priv = (_e) \ +} + +/** + * COUNTER_SIGNAL_ENUM_AVAILABLE() - Initialize Signal enum available extension + * @_name: Attribute name ("_available" will be appended to the name) + * @_e: Pointer to a counter_signal_enum_ext structure + * + * Creates a read only attribute that lists all the available enum items in a + * newline separated list. This should usually be used together with + * COUNTER_SIGNAL_ENUM() + */ +#define COUNTER_SIGNAL_ENUM_AVAILABLE(_name, _e) \ +{ \ + .name = (_name "_available"), \ + .read = counter_signal_enum_available_read, \ + .priv = (_e) \ +} + +enum counter_synapse_action { + COUNTER_SYNAPSE_ACTION_NONE = 0, + COUNTER_SYNAPSE_ACTION_RISING_EDGE, + COUNTER_SYNAPSE_ACTION_FALLING_EDGE, + COUNTER_SYNAPSE_ACTION_BOTH_EDGES +}; + +/** + * struct counter_synapse - Counter Synapse node + * @action: index of current action mode + * @actions_list: array of available action modes + * @num_actions: number of action modes specified in @actions_list + * @signal: pointer to associated signal + */ +struct counter_synapse { + size_t action; + const enum counter_synapse_action *actions_list; + size_t num_actions; + + struct counter_signal *signal; +}; + +struct counter_count; + +/** + * struct counter_count_ext - Counter Count extension + * @name: attribute name + * @read: read callback for this attribute; may be NULL + * @write: write callback for this attribute; may be NULL + * @priv: data private to the driver + */ +struct counter_count_ext { + const char *name; + ssize_t (*read)(struct counter_device *counter, + struct counter_count *count, void *priv, char *buf); + ssize_t (*write)(struct counter_device *counter, + struct counter_count *count, void *priv, + const char *buf, size_t len); + void *priv; +}; + +enum counter_count_function { + COUNTER_COUNT_FUNCTION_INCREASE = 0, + COUNTER_COUNT_FUNCTION_DECREASE, + COUNTER_COUNT_FUNCTION_PULSE_DIRECTION, + COUNTER_COUNT_FUNCTION_QUADRATURE_X1_A, + COUNTER_COUNT_FUNCTION_QUADRATURE_X1_B, + COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A, + COUNTER_COUNT_FUNCTION_QUADRATURE_X2_B, + COUNTER_COUNT_FUNCTION_QUADRATURE_X4 +}; + +/** + * struct counter_count - Counter Count node + * @id: unique ID used to identify Count + * @name: device-specific Count name; ideally, this should match + * the name as it appears in the datasheet documentation + * @function: index of current function mode + * @functions_list: array available function modes + * @num_functions: number of function modes specified in @functions_list + * @synapses: array of synapses for initialization + * @num_synapses: number of synapses specified in @synapses + * @ext: optional array of Counter Count extensions + * @num_ext: number of Counter Count extensions specified in @ext + * @priv: optional private data supplied by driver + */ +struct counter_count { + int id; + const char *name; + + size_t function; + const enum counter_count_function *functions_list; + size_t num_functions; + + struct counter_synapse *synapses; + size_t num_synapses; + + const struct counter_count_ext *ext; + size_t num_ext; + + void *priv; +}; + +/** + * struct counter_count_enum_ext - Count enum extension attribute + * @items: Array of strings + * @num_items: Number of items specified in @items + * @set: Set callback function; may be NULL + * @get: Get callback function; may be NULL + * + * The counter_count_enum_ext structure can be used to implement enum style + * Count extension attributes. Enum style attributes are those which have a set + * of strings that map to unsigned integer values. The Generic Counter Count + * enum extension helper code takes care of mapping between value and string, as + * well as generating a "_available" file which contains a list of all available + * items. The get callback is used to query the currently active item; the index + * of the item within the respective items array is returned via the 'item' + * parameter. The set callback is called when the attribute is updated; the + * 'item' parameter contains the index of the newly activated item within the + * respective items array. + */ +struct counter_count_enum_ext { + const char * const *items; + size_t num_items; + int (*get)(struct counter_device *counter, struct counter_count *count, + size_t *item); + int (*set)(struct counter_device *counter, struct counter_count *count, + size_t item); +}; + +/** + * COUNTER_COUNT_ENUM() - Initialize Count enum extension + * @_name: Attribute name + * @_e: Pointer to a counter_count_enum_ext structure + * + * This should usually be used together with COUNTER_COUNT_ENUM_AVAILABLE() + */ +#define COUNTER_COUNT_ENUM(_name, _e) \ +{ \ + .name = (_name), \ + .read = counter_count_enum_read, \ + .write = counter_count_enum_write, \ + .priv = (_e) \ +} + +/** + * COUNTER_COUNT_ENUM_AVAILABLE() - Initialize Count enum available extension + * @_name: Attribute name ("_available" will be appended to the name) + * @_e: Pointer to a counter_count_enum_ext structure + * + * Creates a read only attribute that lists all the available enum items in a + * newline separated list. This should usually be used together with + * COUNTER_COUNT_ENUM() + */ +#define COUNTER_COUNT_ENUM_AVAILABLE(_name, _e) \ +{ \ + .name = (_name "_available"), \ + .read = counter_count_enum_available_read, \ + .priv = (_e) \ +} + +/** + * struct counter_device_attr_group - internal container for attribute group + * @attr_group: Counter sysfs attributes group + * @attr_list: list to keep track of created Counter sysfs attributes + * @num_attr: number of Counter sysfs attributes + */ +struct counter_device_attr_group { + struct attribute_group attr_group; + struct list_head attr_list; + size_t num_attr; +}; + +/** + * struct counter_device_state - internal state container for a Counter device + * @id: unique ID used to identify the Counter + * @dev: internal device structure + * @groups_list: attribute groups list (for Signals, Counts, and ext) + * @num_groups: number of attribute groups containers + * @groups: Counter sysfs attribute groups (to populate @dev.groups) + */ +struct counter_device_state { + int id; + struct device dev; + struct counter_device_attr_group *groups_list; + size_t num_groups; + const struct attribute_group **groups; +}; + +/** + * struct counter_signal_read_value - Opaque Signal read value + * @buf: string representation of Signal read value + * @len: length of string in @buf + */ +struct counter_signal_read_value { + char *buf; + size_t len; +}; + +/** + * struct counter_count_read_value - Opaque Count read value + * @buf: string representation of Count read value + * @len: length of string in @buf + */ +struct counter_count_read_value { + char *buf; + size_t len; +}; + +/** + * struct counter_count_write_value - Opaque Count write value + * @buf: string representation of Count write value + */ +struct counter_count_write_value { + const char *buf; +}; + +/** + * struct counter_ops - Callbacks from driver + * @signal_read: optional read callback for Signal attribute. The read + * value of the respective Signal should be passed back via + * the val parameter. val points to an opaque type which + * should be set only by calling the + * counter_signal_read_value_set function from within the + * signal_read callback. + * @count_read: optional read callback for Count attribute. The read + * value of the respective Count should be passed back via + * the val parameter. val points to an opaque type which + * should be set only by calling the + * counter_count_read_value_set function from within the + * count_read callback. + * @count_write: optional write callback for Count attribute. The write + * value for the respective Count is passed in via the val + * parameter. val points to an opaque type which should be + * accessed only by calling the + * counter_count_write_value_get function. + * @function_get: function to get the current count function mode. Returns + * 0 on success and negative error code on error. The index + * of the respective Count's returned function mode should + * be passed back via the function parameter. + * @function_set: function to set the count function mode. function is the + * index of the requested function mode from the respective + * Count's functions_list array. + * @action_get: function to get the current action mode. Returns 0 on + * success and negative error code on error. The index of + * the respective Signal's returned action mode should be + * passed back via the action parameter. + * @action_set: function to set the action mode. action is the index of + * the requested action mode from the respective Synapse's + * actions_list array. + */ +struct counter_ops { + int (*signal_read)(struct counter_device *counter, + struct counter_signal *signal, + struct counter_signal_read_value *val); + int (*count_read)(struct counter_device *counter, + struct counter_count *count, + struct counter_count_read_value *val); + int (*count_write)(struct counter_device *counter, + struct counter_count *count, + struct counter_count_write_value *val); + int (*function_get)(struct counter_device *counter, + struct counter_count *count, size_t *function); + int (*function_set)(struct counter_device *counter, + struct counter_count *count, size_t function); + int (*action_get)(struct counter_device *counter, + struct counter_count *count, + struct counter_synapse *synapse, size_t *action); + int (*action_set)(struct counter_device *counter, + struct counter_count *count, + struct counter_synapse *synapse, size_t action); +}; + +/** + * struct counter_device_ext - Counter device extension + * @name: attribute name + * @read: read callback for this attribute; may be NULL + * @write: write callback for this attribute; may be NULL + * @priv: data private to the driver + */ +struct counter_device_ext { + const char *name; + ssize_t (*read)(struct counter_device *counter, void *priv, char *buf); + ssize_t (*write)(struct counter_device *counter, void *priv, + const char *buf, size_t len); + void *priv; +}; + +/** + * struct counter_device_enum_ext - Counter enum extension attribute + * @items: Array of strings + * @num_items: Number of items specified in @items + * @set: Set callback function; may be NULL + * @get: Get callback function; may be NULL + * + * The counter_device_enum_ext structure can be used to implement enum style + * Counter extension attributes. Enum style attributes are those which have a + * set of strings that map to unsigned integer values. The Generic Counter enum + * extension helper code takes care of mapping between value and string, as well + * as generating a "_available" file which contains a list of all available + * items. The get callback is used to query the currently active item; the index + * of the item within the respective items array is returned via the 'item' + * parameter. The set callback is called when the attribute is updated; the + * 'item' parameter contains the index of the newly activated item within the + * respective items array. + */ +struct counter_device_enum_ext { + const char * const *items; + size_t num_items; + int (*get)(struct counter_device *counter, size_t *item); + int (*set)(struct counter_device *counter, size_t item); +}; + +/** + * COUNTER_DEVICE_ENUM() - Initialize Counter enum extension + * @_name: Attribute name + * @_e: Pointer to a counter_device_enum_ext structure + * + * This should usually be used together with COUNTER_DEVICE_ENUM_AVAILABLE() + */ +#define COUNTER_DEVICE_ENUM(_name, _e) \ +{ \ + .name = (_name), \ + .read = counter_device_enum_read, \ + .write = counter_device_enum_write, \ + .priv = (_e) \ +} + +/** + * COUNTER_DEVICE_ENUM_AVAILABLE() - Initialize Counter enum available extension + * @_name: Attribute name ("_available" will be appended to the name) + * @_e: Pointer to a counter_device_enum_ext structure + * + * Creates a read only attribute that lists all the available enum items in a + * newline separated list. This should usually be used together with + * COUNTER_DEVICE_ENUM() + */ +#define COUNTER_DEVICE_ENUM_AVAILABLE(_name, _e) \ +{ \ + .name = (_name "_available"), \ + .read = counter_device_enum_available_read, \ + .priv = (_e) \ +} + +/** + * struct counter_device - Counter data structure + * @name: name of the device as it appears in the datasheet + * @parent: optional parent device providing the counters + * @device_state: internal device state container + * @ops: callbacks from driver + * @signals: array of Signals + * @num_signals: number of Signals specified in @signals + * @counts: array of Counts + * @num_counts: number of Counts specified in @counts + * @ext: optional array of Counter device extensions + * @num_ext: number of Counter device extensions specified in @ext + * @priv: optional private data supplied by driver + */ +struct counter_device { + const char *name; + struct device *parent; + struct counter_device_state *device_state; + + const struct counter_ops *ops; + + struct counter_signal *signals; + size_t num_signals; + struct counter_count *counts; + size_t num_counts; + + const struct counter_device_ext *ext; + size_t num_ext; + + void *priv; +}; + +enum counter_signal_level { + COUNTER_SIGNAL_LEVEL_LOW = 0, + COUNTER_SIGNAL_LEVEL_HIGH +}; + +enum counter_signal_value_type { + COUNTER_SIGNAL_LEVEL = 0 +}; + +enum counter_count_value_type { + COUNTER_COUNT_POSITION = 0, +}; + +void counter_signal_read_value_set(struct counter_signal_read_value *const val, + const enum counter_signal_value_type type, + void *const data); +void counter_count_read_value_set(struct counter_count_read_value *const val, + const enum counter_count_value_type type, + void *const data); +int counter_count_write_value_get(void *const data, + const enum counter_count_value_type type, + const struct counter_count_write_value *const val); + +int counter_register(struct counter_device *const counter); +void counter_unregister(struct counter_device *const counter); +int devm_counter_register(struct device *dev, + struct counter_device *const counter); +void devm_counter_unregister(struct device *dev, + struct counter_device *const counter); + +#endif /* _COUNTER_H_ */ diff --git a/include/linux/counter_enum.h b/include/linux/counter_enum.h new file mode 100644 index 000000000000..9f917298a88f --- /dev/null +++ b/include/linux/counter_enum.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Counter interface enum functions + * Copyright (C) 2018 William Breathitt Gray + */ +#ifndef _COUNTER_ENUM_H_ +#define _COUNTER_ENUM_H_ + +#include + +struct counter_device; +struct counter_signal; +struct counter_count; + +ssize_t counter_signal_enum_read(struct counter_device *counter, + struct counter_signal *signal, void *priv, + char *buf); +ssize_t counter_signal_enum_write(struct counter_device *counter, + struct counter_signal *signal, void *priv, + const char *buf, size_t len); + +ssize_t counter_signal_enum_available_read(struct counter_device *counter, + struct counter_signal *signal, + void *priv, char *buf); + +ssize_t counter_count_enum_read(struct counter_device *counter, + struct counter_count *count, void *priv, + char *buf); +ssize_t counter_count_enum_write(struct counter_device *counter, + struct counter_count *count, void *priv, + const char *buf, size_t len); + +ssize_t counter_count_enum_available_read(struct counter_device *counter, + struct counter_count *count, + void *priv, char *buf); + +ssize_t counter_device_enum_read(struct counter_device *counter, void *priv, + char *buf); +ssize_t counter_device_enum_write(struct counter_device *counter, void *priv, + const char *buf, size_t len); + +ssize_t counter_device_enum_available_read(struct counter_device *counter, + void *priv, char *buf); + +#endif /* _COUNTER_ENUM_H_ */ From patchwork Tue Apr 2 06:30:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Breathitt Gray X-Patchwork-Id: 10881071 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 712DE1669 for ; Tue, 2 Apr 2019 06:31:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 55A0428770 for ; Tue, 2 Apr 2019 06:31:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4874D28843; Tue, 2 Apr 2019 06:31:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9A77028770 for ; Tue, 2 Apr 2019 06:31:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=v2b1S7Q/w4mDRLAZIINonryRkQqzeIiqrBREt4fYo1U=; b=nBmrbnq+ez1WZo JbI90QZu+CqBH1JZkihXu6CxurpJjnc1Ahx4Ra1AQiKMwLhCl+H80Xp8rev3O2GogiuHi79YdwcNf iq0nMqigFeEpMBX0Tei5V3tlrwaKVShDzeb34udTuHhDhLLkDjOCY7enGZff3n/TZ21us/E0SZpLV t7kLwF1736TbL3KzFkR/aG9dHqKCS+w/UkkhS6fRfhcCj5/djYx58RA/Qxpm5XCOHe+BDH35vipCq gS0fcJV16BvO+wG4/LkGPcpq2UA7IovN79nrGx81Z60VbB0pRmOoRpdM5rahJNL8OHIKSyEnxRA8A L7IzrR1W120y8xlJ28JA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCwn-0008Rg-8H; Tue, 02 Apr 2019 06:31:01 +0000 Received: from mail-pg1-x544.google.com ([2607:f8b0:4864:20::544]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCwL-0007xE-9w for linux-arm-kernel@lists.infradead.org; Tue, 02 Apr 2019 06:30:42 +0000 Received: by mail-pg1-x544.google.com with SMTP id j26so6022357pgl.5 for ; Mon, 01 Apr 2019 23:30:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=D3TIN7GVmzZf2vc4K8K5AuMdS/7XAlZhj8cjpR6bpjs=; b=JsVsUpDoZ8mC7tNQGcsRzmeEU0alBBVqm5MslrRSC6T2ZRVw+zUqt5rkWJPxMciLun u1i9k9xtM7TlZs7oEbetVzr+i3i4A49Y87c5Mnd8cseTs6iZILi+vQRtwcijBUdNfCRb +nTtiJ1hSXrpi2IK5px1Acc9Z4uLWXcrCIikshC3zYiwtMYyHAh8twl5Iy3ELpSpOvT4 Uo3t9KZC8d5Egtkyew32U3Qx7qUMG6Om1tO8BNDXO30ragx0q7HIT5cpWIZOjUYVnoT+ SoXITqElV2aKCzMkVYJGgaYBQYAiVGcrKp3GZezuaueYlH+Zlp4NqkPcIDSkw9996Gt0 V8VQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=D3TIN7GVmzZf2vc4K8K5AuMdS/7XAlZhj8cjpR6bpjs=; b=p/7E9pktAurYtD9BpYrfWpbkGxBiLZf9G2w/Y2bPryl2M84VNUxoKR+IBG2S6OysU6 t190cZDFKEGCHaNAbN+J8La0sXSEtsSFc3wCL/ctxJ2rVujF1U/HA1kijcJ8a/70/bpK tbGNJojHW/OVqaDrc4OoKQ8wseCZA95Mo1wke8mDc03FkFVi/jlNhCZK17nEL+bgfi1/ fc4sEiO4nW0Nzd41efLXJTGxCa7VlX9TTsZUlk6LY4VXqUQXh2BzfFghR+gd/uQkHN/7 adEw8Jwcl+J+WrDhm8UmcV3DW37J29fQGpjUc4Lqweb7DtK+TPpZ3KBczkkRfEEH4XSy 3TAw== X-Gm-Message-State: APjAAAXUZcfI4ZnP6Yq4mpXNuj0FpnVr9yatLivQtwVg87AJHY9ceElD Wj/88uRp2n8qzahnlqrKJBY= X-Google-Smtp-Source: APXvYqzSeGoSAa/6Nug0zyY9tEFUnup6xUq83Lxmbp4KhfmcdS/VfA1Xkq1I1CPJp/NHDZYDlGfFwQ== X-Received: by 2002:a63:fc43:: with SMTP id r3mr47039829pgk.44.1554186632252; Mon, 01 Apr 2019 23:30:32 -0700 (PDT) Received: from localhost.localdomain ([2001:268:c0a5:4ce0:c70:4af9:86e2:2]) by smtp.gmail.com with ESMTPSA id a17sm19327289pfj.123.2019.04.01.23.30.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Apr 2019 23:30:31 -0700 (PDT) From: William Breathitt Gray To: gregkh@linuxfoundation.org Subject: [PATCH v10 02/18] counter: Documentation: Add Generic Counter sysfs documentation Date: Tue, 2 Apr 2019 15:30:37 +0900 Message-Id: X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190401_233033_743356_2C75A37A X-CRM114-Status: GOOD ( 21.91 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, benjamin.gaignard@st.com, linux-pwm@vger.kernel.org, linux-iio@vger.kernel.org, patrick.havelange@essensium.com, thierry.reding@gmail.com, pmeerw@pmeerw.net, lars@metafoo.de, daniel.lezcano@linaro.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, david@lechnology.com, William Breathitt Gray , robh+dt@kernel.org, Jonathan Cameron , tglx@linutronix.de, fabrice.gasnier@st.com, esben@haabendal.dk, shawnguo@kernel.org, linux-kernel@vger.kernel.org, leoyang.li@nxp.com, knaack.h@gmx.de, akpm@linux-foundation.org, linuxppc-dev@lists.ozlabs.org, jic23@kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds standard documentation for the userspace sysfs attributes of the Generic Counter interface. Reviewed-by: Jonathan Cameron Signed-off-by: William Breathitt Gray --- Documentation/ABI/testing/sysfs-bus-counter | 230 ++++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 231 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-counter diff --git a/Documentation/ABI/testing/sysfs-bus-counter b/Documentation/ABI/testing/sysfs-bus-counter new file mode 100644 index 000000000000..566bd99fe0a5 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-counter @@ -0,0 +1,230 @@ +What: /sys/bus/counter/devices/counterX/countY/count +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Count data of Count Y represented as a string. + +What: /sys/bus/counter/devices/counterX/countY/ceiling +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Count value ceiling for Count Y. This is the upper limit for the + respective counter. + +What: /sys/bus/counter/devices/counterX/countY/floor +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Count value floor for Count Y. This is the lower limit for the + respective counter. + +What: /sys/bus/counter/devices/counterX/countY/count_mode +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Count mode for channel Y. The ceiling and floor values for + Count Y are used by the count mode where required. The following + count modes are available: + + normal: + Counting is continuous in either direction. + + range limit: + An upper or lower limit is set, mimicking limit switches + in the mechanical counterpart. The upper limit is set to + the Count Y ceiling value, while the lower limit is set + to the Count Y floor value. The counter freezes at + count = ceiling when counting up, and at count = floor + when counting down. At either of these limits, the + counting is resumed only when the count direction is + reversed. + + non-recycle: + The counter is disabled whenever a counter overflow or + underflow takes place. The counter is re-enabled when a + new count value is loaded to the counter via a preset + operation or direct write. + + modulo-n: + A count value boundary is set between the Count Y floor + value and the Count Y ceiling value. The counter is + reset to the Count Y floor value at count = ceiling when + counting up, while the counter is set to the Count Y + ceiling value at count = floor when counting down; the + counter does not freeze at the boundary points, but + counts continuously throughout. + +What: /sys/bus/counter/devices/counterX/countY/count_mode_available +What: /sys/bus/counter/devices/counterX/countY/error_noise_available +What: /sys/bus/counter/devices/counterX/countY/function_available +What: /sys/bus/counter/devices/counterX/countY/signalZ_action_available +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Discrete set of available values for the respective Count Y + configuration are listed in this file. Values are delimited by + newline characters. + +What: /sys/bus/counter/devices/counterX/countY/direction +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Read-only attribute that indicates the count direction of Count + Y. Two count directions are available: forward and backward. + + Some counter devices are able to determine the direction of + their counting. For example, quadrature encoding counters can + determine the direction of movement by evaluating the leading + phase of the respective A and B quadrature encoding signals. + This attribute exposes such count directions. + +What: /sys/bus/counter/devices/counterX/countY/enable +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Whether channel Y counter is enabled. Valid attribute values are + boolean. + + This attribute is intended to serve as a pause/unpause mechanism + for Count Y. Suppose a counter device is used to count the total + movement of a conveyor belt: this attribute allows an operator + to temporarily pause the counter, service the conveyor belt, + and then finally unpause the counter to continue where it had + left off. + +What: /sys/bus/counter/devices/counterX/countY/error_noise +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Read-only attribute that indicates whether excessive noise is + present at the channel Y counter inputs. + +What: /sys/bus/counter/devices/counterX/countY/function +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Count function mode of Count Y; count function evaluation is + triggered by conditions specified by the Count Y signalZ_action + attributes. The following count functions are available: + + increase: + Accumulated count is incremented. + + decrease: + Accumulated count is decremented. + + pulse-direction: + Rising edges on signal A updates the respective count. + The input level of signal B determines direction. + + quadrature x1 a: + If direction is forward, rising edges on quadrature pair + signal A updates the respective count; if the direction + is backward, falling edges on quadrature pair signal A + updates the respective count. Quadrature encoding + determines the direction. + + quadrature x1 b: + If direction is forward, rising edges on quadrature pair + signal B updates the respective count; if the direction + is backward, falling edges on quadrature pair signal B + updates the respective count. Quadrature encoding + determines the direction. + + quadrature x2 a: + Any state transition on quadrature pair signal A updates + the respective count. Quadrature encoding determines the + direction. + + quadrature x2 b: + Any state transition on quadrature pair signal B updates + the respective count. Quadrature encoding determines the + direction. + + quadrature x4: + Any state transition on either quadrature pair signals + updates the respective count. Quadrature encoding + determines the direction. + +What: /sys/bus/counter/devices/counterX/countY/name +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Read-only attribute that indicates the device-specific name of + Count Y. If possible, this should match the name of the + respective channel as it appears in the device datasheet. + +What: /sys/bus/counter/devices/counterX/countY/preset +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + If the counter device supports preset registers -- registers + used to load counter channels to a set count upon device-defined + preset operation trigger events -- the preset count for channel + Y is provided by this attribute. + +What: /sys/bus/counter/devices/counterX/countY/preset_enable +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Whether channel Y counter preset operation is enabled. Valid + attribute values are boolean. + +What: /sys/bus/counter/devices/counterX/countY/signalZ_action +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Action mode of Count Y for Signal Z. This attribute indicates + the condition of Signal Z that triggers the count function + evaluation for Count Y. The following action modes are + available: + + none: + Signal does not trigger the count function. In + Pulse-Direction count function mode, this Signal is + evaluated as Direction. + + rising edge: + Low state transitions to high state. + + falling edge: + High state transitions to low state. + + both edges: + Any state transition. + +What: /sys/bus/counter/devices/counterX/name +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Read-only attribute that indicates the device-specific name of + the Counter. This should match the name of the device as it + appears in its respective datasheet. + +What: /sys/bus/counter/devices/counterX/num_counts +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Read-only attribute that indicates the total number of Counts + belonging to the Counter. + +What: /sys/bus/counter/devices/counterX/num_signals +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Read-only attribute that indicates the total number of Signals + belonging to the Counter. + +What: /sys/bus/counter/devices/counterX/signalY/signal +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Signal data of Signal Y represented as a string. + +What: /sys/bus/counter/devices/counterX/signalY/name +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Read-only attribute that indicates the device-specific name of + Signal Y. If possible, this should match the name of the + respective signal as it appears in the device datasheet. diff --git a/MAINTAINERS b/MAINTAINERS index ef497d470501..af701863a249 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3970,6 +3970,7 @@ COUNTER SUBSYSTEM M: William Breathitt Gray L: linux-iio@vger.kernel.org S: Maintained +F: Documentation/ABI/testing/sysfs-bus-counter* F: drivers/counter/ F: include/linux/counter.h F: include/linux/counter_enum.h From patchwork Tue Apr 2 06:30:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Breathitt Gray X-Patchwork-Id: 10881077 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 500561669 for ; Tue, 2 Apr 2019 06:31:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 33CC128770 for ; Tue, 2 Apr 2019 06:31:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 27867288B4; Tue, 2 Apr 2019 06:31:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 799DC28770 for ; Tue, 2 Apr 2019 06:31:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Jxt4kSln6erNd+TwKFplqS/7W3I21VF/ESasPiwrafA=; b=euoI56X+4p1dqf cbypgolA35myef+ZjrinGu4KaB3CdxmlfCunmN4nmK1YVjAwNt+KAF17eJQcxPGGYbwjhPN9TO5kP agmrPdE7Af4w+OQVRAU6NLX9FDO71I0lIzj1vp0i8tkj+Ey3TRcXWUCRNEqoxHxgzC3f9iXqCvSHy +YUuWLwfKKTKbkrMtWTnMjdUiNQ2Qyb/mUinjeRFJwfZ2KzGQu2SdKKeK/lT6w3kFAqh0tXTxGoxP NSdTULO9KLut0LPQDKSAIyukeg/+bm7A3qxat6Cnl8aVdUZpgObNNbtNL/3M9wH8chM8aSr/zD0mR F0ffJAjw6OeJbXDLBF2A==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCwz-0000Ic-Jl; Tue, 02 Apr 2019 06:31:13 +0000 Received: from mail-pg1-x543.google.com ([2607:f8b0:4864:20::543]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCwV-00089h-Vf for linux-arm-kernel@lists.infradead.org; Tue, 02 Apr 2019 06:30:59 +0000 Received: by mail-pg1-x543.google.com with SMTP id p6so6009013pgh.9 for ; Mon, 01 Apr 2019 23:30:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=lKsEEW9zGC7z+vMiNGYsEakXMLu4Ku5min8yoaBqYdY=; b=m/YU9WquU9JxGHokLkAUweNMwtJP8IUYe2IrUE253dHBmNL9x7Vy9j7PZRxl7iN5/+ /uyZU+my3pwdZ/IR43LjfwoP2H3Po8lAXLcFItQ0UqcGdvaqrZFWoWfsu82Z61g03B13 Up6qmtH6OrAJFOD/N4zCjEIAEv5cs05y6acf313KOsHsR5cT3otZWFi9NwWKZwDJ2Dmt s1Dj89/NDxMyHDXpn5T5Wz6GtT6pMfAhKurgjWJotiK1Q6ObrchjNDU8EmUftbwItPxu H3GAaq5hEai6m65YhK7ErHzEkcC3sPFe5E6I/feUErH+d9eDf0z9RHx6GSRfZ75Zin8g piaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=lKsEEW9zGC7z+vMiNGYsEakXMLu4Ku5min8yoaBqYdY=; b=QfhusBXZcBXri5MArTMG3MRlAt94GDAgnWL7P8ZTW5kGem5ZCsMWFKBOQVRAJvtMva MFOvawL6i41LcwDLZ1X/rke5cjBCMAsQgIn88loBD6k411ucP7A3yP5cYPgDlg0FOFSr ZrSnr40/3dfcETJh/+jWxbu9nb6quBOA6x3SxMeTyEOvKtvFz0votKzs/T3jIy7AOSqu LzK3YMVnLKtdD++9kLG8GlNFFhOHBREwWkYf0fc0+e3ZMwugbYOJYxIvOa+VCaNyI/N8 t2bprvqB6efqKErRQ2fd8iTczMZmbsaXGE+GlQAR4MBP2iwFMPZWj+xDlobaH4xPVRIu f7QQ== X-Gm-Message-State: APjAAAXGZJCTX1pDTa0nkn8JTCM4yHIERUuctYyjvPWEDzgecxTNXGRX bwYOkL8yV0K+Pgw3epAuUGU= X-Google-Smtp-Source: APXvYqweF4OgPR3Bh2MXNEgp2fs9TLID62C/xhXUlzaAid8hKvU0ECtorgzz9nRsZc1/88rSyHEydA== X-Received: by 2002:a63:700f:: with SMTP id l15mr19831057pgc.3.1554186643341; Mon, 01 Apr 2019 23:30:43 -0700 (PDT) Received: from localhost.localdomain ([2001:268:c0a5:4ce0:c70:4af9:86e2:2]) by smtp.gmail.com with ESMTPSA id a17sm19327289pfj.123.2019.04.01.23.30.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Apr 2019 23:30:42 -0700 (PDT) From: William Breathitt Gray To: gregkh@linuxfoundation.org Subject: [PATCH v10 03/18] docs: Add Generic Counter interface documentation Date: Tue, 2 Apr 2019 15:30:38 +0900 Message-Id: <1a232b5fdfe434b5e066f389f839243bcf151a33.1554184734.git.vilhelm.gray@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190401_233044_325799_7217CC1C X-CRM114-Status: GOOD ( 23.59 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, benjamin.gaignard@st.com, linux-pwm@vger.kernel.org, linux-iio@vger.kernel.org, patrick.havelange@essensium.com, thierry.reding@gmail.com, pmeerw@pmeerw.net, lars@metafoo.de, daniel.lezcano@linaro.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, david@lechnology.com, William Breathitt Gray , robh+dt@kernel.org, Jonathan Cameron , tglx@linutronix.de, fabrice.gasnier@st.com, esben@haabendal.dk, shawnguo@kernel.org, linux-kernel@vger.kernel.org, leoyang.li@nxp.com, knaack.h@gmx.de, akpm@linux-foundation.org, linuxppc-dev@lists.ozlabs.org, jic23@kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds high-level documentation about the Generic Counter interface. Reviewed-by: Jonathan Cameron Signed-off-by: William Breathitt Gray --- Documentation/driver-api/generic-counter.rst | 342 +++++++++++++++++++ Documentation/driver-api/index.rst | 1 + MAINTAINERS | 1 + 3 files changed, 344 insertions(+) create mode 100644 Documentation/driver-api/generic-counter.rst diff --git a/Documentation/driver-api/generic-counter.rst b/Documentation/driver-api/generic-counter.rst new file mode 100644 index 000000000000..f51db893f595 --- /dev/null +++ b/Documentation/driver-api/generic-counter.rst @@ -0,0 +1,342 @@ +.. SPDX-License-Identifier: GPL-2.0 + +========================= +Generic Counter Interface +========================= + +Introduction +============ + +Counter devices are prevalent within a diverse spectrum of industries. +The ubiquitous presence of these devices necessitates a common interface +and standard of interaction and exposure. This driver API attempts to +resolve the issue of duplicate code found among existing counter device +drivers by introducing a generic counter interface for consumption. The +Generic Counter interface enables drivers to support and expose a common +set of components and functionality present in counter devices. + +Theory +====== + +Counter devices can vary greatly in design, but regardless of whether +some devices are quadrature encoder counters or tally counters, all +counter devices consist of a core set of components. This core set of +components, shared by all counter devices, is what forms the essence of +the Generic Counter interface. + +There are three core components to a counter: + +* Count: + Count data for a set of Signals. + +* Signal: + Input data that is evaluated by the counter to determine the count + data. + +* Synapse: + The association of a Signal with a respective Count. + +COUNT +----- +A Count represents the count data for a set of Signals. The Generic +Counter interface provides the following available count data types: + +* COUNT_POSITION: + Unsigned integer value representing position. + +A Count has a count function mode which represents the update behavior +for the count data. The Generic Counter interface provides the following +available count function modes: + +* Increase: + Accumulated count is incremented. + +* Decrease: + Accumulated count is decremented. + +* Pulse-Direction: + Rising edges on signal A updates the respective count. The input level + of signal B determines direction. + +* Quadrature: + A pair of quadrature encoding signals are evaluated to determine + position and direction. The following Quadrature modes are available: + + - x1 A: + If direction is forward, rising edges on quadrature pair signal A + updates the respective count; if the direction is backward, falling + edges on quadrature pair signal A updates the respective count. + Quadrature encoding determines the direction. + + - x1 B: + If direction is forward, rising edges on quadrature pair signal B + updates the respective count; if the direction is backward, falling + edges on quadrature pair signal B updates the respective count. + Quadrature encoding determines the direction. + + - x2 A: + Any state transition on quadrature pair signal A updates the + respective count. Quadrature encoding determines the direction. + + - x2 B: + Any state transition on quadrature pair signal B updates the + respective count. Quadrature encoding determines the direction. + + - x4: + Any state transition on either quadrature pair signals updates the + respective count. Quadrature encoding determines the direction. + +A Count has a set of one or more associated Signals. + +SIGNAL +------ +A Signal represents a counter input data; this is the input data that is +evaluated by the counter to determine the count data; e.g. a quadrature +signal output line of a rotary encoder. Not all counter devices provide +user access to the Signal data. + +The Generic Counter interface provides the following available signal +data types for when the Signal data is available for user access: + +* SIGNAL_LEVEL: + Signal line state level. The following states are possible: + + - SIGNAL_LEVEL_LOW: + Signal line is in a low state. + + - SIGNAL_LEVEL_HIGH: + Signal line is in a high state. + +A Signal may be associated with one or more Counts. + +SYNAPSE +------- +A Synapse represents the association of a Signal with a respective +Count. Signal data affects respective Count data, and the Synapse +represents this relationship. + +The Synapse action mode specifies the Signal data condition which +triggers the respective Count's count function evaluation to update the +count data. The Generic Counter interface provides the following +available action modes: + +* None: + Signal does not trigger the count function. In Pulse-Direction count + function mode, this Signal is evaluated as Direction. + +* Rising Edge: + Low state transitions to high state. + +* Falling Edge: + High state transitions to low state. + +* Both Edges: + Any state transition. + +A counter is defined as a set of input signals associated with count +data that are generated by the evaluation of the state of the associated +input signals as defined by the respective count functions. Within the +context of the Generic Counter interface, a counter consists of Counts +each associated with a set of Signals, whose respective Synapse +instances represent the count function update conditions for the +associated Counts. + +Paradigm +======== + +The most basic counter device may be expressed as a single Count +associated with a single Signal via a single Synapse. Take for example +a counter device which simply accumulates a count of rising edges on a +source input line:: + + Count Synapse Signal + ----- ------- ------ + +---------------------+ + | Data: Count | Rising Edge ________ + | Function: Increase | <------------- / Source \ + | | ____________ + +---------------------+ + +In this example, the Signal is a source input line with a pulsing +voltage, while the Count is a persistent count value which is repeatedly +incremented. The Signal is associated with the respective Count via a +Synapse. The increase function is triggered by the Signal data condition +specified by the Synapse -- in this case a rising edge condition on the +voltage input line. In summary, the counter device existence and +behavior is aptly represented by respective Count, Signal, and Synapse +components: a rising edge condition triggers an increase function on an +accumulating count datum. + +A counter device is not limited to a single Signal; in fact, in theory +many Signals may be associated with even a single Count. For example, a +quadrature encoder counter device can keep track of position based on +the states of two input lines:: + + Count Synapse Signal + ----- ------- ------ + +-------------------------+ + | Data: Position | Both Edges ___ + | Function: Quadrature x4 | <------------ / A \ + | | _______ + | | + | | Both Edges ___ + | | <------------ / B \ + | | _______ + +-------------------------+ + +In this example, two Signals (quadrature encoder lines A and B) are +associated with a single Count: a rising or falling edge on either A or +B triggers the "Quadrature x4" function which determines the direction +of movement and updates the respective position data. The "Quadrature +x4" function is likely implemented in the hardware of the quadrature +encoder counter device; the Count, Signals, and Synapses simply +represent this hardware behavior and functionality. + +Signals associated with the same Count can have differing Synapse action +mode conditions. For example, a quadrature encoder counter device +operating in a non-quadrature Pulse-Direction mode could have one input +line dedicated for movement and a second input line dedicated for +direction:: + + Count Synapse Signal + ----- ------- ------ + +---------------------------+ + | Data: Position | Rising Edge ___ + | Function: Pulse-Direction | <------------- / A \ (Movement) + | | _______ + | | + | | None ___ + | | <------------- / B \ (Direction) + | | _______ + +---------------------------+ + +Only Signal A triggers the "Pulse-Direction" update function, but the +instantaneous state of Signal B is still required in order to know the +direction so that the position data may be properly updated. Ultimately, +both Signals are associated with the same Count via two respective +Synapses, but only one Synapse has an active action mode condition which +triggers the respective count function while the other is left with a +"None" condition action mode to indicate its respective Signal's +availability for state evaluation despite its non-triggering mode. + +Keep in mind that the Signal, Synapse, and Count are abstract +representations which do not need to be closely married to their +respective physical sources. This allows the user of a counter to +divorce themselves from the nuances of physical components (such as +whether an input line is differential or single-ended) and instead focus +on the core idea of what the data and process represent (e.g. position +as interpreted from quadrature encoding data). + +Userspace Interface +=================== + +Several sysfs attributes are generated by the Generic Counter interface, +and reside under the /sys/bus/counter/devices/counterX directory, where +counterX refers to the respective counter device. Please see +Documentation/ABI/testing/sys-bus-counter-generic-sysfs for detailed +information on each Generic Counter interface sysfs attribute. + +Through these sysfs attributes, programs and scripts may interact with +the Generic Counter paradigm Counts, Signals, and Synapses of respective +counter devices. + +Driver API +========== + +Driver authors may utilize the Generic Counter interface in their code +by including the include/linux/counter.h header file. This header file +provides several core data structures, function prototypes, and macros +for defining a counter device. + +.. kernel-doc:: include/linux/counter.h + :internal: + +.. kernel-doc:: drivers/counter/generic-counter.c + :export: + +Implementation +============== + +To support a counter device, a driver must first allocate the available +Counter Signals via counter_signal structures. These Signals should +be stored as an array and set to the signals array member of an +allocated counter_device structure before the Counter is registered to +the system. + +Counter Counts may be allocated via counter_count structures, and +respective Counter Signal associations (Synapses) made via +counter_synapse structures. Associated counter_synapse structures are +stored as an array and set to the the synapses array member of the +respective counter_count structure. These counter_count structures are +set to the counts array member of an allocated counter_device structure +before the Counter is registered to the system. + +Driver callbacks should be provided to the counter_device structure via +a constant counter_ops structure in order to communicate with the +device: to read and write various Signals and Counts, and to set and get +the "action mode" and "function mode" for various Synapses and Counts +respectively. + +A defined counter_device structure may be registered to the system by +passing it to the counter_register function, and unregistered by passing +it to the counter_unregister function. Similarly, the +devm_counter_register and devm_counter_unregister functions may be used +if device memory-managed registration is desired. + +Extension sysfs attributes can be created for auxiliary functionality +and data by passing in defined counter_device_ext, counter_count_ext, +and counter_signal_ext structures. In these cases, the +counter_device_ext structure is used for global configuration of the +respective Counter device, while the counter_count_ext and +counter_signal_ext structures allow for auxiliary exposure and +configuration of a specific Count or Signal respectively. + +Architecture +============ + +When the Generic Counter interface counter module is loaded, the +counter_init function is called which registers a bus_type named +"counter" to the system. Subsequently, when the module is unloaded, the +counter_exit function is called which unregisters the bus_type named +"counter" from the system. + +Counter devices are registered to the system via the counter_register +function, and later removed via the counter_unregister function. The +counter_register function establishes a unique ID for the Counter +device and creates a respective sysfs directory, where X is the +mentioned unique ID: + + /sys/bus/counter/devices/counterX + +Sysfs attributes are created within the counterX directory to expose +functionality, configurations, and data relating to the Counts, Signals, +and Synapses of the Counter device, as well as options and information +for the Counter device itself. + +Each Signal has a directory created to house its relevant sysfs +attributes, where Y is the unique ID of the respective Signal: + + /sys/bus/counter/devices/counterX/signalY + +Similarly, each Count has a directory created to house its relevant +sysfs attributes, where Y is the unique ID of the respective Count: + + /sys/bus/counter/devices/counterX/countY + +For a more detailed breakdown of the available Generic Counter interface +sysfs attributes, please refer to the +Documentation/ABI/testing/sys-bus-counter file. + +The Signals and Counts associated with the Counter device are registered +to the system as well by the counter_register function. The +signal_read/signal_write driver callbacks are associated with their +respective Signal attributes, while the count_read/count_write and +function_get/function_set driver callbacks are associated with their +respective Count attributes; similarly, the same is true for the +action_get/action_set driver callbacks and their respective Synapse +attributes. If a driver callback is left undefined, then the respective +read/write permission is left disabled for the relevant attributes. + +Similarly, extension sysfs attributes are created for the defined +counter_device_ext, counter_count_ext, and counter_signal_ext +structures that are passed in. diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst index ab38ced66a44..37dce988c7fd 100644 --- a/Documentation/driver-api/index.rst +++ b/Documentation/driver-api/index.rst @@ -55,6 +55,7 @@ available subsections can be seen below. slimbus soundwire/index fpga/index + generic-counter .. only:: subproject and html diff --git a/MAINTAINERS b/MAINTAINERS index af701863a249..208c92ff4801 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3971,6 +3971,7 @@ M: William Breathitt Gray L: linux-iio@vger.kernel.org S: Maintained F: Documentation/ABI/testing/sysfs-bus-counter* +F: Documentation/driver-api/generic-counter.rst F: drivers/counter/ F: include/linux/counter.h F: include/linux/counter_enum.h From patchwork Tue Apr 2 06:30:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Breathitt Gray X-Patchwork-Id: 10881081 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 79D5017E0 for ; Tue, 2 Apr 2019 06:31:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6045B28770 for ; Tue, 2 Apr 2019 06:31:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 508C828843; Tue, 2 Apr 2019 06:31:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id F110A28770 for ; Tue, 2 Apr 2019 06:31:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=OpMIV2avPp3bohGT3LTfEPYn//1iN/Ujp8/Fi2Un7vU=; b=lqkNwiP8/jJY7f y/+7dGjcbhlYwzM5Mu/V8oQFMWng3Xsp70n2OotRu+qJQKjxx/mOQ6Cgifd6xx6lF4FCj+rWK3IDn NudC5RqmfnQjCnFASLZa0CZNKLnp6s0BOOv6l/xuiFv82necKrT+65Vc8MuYR/XcC30qwLAKLfztc 5oyWD4YRC2hENnr07CTsAegiYwpkNQ91H7sVPqUEi0ZmrWm1hP5+iQ9nh2T8KUHxRUz279tLSYFNn lElDuUkja/77XrUzS6vUlbTG5aS1+jOewxxbTe0asUgsG7s9ym4uBoFTKus6M2L9GemhxUFk5cIxq fYuR+TsPGeAK2FTj5PMA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCxD-0000b3-Pi; Tue, 02 Apr 2019 06:31:27 +0000 Received: from mail-pl1-x644.google.com ([2607:f8b0:4864:20::644]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCwf-0008LL-H2 for linux-arm-kernel@lists.infradead.org; Tue, 02 Apr 2019 06:31:12 +0000 Received: by mail-pl1-x644.google.com with SMTP id b65so5726253plb.6 for ; Mon, 01 Apr 2019 23:30:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=aNedWm3Hz3KKze8HS2QeLEYl8kQ1q+G71sLG9i3ZRic=; b=ILDqsSxyB02bx9BVIh9Q+V6ahH1FtKycYJdcDWYBcuhkZuyWTkKwWMHegUoTHYL083 KhpHR1vYrBzG5hCwiVWzTKsKIek2jmlfYKPLhIJL63gAa3llh1jtWrJdAiuDErRdw9d+ ntgurJRKRgu+i5hlA+uVWyLiS+lzl9EB2jvvsWyENnvEGH6Ya7YxQT9bpKVmq5rY5BIP sm4+OX4Lu0zQ+bJNfJ5Y5NjOtG3QrBwlRk6xxkx56Kn56FfRLeINM7yWEGjreqUDSxJi Ye3nXJuvtLWkE3dggxILMsil8LjKGgK4g2OFj1aZRnJcj0MxvjHuZXgBbrOtiuBLaV+u G++g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=aNedWm3Hz3KKze8HS2QeLEYl8kQ1q+G71sLG9i3ZRic=; b=kNtBUxZJ8lIUEk76J1l1kQ/RxIdw+Mu21MV8gC3Mu0LjRXm/KXX5VcQYEYSbmrJjPb 8Uwcn6dGTiSM3P77OIDY11qzkh6k96Bgk8nKTTkPM/WjctccDvqam8OzPrkEQ3MqtDpp 5nJ3eXzLaZmvSsXpnRXTLDSeadWCuPuLxbxeyi7MmUn2ZJL0+8xSIqutcaB3vCKtKIuF eQLEMmq9b5Z3rjTTjLqBImXUQoJ0N01mvjYiLUfP+N4Fn9HoCFK4vEv5xQOHBP/F956F so8zSwY9vAIPoRhSMaDWRCLJDPOrmJFMVCM3s7rTM6AKmPztlVB5P+nztZGXWOCRfBtz 7kpQ== X-Gm-Message-State: APjAAAV6YCfSGTkf1/dwmYfNdUZxToZ5zNa2GlMZd7xWbAUS0Eexw6Ma 1YuRGMo7v8qN6VB5V0BS0RU= X-Google-Smtp-Source: APXvYqxpx5VONZZMdLqSroCuHbE6BH9Rd3clDwrowABSUBtP+YUH+S3IPSsfGnO/djWOf39TRGfdqQ== X-Received: by 2002:a17:902:2ba7:: with SMTP id l36mr69293700plb.237.1554186652921; Mon, 01 Apr 2019 23:30:52 -0700 (PDT) Received: from localhost.localdomain ([2001:268:c0a5:4ce0:c70:4af9:86e2:2]) by smtp.gmail.com with ESMTPSA id a17sm19327289pfj.123.2019.04.01.23.30.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Apr 2019 23:30:52 -0700 (PDT) From: William Breathitt Gray To: gregkh@linuxfoundation.org Subject: [PATCH v10 04/18] iio: 104-quad-8: Update license boilerplate Date: Tue, 2 Apr 2019 15:30:39 +0900 Message-Id: X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190401_233054_022240_DBD79E8C X-CRM114-Status: GOOD ( 14.00 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, benjamin.gaignard@st.com, linux-pwm@vger.kernel.org, linux-iio@vger.kernel.org, patrick.havelange@essensium.com, thierry.reding@gmail.com, pmeerw@pmeerw.net, lars@metafoo.de, daniel.lezcano@linaro.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, david@lechnology.com, William Breathitt Gray , robh+dt@kernel.org, tglx@linutronix.de, fabrice.gasnier@st.com, esben@haabendal.dk, shawnguo@kernel.org, linux-kernel@vger.kernel.org, leoyang.li@nxp.com, knaack.h@gmx.de, akpm@linux-foundation.org, linuxppc-dev@lists.ozlabs.org, jic23@kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP This patch simplifies the boilerplate license text by making use of a SPDX license identifier line. Signed-off-by: William Breathitt Gray --- drivers/iio/counter/104-quad-8.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/iio/counter/104-quad-8.c b/drivers/iio/counter/104-quad-8.c index 92be8d0f7735..72b6352e09f0 100644 --- a/drivers/iio/counter/104-quad-8.c +++ b/drivers/iio/counter/104-quad-8.c @@ -1,16 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * IIO driver for the ACCES 104-QUAD-8 * Copyright (C) 2016 William Breathitt Gray * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * * This driver supports the ACCES 104-QUAD-8 and ACCES 104-QUAD-4. */ #include From patchwork Tue Apr 2 06:30:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Breathitt Gray X-Patchwork-Id: 10881087 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AB0FD1669 for ; Tue, 2 Apr 2019 06:31:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8BE4928770 for ; Tue, 2 Apr 2019 06:31:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7F16D28843; Tue, 2 Apr 2019 06:31:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0041E28770 for ; Tue, 2 Apr 2019 06:31:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=X4qT+NUzRcl+wnAb4HT0BYRDyA9On3eWhmupwSPdigg=; b=YkTMvNRaZUbMu0 lkQD5TVregXStc3xoG33WVVre1XsnybUSixqwiWx2MGrwxIvSLvrVXiapNOKj43VAAuD1kIhKr257 UyeHuEhDZ2SJoDbF2rlh+Tl/FxeA0hjAuC86VIheCaAl4XYjm3wc/Aj+ca1PTLC66/gArIxzG0agj NBa/1Lv8h4dm84yI1al1EUZiFLaat9s7ybuK/0LqLEXqyiyajTT9GHFgtwehy0c0oZ/HwFtU2tnaz qST0Kxrv2/6XbdS3YvkM56eHxxD8RDQ7EXqNpF8oeYyD+Pw4s+iCY417bxcMcVvAI5+UmyPM97y4J 0TWtW/2IX2Y0rC45oo5A==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCxa-0000w3-2W; Tue, 02 Apr 2019 06:31:50 +0000 Received: from mail-pf1-x442.google.com ([2607:f8b0:4864:20::442]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCwp-00006f-Kh for linux-arm-kernel@lists.infradead.org; Tue, 02 Apr 2019 06:31:47 +0000 Received: by mail-pf1-x442.google.com with SMTP id b3so5835553pfd.1 for ; Mon, 01 Apr 2019 23:31:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=65FoC5R5sHm7UC7zdR+nsyTyoYObd2MXSPZT6ix4JFU=; b=bJNJmMHlybVk8PPWSwxTi8BaIHZ2V6iVPioYmMdEfoHwd80x/OciT5/KhynQCoZEo4 Qk3/gyRO2Jwvt/TLO7BtZPH0D6L9Ea2v9XRGsIUHVZhdbKTnVwLNYZKKX3DmZYPBpyMD +ppMdYVy9v8wfF9ko6u88ApzP9oStSYxV70oR4MvONa2ZwWz4L4/VwuyXS2XJOixHmco Yg8bfk0Gqpkjs+BFYEXEIPuXnljF41WhGm6ecvRrovnwodJscQcB7pKUpl3t7BbHSgda 1lwlVYdVwFjWCwIpF3Ni6EHmiMsGRN1uxXjJ3EDTGLFjmTromNBju+wX6HXiDr1dY1PK VkCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=65FoC5R5sHm7UC7zdR+nsyTyoYObd2MXSPZT6ix4JFU=; b=QY4kD4UviM/USyPxAdejj/T2ueyXyhy47YeN/2tWOrXJxOXS+X/N7kTaQqjxFAf0g4 vcJqIs618q1yMEu/FBualX5wToSyNCA/qUtoQvPPo8053dvOUZ5FBCNrVTQMqb6GaZM+ 6zutayckVYGe8HOswvySwJcWASzD+3DtqbuxKLCKYbvsuP/KXk6IcMNdW7WJR9cyyThT BZ04bx+Jz1UB+piMCYywbACYq0QacBQ/18pBURfj86fz+yinMom/HPeRYGZJsXFpS2aM BBRZElFJHMNnB8OuLc2zR8sIwTn5qJq/5gBzEbXmrYl2N2i/aAgqB8Sh5ot4d0+kHX5N DegA== X-Gm-Message-State: APjAAAU9oTuwGY88CTKoKZrxSMN8g2q+tqV14oBfXqfJK503f+RxNLDJ KTjUVVg9qbcefsUneUuEj8Q= X-Google-Smtp-Source: APXvYqxXmYSNKGV+f3v+Xk6Os5mofrniKjHKZHDB0PAMzQpnFtn+fhwwq5gwB8grCB9C1402juzY0g== X-Received: by 2002:a63:5a4b:: with SMTP id k11mr64419744pgm.119.1554186662700; Mon, 01 Apr 2019 23:31:02 -0700 (PDT) Received: from localhost.localdomain ([2001:268:c0a5:4ce0:c70:4af9:86e2:2]) by smtp.gmail.com with ESMTPSA id a17sm19327289pfj.123.2019.04.01.23.30.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Apr 2019 23:31:01 -0700 (PDT) From: William Breathitt Gray To: gregkh@linuxfoundation.org Subject: [PATCH v10 05/18] counter: 104-quad-8: Add Generic Counter interface support Date: Tue, 2 Apr 2019 15:30:40 +0900 Message-Id: X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190401_233104_231142_0661DD1A X-CRM114-Status: GOOD ( 23.04 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, benjamin.gaignard@st.com, linux-pwm@vger.kernel.org, linux-iio@vger.kernel.org, patrick.havelange@essensium.com, thierry.reding@gmail.com, pmeerw@pmeerw.net, lars@metafoo.de, daniel.lezcano@linaro.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, david@lechnology.com, William Breathitt Gray , robh+dt@kernel.org, Jonathan Cameron , tglx@linutronix.de, fabrice.gasnier@st.com, esben@haabendal.dk, shawnguo@kernel.org, linux-kernel@vger.kernel.org, leoyang.li@nxp.com, knaack.h@gmx.de, akpm@linux-foundation.org, linuxppc-dev@lists.ozlabs.org, jic23@kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds support for the Generic Counter interface to the 104-QUAD-8 driver. The existing 104-QUAD-8 device interface should not be affected by this patch; all changes are intended as supplemental additions as perceived by the user. Generic Counter Counts are created for the eight quadrature channel counts, as well as their respective quadrature A and B Signals (which are associated via respective Synapse structures) and respective index Signals. The new Generic Counter interface sysfs attributes are intended to expose the same functionality and data available via the existing 104-QUAD-8 IIO device interface; the Generic Counter interface serves to provide the respective functionality and data in a standard way expected of counter devices. Reviewed-by: Jonathan Cameron Signed-off-by: William Breathitt Gray --- MAINTAINERS | 4 +- drivers/{iio => }/counter/104-quad-8.c | 772 ++++++++++++++++++++++++- drivers/counter/Kconfig | 21 + drivers/counter/Makefile | 2 + drivers/iio/counter/Kconfig | 17 - drivers/iio/counter/Makefile | 1 - 6 files changed, 783 insertions(+), 34 deletions(-) rename drivers/{iio => }/counter/104-quad-8.c (44%) diff --git a/MAINTAINERS b/MAINTAINERS index 208c92ff4801..663e7a62752a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -268,12 +268,12 @@ L: linux-gpio@vger.kernel.org S: Maintained F: drivers/gpio/gpio-104-idio-16.c -ACCES 104-QUAD-8 IIO DRIVER +ACCES 104-QUAD-8 DRIVER M: William Breathitt Gray L: linux-iio@vger.kernel.org S: Maintained F: Documentation/ABI/testing/sysfs-bus-iio-counter-104-quad-8 -F: drivers/iio/counter/104-quad-8.c +F: drivers/counter/104-quad-8.c ACCES PCI-IDIO-16 GPIO DRIVER M: William Breathitt Gray diff --git a/drivers/iio/counter/104-quad-8.c b/drivers/counter/104-quad-8.c similarity index 44% rename from drivers/iio/counter/104-quad-8.c rename to drivers/counter/104-quad-8.c index 72b6352e09f0..4fa2931dcb7b 100644 --- a/drivers/iio/counter/104-quad-8.c +++ b/drivers/counter/104-quad-8.c @@ -1,11 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 /* - * IIO driver for the ACCES 104-QUAD-8 + * Counter driver for the ACCES 104-QUAD-8 * Copyright (C) 2016 William Breathitt Gray * * This driver supports the ACCES 104-QUAD-8 and ACCES 104-QUAD-4. */ #include +#include #include #include #include @@ -29,6 +30,7 @@ MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses"); /** * struct quad8_iio - IIO device private data structure + * @counter: instance of the counter_device * @preset: array of preset values * @count_mode: array of count mode configurations * @quadrature_mode: array of quadrature mode configurations @@ -40,6 +42,7 @@ MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses"); * @base: base port address of the IIO device */ struct quad8_iio { + struct counter_device counter; unsigned int preset[QUAD8_NUM_COUNTERS]; unsigned int count_mode[QUAD8_NUM_COUNTERS]; unsigned int quadrature_mode[QUAD8_NUM_COUNTERS]; @@ -83,6 +86,10 @@ struct quad8_iio { #define QUAD8_RLD_CNTR_OUT 0x10 #define QUAD8_CHAN_OP_ENABLE_COUNTERS 0x00 #define QUAD8_CHAN_OP_RESET_COUNTERS 0x01 +#define QUAD8_CMR_QUADRATURE_X1 0x08 +#define QUAD8_CMR_QUADRATURE_X2 0x10 +#define QUAD8_CMR_QUADRATURE_X4 0x18 + static int quad8_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -338,13 +345,13 @@ static const char *const quad8_count_modes[] = { }; static int quad8_set_count_mode(struct iio_dev *indio_dev, - const struct iio_chan_spec *chan, unsigned int count_mode) + const struct iio_chan_spec *chan, unsigned int cnt_mode) { struct quad8_iio *const priv = iio_priv(indio_dev); - unsigned int mode_cfg = count_mode << 1; + unsigned int mode_cfg = cnt_mode << 1; const int base_offset = priv->base + 2 * chan->channel + 1; - priv->count_mode[chan->channel] = count_mode; + priv->count_mode[chan->channel] = cnt_mode; /* Add quadrature mode configuration */ if (priv->quadrature_mode[chan->channel]) @@ -554,24 +561,746 @@ static const struct iio_chan_spec quad8_channels[] = { QUAD8_COUNT_CHAN(7), QUAD8_INDEX_CHAN(7) }; +static int quad8_signal_read(struct counter_device *counter, + struct counter_signal *signal, struct counter_signal_read_value *val) +{ + const struct quad8_iio *const priv = counter->priv; + unsigned int state; + enum counter_signal_level level; + + /* Only Index signal levels can be read */ + if (signal->id < 16) + return -EINVAL; + + state = inb(priv->base + QUAD8_REG_INDEX_INPUT_LEVELS) + & BIT(signal->id - 16); + + level = (state) ? COUNTER_SIGNAL_LEVEL_HIGH : COUNTER_SIGNAL_LEVEL_LOW; + + counter_signal_read_value_set(val, COUNTER_SIGNAL_LEVEL, &level); + + return 0; +} + +static int quad8_count_read(struct counter_device *counter, + struct counter_count *count, struct counter_count_read_value *val) +{ + const struct quad8_iio *const priv = counter->priv; + const int base_offset = priv->base + 2 * count->id; + unsigned int flags; + unsigned int borrow; + unsigned int carry; + unsigned long position; + int i; + + flags = inb(base_offset + 1); + borrow = flags & QUAD8_FLAG_BT; + carry = !!(flags & QUAD8_FLAG_CT); + + /* Borrow XOR Carry effectively doubles count range */ + position = (unsigned long)(borrow ^ carry) << 24; + + /* Reset Byte Pointer; transfer Counter to Output Latch */ + outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_CNTR_OUT, + base_offset + 1); + + for (i = 0; i < 3; i++) + position |= (unsigned long)inb(base_offset) << (8 * i); + + counter_count_read_value_set(val, COUNTER_COUNT_POSITION, &position); + + return 0; +} + +static int quad8_count_write(struct counter_device *counter, + struct counter_count *count, struct counter_count_write_value *val) +{ + const struct quad8_iio *const priv = counter->priv; + const int base_offset = priv->base + 2 * count->id; + int err; + unsigned long position; + int i; + + err = counter_count_write_value_get(&position, COUNTER_COUNT_POSITION, + val); + if (err) + return err; + + /* Only 24-bit values are supported */ + if (position > 0xFFFFFF) + return -EINVAL; + + /* Reset Byte Pointer */ + outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1); + + /* Counter can only be set via Preset Register */ + for (i = 0; i < 3; i++) + outb(position >> (8 * i), base_offset); + + /* Transfer Preset Register to Counter */ + outb(QUAD8_CTR_RLD | QUAD8_RLD_PRESET_CNTR, base_offset + 1); + + /* Reset Byte Pointer */ + outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1); + + /* Set Preset Register back to original value */ + position = priv->preset[count->id]; + for (i = 0; i < 3; i++) + outb(position >> (8 * i), base_offset); + + /* Reset Borrow, Carry, Compare, and Sign flags */ + outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_FLAGS, base_offset + 1); + /* Reset Error flag */ + outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, base_offset + 1); + + return 0; +} + +enum quad8_count_function { + QUAD8_COUNT_FUNCTION_PULSE_DIRECTION = 0, + QUAD8_COUNT_FUNCTION_QUADRATURE_X1, + QUAD8_COUNT_FUNCTION_QUADRATURE_X2, + QUAD8_COUNT_FUNCTION_QUADRATURE_X4 +}; + +static enum counter_count_function quad8_count_functions_list[] = { + [QUAD8_COUNT_FUNCTION_PULSE_DIRECTION] = COUNTER_COUNT_FUNCTION_PULSE_DIRECTION, + [QUAD8_COUNT_FUNCTION_QUADRATURE_X1] = COUNTER_COUNT_FUNCTION_QUADRATURE_X1_A, + [QUAD8_COUNT_FUNCTION_QUADRATURE_X2] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A, + [QUAD8_COUNT_FUNCTION_QUADRATURE_X4] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4 +}; + +static int quad8_function_get(struct counter_device *counter, + struct counter_count *count, size_t *function) +{ + const struct quad8_iio *const priv = counter->priv; + const int id = count->id; + const unsigned int quadrature_mode = priv->quadrature_mode[id]; + const unsigned int scale = priv->quadrature_scale[id]; + + if (quadrature_mode) + switch (scale) { + case 0: + *function = QUAD8_COUNT_FUNCTION_QUADRATURE_X1; + break; + case 1: + *function = QUAD8_COUNT_FUNCTION_QUADRATURE_X2; + break; + case 2: + *function = QUAD8_COUNT_FUNCTION_QUADRATURE_X4; + break; + } + else + *function = QUAD8_COUNT_FUNCTION_PULSE_DIRECTION; + + return 0; +} + +static int quad8_function_set(struct counter_device *counter, + struct counter_count *count, size_t function) +{ + struct quad8_iio *const priv = counter->priv; + const int id = count->id; + unsigned int *const quadrature_mode = priv->quadrature_mode + id; + unsigned int *const scale = priv->quadrature_scale + id; + unsigned int mode_cfg = priv->count_mode[id] << 1; + unsigned int *const synchronous_mode = priv->synchronous_mode + id; + const unsigned int idr_cfg = priv->index_polarity[id] << 1; + const int base_offset = priv->base + 2 * id + 1; + + if (function == QUAD8_COUNT_FUNCTION_PULSE_DIRECTION) { + *quadrature_mode = 0; + + /* Quadrature scaling only available in quadrature mode */ + *scale = 0; + + /* Synchronous function not supported in non-quadrature mode */ + if (*synchronous_mode) { + *synchronous_mode = 0; + /* Disable synchronous function mode */ + outb(QUAD8_CTR_IDR | idr_cfg, base_offset); + } + } else { + *quadrature_mode = 1; + + switch (function) { + case QUAD8_COUNT_FUNCTION_QUADRATURE_X1: + *scale = 0; + mode_cfg |= QUAD8_CMR_QUADRATURE_X1; + break; + case QUAD8_COUNT_FUNCTION_QUADRATURE_X2: + *scale = 1; + mode_cfg |= QUAD8_CMR_QUADRATURE_X2; + break; + case QUAD8_COUNT_FUNCTION_QUADRATURE_X4: + *scale = 2; + mode_cfg |= QUAD8_CMR_QUADRATURE_X4; + break; + } + } + + /* Load mode configuration to Counter Mode Register */ + outb(QUAD8_CTR_CMR | mode_cfg, base_offset); + + return 0; +} + +static void quad8_direction_get(struct counter_device *counter, + struct counter_count *count, enum counter_count_direction *direction) +{ + const struct quad8_iio *const priv = counter->priv; + unsigned int ud_flag; + const unsigned int flag_addr = priv->base + 2 * count->id + 1; + + /* U/D flag: nonzero = up, zero = down */ + ud_flag = inb(flag_addr) & QUAD8_FLAG_UD; + + *direction = (ud_flag) ? COUNTER_COUNT_DIRECTION_FORWARD : + COUNTER_COUNT_DIRECTION_BACKWARD; +} + +enum quad8_synapse_action { + QUAD8_SYNAPSE_ACTION_NONE = 0, + QUAD8_SYNAPSE_ACTION_RISING_EDGE, + QUAD8_SYNAPSE_ACTION_FALLING_EDGE, + QUAD8_SYNAPSE_ACTION_BOTH_EDGES +}; + +static enum counter_synapse_action quad8_index_actions_list[] = { + [QUAD8_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE, + [QUAD8_SYNAPSE_ACTION_RISING_EDGE] = COUNTER_SYNAPSE_ACTION_RISING_EDGE +}; + +static enum counter_synapse_action quad8_synapse_actions_list[] = { + [QUAD8_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE, + [QUAD8_SYNAPSE_ACTION_RISING_EDGE] = COUNTER_SYNAPSE_ACTION_RISING_EDGE, + [QUAD8_SYNAPSE_ACTION_FALLING_EDGE] = COUNTER_SYNAPSE_ACTION_FALLING_EDGE, + [QUAD8_SYNAPSE_ACTION_BOTH_EDGES] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES +}; + +static int quad8_action_get(struct counter_device *counter, + struct counter_count *count, struct counter_synapse *synapse, + size_t *action) +{ + struct quad8_iio *const priv = counter->priv; + int err; + size_t function = 0; + const size_t signal_a_id = count->synapses[0].signal->id; + enum counter_count_direction direction; + + /* Handle Index signals */ + if (synapse->signal->id >= 16) { + if (priv->preset_enable[count->id]) + *action = QUAD8_SYNAPSE_ACTION_RISING_EDGE; + else + *action = QUAD8_SYNAPSE_ACTION_NONE; + + return 0; + } + + err = quad8_function_get(counter, count, &function); + if (err) + return err; + + /* Default action mode */ + *action = QUAD8_SYNAPSE_ACTION_NONE; + + /* Determine action mode based on current count function mode */ + switch (function) { + case QUAD8_COUNT_FUNCTION_PULSE_DIRECTION: + if (synapse->signal->id == signal_a_id) + *action = QUAD8_SYNAPSE_ACTION_RISING_EDGE; + break; + case QUAD8_COUNT_FUNCTION_QUADRATURE_X1: + if (synapse->signal->id == signal_a_id) { + quad8_direction_get(counter, count, &direction); + + if (direction == COUNTER_COUNT_DIRECTION_FORWARD) + *action = QUAD8_SYNAPSE_ACTION_RISING_EDGE; + else + *action = QUAD8_SYNAPSE_ACTION_FALLING_EDGE; + } + break; + case QUAD8_COUNT_FUNCTION_QUADRATURE_X2: + if (synapse->signal->id == signal_a_id) + *action = QUAD8_SYNAPSE_ACTION_BOTH_EDGES; + break; + case QUAD8_COUNT_FUNCTION_QUADRATURE_X4: + *action = QUAD8_SYNAPSE_ACTION_BOTH_EDGES; + break; + } + + return 0; +} + +const struct counter_ops quad8_ops = { + .signal_read = quad8_signal_read, + .count_read = quad8_count_read, + .count_write = quad8_count_write, + .function_get = quad8_function_get, + .function_set = quad8_function_set, + .action_get = quad8_action_get +}; + +static int quad8_index_polarity_get(struct counter_device *counter, + struct counter_signal *signal, size_t *index_polarity) +{ + const struct quad8_iio *const priv = counter->priv; + const size_t channel_id = signal->id - 16; + + *index_polarity = priv->index_polarity[channel_id]; + + return 0; +} + +static int quad8_index_polarity_set(struct counter_device *counter, + struct counter_signal *signal, size_t index_polarity) +{ + struct quad8_iio *const priv = counter->priv; + const size_t channel_id = signal->id - 16; + const unsigned int idr_cfg = priv->synchronous_mode[channel_id] | + index_polarity << 1; + const int base_offset = priv->base + 2 * channel_id + 1; + + priv->index_polarity[channel_id] = index_polarity; + + /* Load Index Control configuration to Index Control Register */ + outb(QUAD8_CTR_IDR | idr_cfg, base_offset); + + return 0; +} + +static struct counter_signal_enum_ext quad8_index_pol_enum = { + .items = quad8_index_polarity_modes, + .num_items = ARRAY_SIZE(quad8_index_polarity_modes), + .get = quad8_index_polarity_get, + .set = quad8_index_polarity_set +}; + +static int quad8_synchronous_mode_get(struct counter_device *counter, + struct counter_signal *signal, size_t *synchronous_mode) +{ + const struct quad8_iio *const priv = counter->priv; + const size_t channel_id = signal->id - 16; + + *synchronous_mode = priv->synchronous_mode[channel_id]; + + return 0; +} + +static int quad8_synchronous_mode_set(struct counter_device *counter, + struct counter_signal *signal, size_t synchronous_mode) +{ + struct quad8_iio *const priv = counter->priv; + const size_t channel_id = signal->id - 16; + const unsigned int idr_cfg = synchronous_mode | + priv->index_polarity[channel_id] << 1; + const int base_offset = priv->base + 2 * channel_id + 1; + + /* Index function must be non-synchronous in non-quadrature mode */ + if (synchronous_mode && !priv->quadrature_mode[channel_id]) + return -EINVAL; + + priv->synchronous_mode[channel_id] = synchronous_mode; + + /* Load Index Control configuration to Index Control Register */ + outb(QUAD8_CTR_IDR | idr_cfg, base_offset); + + return 0; +} + +static struct counter_signal_enum_ext quad8_syn_mode_enum = { + .items = quad8_synchronous_modes, + .num_items = ARRAY_SIZE(quad8_synchronous_modes), + .get = quad8_synchronous_mode_get, + .set = quad8_synchronous_mode_set +}; + +static ssize_t quad8_count_floor_read(struct counter_device *counter, + struct counter_count *count, void *private, char *buf) +{ + /* Only a floor of 0 is supported */ + return sprintf(buf, "0\n"); +} + +static int quad8_count_mode_get(struct counter_device *counter, + struct counter_count *count, size_t *cnt_mode) +{ + const struct quad8_iio *const priv = counter->priv; + + /* Map 104-QUAD-8 count mode to Generic Counter count mode */ + switch (priv->count_mode[count->id]) { + case 0: + *cnt_mode = COUNTER_COUNT_MODE_NORMAL; + break; + case 1: + *cnt_mode = COUNTER_COUNT_MODE_RANGE_LIMIT; + break; + case 2: + *cnt_mode = COUNTER_COUNT_MODE_NON_RECYCLE; + break; + case 3: + *cnt_mode = COUNTER_COUNT_MODE_MODULO_N; + break; + } + + return 0; +} + +static int quad8_count_mode_set(struct counter_device *counter, + struct counter_count *count, size_t cnt_mode) +{ + struct quad8_iio *const priv = counter->priv; + unsigned int mode_cfg; + const int base_offset = priv->base + 2 * count->id + 1; + + /* Map Generic Counter count mode to 104-QUAD-8 count mode */ + switch (cnt_mode) { + case COUNTER_COUNT_MODE_NORMAL: + cnt_mode = 0; + break; + case COUNTER_COUNT_MODE_RANGE_LIMIT: + cnt_mode = 1; + break; + case COUNTER_COUNT_MODE_NON_RECYCLE: + cnt_mode = 2; + break; + case COUNTER_COUNT_MODE_MODULO_N: + cnt_mode = 3; + break; + } + + priv->count_mode[count->id] = cnt_mode; + + /* Set count mode configuration value */ + mode_cfg = cnt_mode << 1; + + /* Add quadrature mode configuration */ + if (priv->quadrature_mode[count->id]) + mode_cfg |= (priv->quadrature_scale[count->id] + 1) << 3; + + /* Load mode configuration to Counter Mode Register */ + outb(QUAD8_CTR_CMR | mode_cfg, base_offset); + + return 0; +} + +static struct counter_count_enum_ext quad8_cnt_mode_enum = { + .items = counter_count_mode_str, + .num_items = ARRAY_SIZE(counter_count_mode_str), + .get = quad8_count_mode_get, + .set = quad8_count_mode_set +}; + +static ssize_t quad8_count_direction_read(struct counter_device *counter, + struct counter_count *count, void *priv, char *buf) +{ + enum counter_count_direction dir; + + quad8_direction_get(counter, count, &dir); + + return sprintf(buf, "%s\n", counter_count_direction_str[dir]); +} + +static ssize_t quad8_count_enable_read(struct counter_device *counter, + struct counter_count *count, void *private, char *buf) +{ + const struct quad8_iio *const priv = counter->priv; + + return sprintf(buf, "%u\n", priv->ab_enable[count->id]); +} + +static ssize_t quad8_count_enable_write(struct counter_device *counter, + struct counter_count *count, void *private, const char *buf, size_t len) +{ + struct quad8_iio *const priv = counter->priv; + const int base_offset = priv->base + 2 * count->id; + int err; + bool ab_enable; + unsigned int ior_cfg; + + err = kstrtobool(buf, &ab_enable); + if (err) + return err; + + priv->ab_enable[count->id] = ab_enable; + + ior_cfg = ab_enable | priv->preset_enable[count->id] << 1; + + /* Load I/O control configuration */ + outb(QUAD8_CTR_IOR | ior_cfg, base_offset + 1); + + return len; +} + +static int quad8_error_noise_get(struct counter_device *counter, + struct counter_count *count, size_t *noise_error) +{ + const struct quad8_iio *const priv = counter->priv; + const int base_offset = priv->base + 2 * count->id + 1; + + *noise_error = !!(inb(base_offset) & QUAD8_FLAG_E); + + return 0; +} + +static struct counter_count_enum_ext quad8_error_noise_enum = { + .items = quad8_noise_error_states, + .num_items = ARRAY_SIZE(quad8_noise_error_states), + .get = quad8_error_noise_get +}; + +static ssize_t quad8_count_preset_read(struct counter_device *counter, + struct counter_count *count, void *private, char *buf) +{ + const struct quad8_iio *const priv = counter->priv; + + return sprintf(buf, "%u\n", priv->preset[count->id]); +} + +static ssize_t quad8_count_preset_write(struct counter_device *counter, + struct counter_count *count, void *private, const char *buf, size_t len) +{ + struct quad8_iio *const priv = counter->priv; + const int base_offset = priv->base + 2 * count->id; + unsigned int preset; + int ret; + int i; + + ret = kstrtouint(buf, 0, &preset); + if (ret) + return ret; + + /* Only 24-bit values are supported */ + if (preset > 0xFFFFFF) + return -EINVAL; + + priv->preset[count->id] = preset; + + /* Reset Byte Pointer */ + outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1); + + /* Set Preset Register */ + for (i = 0; i < 3; i++) + outb(preset >> (8 * i), base_offset); + + return len; +} + +static ssize_t quad8_count_ceiling_read(struct counter_device *counter, + struct counter_count *count, void *private, char *buf) +{ + const struct quad8_iio *const priv = counter->priv; + + /* Range Limit and Modulo-N count modes use preset value as ceiling */ + switch (priv->count_mode[count->id]) { + case 1: + case 3: + return quad8_count_preset_read(counter, count, private, buf); + } + + /* By default 0x1FFFFFF (25 bits unsigned) is maximum count */ + return sprintf(buf, "33554431\n"); +} + +static ssize_t quad8_count_ceiling_write(struct counter_device *counter, + struct counter_count *count, void *private, const char *buf, size_t len) +{ + struct quad8_iio *const priv = counter->priv; + + /* Range Limit and Modulo-N count modes use preset value as ceiling */ + switch (priv->count_mode[count->id]) { + case 1: + case 3: + return quad8_count_preset_write(counter, count, private, buf, + len); + } + + return len; +} + +static ssize_t quad8_count_preset_enable_read(struct counter_device *counter, + struct counter_count *count, void *private, char *buf) +{ + const struct quad8_iio *const priv = counter->priv; + + return sprintf(buf, "%u\n", !priv->preset_enable[count->id]); +} + +static ssize_t quad8_count_preset_enable_write(struct counter_device *counter, + struct counter_count *count, void *private, const char *buf, size_t len) +{ + struct quad8_iio *const priv = counter->priv; + const int base_offset = priv->base + 2 * count->id + 1; + bool preset_enable; + int ret; + unsigned int ior_cfg; + + ret = kstrtobool(buf, &preset_enable); + if (ret) + return ret; + + /* Preset enable is active low in Input/Output Control register */ + preset_enable = !preset_enable; + + priv->preset_enable[count->id] = preset_enable; + + ior_cfg = priv->ab_enable[count->id] | (unsigned int)preset_enable << 1; + + /* Load I/O control configuration to Input / Output Control Register */ + outb(QUAD8_CTR_IOR | ior_cfg, base_offset); + + return len; +} + +static const struct counter_signal_ext quad8_index_ext[] = { + COUNTER_SIGNAL_ENUM("index_polarity", &quad8_index_pol_enum), + COUNTER_SIGNAL_ENUM_AVAILABLE("index_polarity", &quad8_index_pol_enum), + COUNTER_SIGNAL_ENUM("synchronous_mode", &quad8_syn_mode_enum), + COUNTER_SIGNAL_ENUM_AVAILABLE("synchronous_mode", &quad8_syn_mode_enum) +}; + +#define QUAD8_QUAD_SIGNAL(_id, _name) { \ + .id = (_id), \ + .name = (_name) \ +} + +#define QUAD8_INDEX_SIGNAL(_id, _name) { \ + .id = (_id), \ + .name = (_name), \ + .ext = quad8_index_ext, \ + .num_ext = ARRAY_SIZE(quad8_index_ext) \ +} + +static struct counter_signal quad8_signals[] = { + QUAD8_QUAD_SIGNAL(0, "Channel 1 Quadrature A"), + QUAD8_QUAD_SIGNAL(1, "Channel 1 Quadrature B"), + QUAD8_QUAD_SIGNAL(2, "Channel 2 Quadrature A"), + QUAD8_QUAD_SIGNAL(3, "Channel 2 Quadrature B"), + QUAD8_QUAD_SIGNAL(4, "Channel 3 Quadrature A"), + QUAD8_QUAD_SIGNAL(5, "Channel 3 Quadrature B"), + QUAD8_QUAD_SIGNAL(6, "Channel 4 Quadrature A"), + QUAD8_QUAD_SIGNAL(7, "Channel 4 Quadrature B"), + QUAD8_QUAD_SIGNAL(8, "Channel 5 Quadrature A"), + QUAD8_QUAD_SIGNAL(9, "Channel 5 Quadrature B"), + QUAD8_QUAD_SIGNAL(10, "Channel 6 Quadrature A"), + QUAD8_QUAD_SIGNAL(11, "Channel 6 Quadrature B"), + QUAD8_QUAD_SIGNAL(12, "Channel 7 Quadrature A"), + QUAD8_QUAD_SIGNAL(13, "Channel 7 Quadrature B"), + QUAD8_QUAD_SIGNAL(14, "Channel 8 Quadrature A"), + QUAD8_QUAD_SIGNAL(15, "Channel 8 Quadrature B"), + QUAD8_INDEX_SIGNAL(16, "Channel 1 Index"), + QUAD8_INDEX_SIGNAL(17, "Channel 2 Index"), + QUAD8_INDEX_SIGNAL(18, "Channel 3 Index"), + QUAD8_INDEX_SIGNAL(19, "Channel 4 Index"), + QUAD8_INDEX_SIGNAL(20, "Channel 5 Index"), + QUAD8_INDEX_SIGNAL(21, "Channel 6 Index"), + QUAD8_INDEX_SIGNAL(22, "Channel 7 Index"), + QUAD8_INDEX_SIGNAL(23, "Channel 8 Index") +}; + +#define QUAD8_COUNT_SYNAPSES(_id) { \ + { \ + .actions_list = quad8_synapse_actions_list, \ + .num_actions = ARRAY_SIZE(quad8_synapse_actions_list), \ + .signal = quad8_signals + 2 * (_id) \ + }, \ + { \ + .actions_list = quad8_synapse_actions_list, \ + .num_actions = ARRAY_SIZE(quad8_synapse_actions_list), \ + .signal = quad8_signals + 2 * (_id) + 1 \ + }, \ + { \ + .actions_list = quad8_index_actions_list, \ + .num_actions = ARRAY_SIZE(quad8_index_actions_list), \ + .signal = quad8_signals + 2 * (_id) + 16 \ + } \ +} + +static struct counter_synapse quad8_count_synapses[][3] = { + QUAD8_COUNT_SYNAPSES(0), QUAD8_COUNT_SYNAPSES(1), + QUAD8_COUNT_SYNAPSES(2), QUAD8_COUNT_SYNAPSES(3), + QUAD8_COUNT_SYNAPSES(4), QUAD8_COUNT_SYNAPSES(5), + QUAD8_COUNT_SYNAPSES(6), QUAD8_COUNT_SYNAPSES(7) +}; + +static const struct counter_count_ext quad8_count_ext[] = { + { + .name = "ceiling", + .read = quad8_count_ceiling_read, + .write = quad8_count_ceiling_write + }, + { + .name = "floor", + .read = quad8_count_floor_read + }, + COUNTER_COUNT_ENUM("count_mode", &quad8_cnt_mode_enum), + COUNTER_COUNT_ENUM_AVAILABLE("count_mode", &quad8_cnt_mode_enum), + { + .name = "direction", + .read = quad8_count_direction_read + }, + { + .name = "enable", + .read = quad8_count_enable_read, + .write = quad8_count_enable_write + }, + COUNTER_COUNT_ENUM("error_noise", &quad8_error_noise_enum), + COUNTER_COUNT_ENUM_AVAILABLE("error_noise", &quad8_error_noise_enum), + { + .name = "preset", + .read = quad8_count_preset_read, + .write = quad8_count_preset_write + }, + { + .name = "preset_enable", + .read = quad8_count_preset_enable_read, + .write = quad8_count_preset_enable_write + } +}; + +#define QUAD8_COUNT(_id, _cntname) { \ + .id = (_id), \ + .name = (_cntname), \ + .functions_list = quad8_count_functions_list, \ + .num_functions = ARRAY_SIZE(quad8_count_functions_list), \ + .synapses = quad8_count_synapses[(_id)], \ + .num_synapses = 2, \ + .ext = quad8_count_ext, \ + .num_ext = ARRAY_SIZE(quad8_count_ext) \ +} + +static struct counter_count quad8_counts[] = { + QUAD8_COUNT(0, "Channel 1 Count"), + QUAD8_COUNT(1, "Channel 2 Count"), + QUAD8_COUNT(2, "Channel 3 Count"), + QUAD8_COUNT(3, "Channel 4 Count"), + QUAD8_COUNT(4, "Channel 5 Count"), + QUAD8_COUNT(5, "Channel 6 Count"), + QUAD8_COUNT(6, "Channel 7 Count"), + QUAD8_COUNT(7, "Channel 8 Count") +}; + static int quad8_probe(struct device *dev, unsigned int id) { struct iio_dev *indio_dev; - struct quad8_iio *priv; + struct quad8_iio *quad8iio; int i, j; unsigned int base_offset; + int err; - indio_dev = devm_iio_device_alloc(dev, sizeof(*priv)); - if (!indio_dev) - return -ENOMEM; - - if (!devm_request_region(dev, base[id], QUAD8_EXTENT, - dev_name(dev))) { + if (!devm_request_region(dev, base[id], QUAD8_EXTENT, dev_name(dev))) { dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", base[id], base[id] + QUAD8_EXTENT); return -EBUSY; } + /* Allocate IIO device; this also allocates driver data structure */ + indio_dev = devm_iio_device_alloc(dev, sizeof(*quad8iio)); + if (!indio_dev) + return -ENOMEM; + + /* Initialize IIO device */ indio_dev->info = &quad8_info; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->num_channels = ARRAY_SIZE(quad8_channels); @@ -579,8 +1308,17 @@ static int quad8_probe(struct device *dev, unsigned int id) indio_dev->name = dev_name(dev); indio_dev->dev.parent = dev; - priv = iio_priv(indio_dev); - priv->base = base[id]; + /* Initialize Counter device and driver data */ + quad8iio = iio_priv(indio_dev); + quad8iio->counter.name = dev_name(dev); + quad8iio->counter.parent = dev; + quad8iio->counter.ops = &quad8_ops; + quad8iio->counter.counts = quad8_counts; + quad8iio->counter.num_counts = ARRAY_SIZE(quad8_counts); + quad8iio->counter.signals = quad8_signals; + quad8iio->counter.num_signals = ARRAY_SIZE(quad8_signals); + quad8iio->counter.priv = quad8iio; + quad8iio->base = base[id]; /* Reset all counters and disable interrupt function */ outb(QUAD8_CHAN_OP_RESET_COUNTERS, base[id] + QUAD8_REG_CHAN_OP); @@ -606,7 +1344,13 @@ static int quad8_probe(struct device *dev, unsigned int id) /* Enable all counters */ outb(QUAD8_CHAN_OP_ENABLE_COUNTERS, base[id] + QUAD8_REG_CHAN_OP); - return devm_iio_device_register(dev, indio_dev); + /* Register IIO device */ + err = devm_iio_device_register(dev, indio_dev); + if (err) + return err; + + /* Register Counter device */ + return devm_counter_register(dev, &quad8iio->counter); } static struct isa_driver quad8_driver = { diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig index a74998400282..dd3add729529 100644 --- a/drivers/counter/Kconfig +++ b/drivers/counter/Kconfig @@ -8,3 +8,24 @@ menuconfig COUNTER This enables counter device support through the Generic Counter interface. You only need to enable this, if you also want to enable one or more of the counter device drivers below. + +if COUNTER + +config 104_QUAD_8 + tristate "ACCES 104-QUAD-8 driver" + depends on PC104 && X86 && IIO + select ISA_BUS_API + help + Say yes here to build support for the ACCES 104-QUAD-8 quadrature + encoder counter/interface device family (104-QUAD-8, 104-QUAD-4). + + A counter's respective error flag may be cleared by performing a write + operation on the respective count value attribute. Although the + 104-QUAD-8 counters have a 25-bit range, only the lower 24 bits may be + set, either directly or via the counter's preset attribute. Interrupts + are not supported by this driver. + + The base port addresses for the devices may be configured via the base + array module parameter. + +endif # COUNTER diff --git a/drivers/counter/Makefile b/drivers/counter/Makefile index b1464604bdbe..aee0d2ddcf2c 100644 --- a/drivers/counter/Makefile +++ b/drivers/counter/Makefile @@ -3,3 +3,5 @@ # obj-$(CONFIG_COUNTER) += counter.o + +obj-$(CONFIG_104_QUAD_8) += 104-quad-8.o diff --git a/drivers/iio/counter/Kconfig b/drivers/iio/counter/Kconfig index bf1e559ad7cd..eeb358122cbe 100644 --- a/drivers/iio/counter/Kconfig +++ b/drivers/iio/counter/Kconfig @@ -5,23 +5,6 @@ menu "Counters" -config 104_QUAD_8 - tristate "ACCES 104-QUAD-8 driver" - depends on PC104 && X86 - select ISA_BUS_API - help - Say yes here to build support for the ACCES 104-QUAD-8 quadrature - encoder counter/interface device family (104-QUAD-8, 104-QUAD-4). - - Performing a write to a counter's IIO_CHAN_INFO_RAW sets the counter and - also clears the counter's respective error flag. Although the counters - have a 25-bit range, only the lower 24 bits may be set, either directly - or via a counter's preset attribute. Interrupts are not supported by - this driver. - - The base port addresses for the devices may be configured via the base - array module parameter. - config STM32_LPTIMER_CNT tristate "STM32 LP Timer encoder counter driver" depends on MFD_STM32_LPTIMER || COMPILE_TEST diff --git a/drivers/iio/counter/Makefile b/drivers/iio/counter/Makefile index 1b9a896eb488..93933ba49280 100644 --- a/drivers/iio/counter/Makefile +++ b/drivers/iio/counter/Makefile @@ -4,5 +4,4 @@ # When adding new entries keep the list in alphabetical order -obj-$(CONFIG_104_QUAD_8) += 104-quad-8.o obj-$(CONFIG_STM32_LPTIMER_CNT) += stm32-lptimer-cnt.o From patchwork Tue Apr 2 06:30:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Breathitt Gray X-Patchwork-Id: 10881117 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C180D139A for ; Tue, 2 Apr 2019 06:37:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A7FEC28806 for ; Tue, 2 Apr 2019 06:37:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9BF61288AE; Tue, 2 Apr 2019 06:37:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D749F28806 for ; Tue, 2 Apr 2019 06:37:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=YW08ITvoOu9nxtokMOtvJashPu8ZOFf8Q2/67TTyb0Q=; b=TcOXVdo4EVLitq jR+UXZsP9MSnXra16WYSOtL25UsYflK9FilskgrntEriwn9xjgK2x3lf6Jpe59Nppsy93KNPDqwdo nAQxF9SDXYprvkiDPmL9OhRj71mF47rTgaXpR2lnl68ynpmNZA9H+qgL0JDsHLLmEB1XsCOzB6BK3 uyAs3OCny1GMC/AXQECfqF698N5Tm4lQDlDZrIfxqupcFy2NfMSlZt3oS0ZWY+Q9GfRJGIFenrgQf p/cvL5KLMI7DoYTuATwhAaBRzg8XJ4s9sTHk7MhenI/2S/k4ltUMW+e2U2J+5CwHTMqxeTe169YaW IkVMWvEcVGWu2qcFmSzA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBD2u-0004n8-F1; Tue, 02 Apr 2019 06:37:20 +0000 Received: from mail-pf1-x442.google.com ([2607:f8b0:4864:20::442]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCwz-0000J4-3e for linux-arm-kernel@lists.infradead.org; Tue, 02 Apr 2019 06:31:58 +0000 Received: by mail-pf1-x442.google.com with SMTP id 188so5830426pfd.8 for ; Mon, 01 Apr 2019 23:31:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=82SzGL+dDrDrdF7a/L+pw1B8d27zaqfl1K0+UvDKEBk=; b=AWkdkXjPM9jKJ/FBkzzrKCTtM2zDZLPz/0VBrzDEjZewLdw7S1N0/J/Wzm6Hd0cQUy SPks6JE8eIMbVvLb0a4OqQ4laWBi/BwsXRqP533Lb+0vI41q+QGUwG4sbygoaCqXhskQ EEibYKqbJtYLIKfvT/GXsTb7dWmC+XvWTJVy3B8nh9UBYyELUGqr4sefW9AeIQnvoTZt fguv9MXl6GgLQSpX9N+3qNMtRlo85Z9wxfDrd3O8CCDx/+Uh3+shxfZQSmcLhAiBm0Tw 2tDgU95OAvNv4jGaBP/zws7IDfZP+qwzkx83LEX1UDfrGYZVTz/WNbtysk6rw9eKttm5 8ZIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=82SzGL+dDrDrdF7a/L+pw1B8d27zaqfl1K0+UvDKEBk=; b=WoqdNrhOFtHRr3Avb5n1d1S+oGe3l0JksRsc5ACfyR0jzgQx3i4chNYVImwqXDrRE6 bKQiwY4tN7JxmPvPo1q/2yU+Yiqs1jPYG3Zb2z8evox/6yE2CkjRHTOviMjSZgzfKPlr JgqMbrVXc/mG/l5ndAgm4iEmeXiVOi93TD4tbJxLnkYowyEJmuDXNsjB/GemL7Cq6FDi ANQkQPp5JR7cS+fHi0RyGoc2ArOEg3EC1ayQMX1WFQgdd/LkEgQ0chVM4US2ALfkVJYL 2rXFs5N5bzzkqdR4ruIm3wCyC3YnKqB8wSKruXvhvyLwZ2oWEiXzbVig6E+YBU/2Flfj nxVQ== X-Gm-Message-State: APjAAAVs7lafh/+OAdfUW6l/6wzCX8StbcwfP1fc3XyNlR3RbPKtimA/ gj5jztNRuGMV9e48LDfQJz2v8a9YiL0= X-Google-Smtp-Source: APXvYqyVC7xYZcFOZlQSgA8iyuaZfJ8F7kWF1o5LWZdzWpAa7yMl07z/TP6hWXOLoe3zitewlsFYnw== X-Received: by 2002:aa7:8083:: with SMTP id v3mr50669006pff.135.1554186672607; Mon, 01 Apr 2019 23:31:12 -0700 (PDT) Received: from localhost.localdomain ([2001:268:c0a5:4ce0:c70:4af9:86e2:2]) by smtp.gmail.com with ESMTPSA id a17sm19327289pfj.123.2019.04.01.23.31.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Apr 2019 23:31:12 -0700 (PDT) From: William Breathitt Gray To: gregkh@linuxfoundation.org Subject: [PATCH v10 06/18] counter: 104-quad-8: Documentation: Add Generic Counter sysfs documentation Date: Tue, 2 Apr 2019 15:30:41 +0900 Message-Id: <90ea2b39df0194bcf6389802c1b6e22decdf2f8f.1554184734.git.vilhelm.gray@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190401_233113_765116_DD5A7D8B X-CRM114-Status: GOOD ( 13.62 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, benjamin.gaignard@st.com, linux-pwm@vger.kernel.org, linux-iio@vger.kernel.org, patrick.havelange@essensium.com, thierry.reding@gmail.com, pmeerw@pmeerw.net, lars@metafoo.de, daniel.lezcano@linaro.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, david@lechnology.com, William Breathitt Gray , robh+dt@kernel.org, Jonathan Cameron , tglx@linutronix.de, fabrice.gasnier@st.com, esben@haabendal.dk, shawnguo@kernel.org, linux-kernel@vger.kernel.org, leoyang.li@nxp.com, knaack.h@gmx.de, akpm@linux-foundation.org, linuxppc-dev@lists.ozlabs.org, jic23@kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds standard documentation for the Generic Counter interface userspace sysfs attributes of the 104-QUAD-8 driver. Acked-by: Jonathan Cameron Signed-off-by: William Breathitt Gray --- .../ABI/testing/sysfs-bus-counter-104-quad-8 | 36 +++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 37 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-counter-104-quad-8 diff --git a/Documentation/ABI/testing/sysfs-bus-counter-104-quad-8 b/Documentation/ABI/testing/sysfs-bus-counter-104-quad-8 new file mode 100644 index 000000000000..46b1f33b2fce --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-counter-104-quad-8 @@ -0,0 +1,36 @@ +What: /sys/bus/counter/devices/counterX/signalY/index_polarity +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Active level of index input Signal Y; irrelevant in + non-synchronous load mode. + +What: /sys/bus/counter/devices/counterX/signalY/index_polarity_available +What: /sys/bus/counter/devices/counterX/signalY/synchronous_mode_available +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Discrete set of available values for the respective Signal Y + configuration are listed in this file. + +What: /sys/bus/counter/devices/counterX/signalY/synchronous_mode +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Configure the counter associated with Signal Y for + non-synchronous or synchronous load mode. Synchronous load mode + cannot be selected in non-quadrature (Pulse-Direction) clock + mode. + + non-synchronous: + A logic low level is the active level at this index + input. The index function (as enabled via preset_enable) + is performed directly on the active level of the index + input. + + synchronous: + Intended for interfacing with encoder Index output in + quadrature clock mode. The active level is configured + via index_polarity. The index function (as enabled via + preset_enable) is performed synchronously with the + quadrature clock on the active level of the index input. diff --git a/MAINTAINERS b/MAINTAINERS index 663e7a62752a..d3d93a5d3b10 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -272,6 +272,7 @@ ACCES 104-QUAD-8 DRIVER M: William Breathitt Gray L: linux-iio@vger.kernel.org S: Maintained +F: Documentation/ABI/testing/sysfs-bus-counter-104-quad-8 F: Documentation/ABI/testing/sysfs-bus-iio-counter-104-quad-8 F: drivers/counter/104-quad-8.c From patchwork Tue Apr 2 06:30:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Breathitt Gray X-Patchwork-Id: 10881131 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7659813B5 for ; Tue, 2 Apr 2019 06:47:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 563CF28553 for ; Tue, 2 Apr 2019 06:47:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4820D28797; Tue, 2 Apr 2019 06:47:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 70D8728553 for ; Tue, 2 Apr 2019 06:47:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=cC0T8sqoc4zx79hxbwF6JAy+anEXqyXu7kC3yCqCkpo=; b=tyIiQiDqcpRHNa uHEP+DpjjWzO6Hw8Yl07d4PCoWA8iJKo6pPWAEngwQsKclKaY+6qKes7VqWm34V2TuEy8tIeE41nZ SW2YPEkC6vORQbYo2Wnc47eDZ2cTqLcA5ve7ZKgm/kSd6He5RtWSAOGlQfaMsaCjx6hEIetSHK+wt vDly3BDjX9EsvGkkSHtvpB+PWxJCBMlPceIeCOSrZdPW1FAmEcnlAAQxkrGue0xXF1giXfxDzNXNm 9Z0kjG9qxVBTqLI0mQXwS9grU7/OQCVa+2KhbG4Qj5dm0C7Pb8PpCdD1d5PrI/kymTzwcDyyvXzrF 9QWQm7rjMrUkNN+nNNlA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBDD0-0001PW-Jl; Tue, 02 Apr 2019 06:47:46 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBDCE-0008TY-Sh for linux-arm-kernel@bombadil.infradead.org; Tue, 02 Apr 2019 06:46:59 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=bsKrHycEMshfijbOx0t8uUYTp2zrrlI7D+SqxYWqME4=; b=tW5eqrF6jVZR43gBV6Mfx1/cuZ a2pBtPa9Zt0nt/8iazK9fciT39X2q6AujpCYw3hJhKfuluo3CpJfuW0j5LJBMqHChs6tfGG0CP5g9 bmJ32xbRmAfAIPHjEBJet4k+fr+hHaVDFi2U3ZazAaOj+PPYxw/EbZxz2l0iO0oflJM2HUBtcbSQu 7aryM7MPwfVVQW7UoP+FtvIVzM0qjDv0WWFruPBS6xlHAAJwe59vTAsT7/sqTlbHsdT6o4g/xejTs AbxULqcyzR+r4+t5ywCqJXxhy4w6kdyBCeXUSB6mrqx7dCNcu6YqNq+epI6T1j9SdXhoaVuiUop22 G8vkX6nA==; Received: from mail-pg1-x541.google.com ([2607:f8b0:4864:20::541]) by casper.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCxA-0004rO-B9 for linux-arm-kernel@lists.infradead.org; Tue, 02 Apr 2019 06:31:29 +0000 Received: by mail-pg1-x541.google.com with SMTP id b12so6040738pgk.0 for ; Mon, 01 Apr 2019 23:31:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=bsKrHycEMshfijbOx0t8uUYTp2zrrlI7D+SqxYWqME4=; b=VHlOjWwcpX3nxcLyXclOaWccYu/68EoJyrb70i5tCG7/hYMy+EGjOHn7EqxBA77Y9E Hdb/KEq6uZNx1ESA+4a7+c7sBK2hTOZcTbo8lWThXMf1rl7Lt9JzpZTi8u/Am2I+rW/O TEAWH/xFnk2Lwf9vcQ85rXPBAP1sP4u9e/UY5aFNziBSVrDF1TzT0pGHCMHun9/Ed8f/ iUqcYpodmBtCL1sPS537vXDCHhtExiIc6lgNtX/GfJAItmoy+yza9Gavu0VekO7wSiRg 4UVZdRZllqmTHgogdluLUSFKK9hGALxgz/39pz5ipHt45w/oRq7cEPf4o0MjYLst84hL qnjQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=bsKrHycEMshfijbOx0t8uUYTp2zrrlI7D+SqxYWqME4=; b=rZinGXj82Om6sUDaqDrG+IzHzOqHjqmuh5sb2Ur8XE9DIGMVGfyAs7ITeBY9ugiRVg MLuLKpwoUP3qvuANpBS24mZcnOGMSBwEX3FWxhvNiFQEeV8Hr17p1E/BSdhCPEWogpB0 uWeUaGRk6rUWAEmVrgqORkJ6rTUibbc0YYM2sSOTYEZLw7WNtbYt8aoQButIwGYS38bi NLBrDbJNiOl6ZAb6ftb5/za3YA4dva8yokN+MKIufAwJcjDSo5hOMnkxulXaWN9HH7QX GngoJe9JRy8VgsLlO9CjMYPKHqR3VyyFu+Zn0YC0DiKm8uq/X7higJICd+OY+a/blmlS C1Lg== X-Gm-Message-State: APjAAAVWr1XnrrTIYRv6UbjnFTr02fV9MnrMieygfnw2kCLnJK/b4elY SHdAo0HaDlt62BwL4ivOooc= X-Google-Smtp-Source: APXvYqwaDpDsC6P+f3DGN7eXCYRr2cwXaH3z3lYFt36Uv4yyNzHCs+9Izbb7mohVDU6n6BFlHSnHVQ== X-Received: by 2002:a62:ab12:: with SMTP id p18mr54433856pff.216.1554186682274; Mon, 01 Apr 2019 23:31:22 -0700 (PDT) Received: from localhost.localdomain ([2001:268:c0a5:4ce0:c70:4af9:86e2:2]) by smtp.gmail.com with ESMTPSA id a17sm19327289pfj.123.2019.04.01.23.31.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Apr 2019 23:31:21 -0700 (PDT) From: William Breathitt Gray To: gregkh@linuxfoundation.org Subject: [PATCH v10 07/18] counter: Add STM32 Timer quadrature encoder Date: Tue, 2 Apr 2019 15:30:42 +0900 Message-Id: <394b4536e48a04607bef8d9df622407e6aabd12b.1554184734.git.vilhelm.gray@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190402_073124_681091_D784CDEE X-CRM114-Status: GOOD ( 27.27 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, benjamin.gaignard@st.com, linux-pwm@vger.kernel.org, linux-iio@vger.kernel.org, patrick.havelange@essensium.com, thierry.reding@gmail.com, pmeerw@pmeerw.net, lars@metafoo.de, daniel.lezcano@linaro.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, david@lechnology.com, William Breathitt Gray , robh+dt@kernel.org, Jonathan Cameron , tglx@linutronix.de, fabrice.gasnier@st.com, esben@haabendal.dk, shawnguo@kernel.org, linux-kernel@vger.kernel.org, leoyang.li@nxp.com, knaack.h@gmx.de, akpm@linux-foundation.org, linuxppc-dev@lists.ozlabs.org, jic23@kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Benjamin Gaignard Implement counter part of the STM32 timer hardware block by using counter API. Hardware only supports X2 and X4 quadrature modes. A ceiling value can be set to define the maximum value reachable by the counter. Signed-off-by: Benjamin Gaignard Co-authored-by: Fabrice Gasnier Reviewed-by: Jonathan Cameron Signed-off-by: William Breathitt Gray --- drivers/counter/Kconfig | 10 + drivers/counter/Makefile | 1 + drivers/counter/stm32-timer-cnt.c | 390 ++++++++++++++++++++++++++++++ 3 files changed, 401 insertions(+) create mode 100644 drivers/counter/stm32-timer-cnt.c diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig index dd3add729529..0bb2340d6087 100644 --- a/drivers/counter/Kconfig +++ b/drivers/counter/Kconfig @@ -28,4 +28,14 @@ config 104_QUAD_8 The base port addresses for the devices may be configured via the base array module parameter. +config STM32_TIMER_CNT + tristate "STM32 Timer encoder counter driver" + depends on MFD_STM32_TIMERS || COMPILE_TEST + help + Select this option to enable STM32 Timer quadrature encoder + and counter driver. + + To compile this driver as a module, choose M here: the + module will be called stm32-timer-cnt. + endif # COUNTER diff --git a/drivers/counter/Makefile b/drivers/counter/Makefile index aee0d2ddcf2c..6b4a5be21b00 100644 --- a/drivers/counter/Makefile +++ b/drivers/counter/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_COUNTER) += counter.o obj-$(CONFIG_104_QUAD_8) += 104-quad-8.o +obj-$(CONFIG_STM32_TIMER_CNT) += stm32-timer-cnt.o diff --git a/drivers/counter/stm32-timer-cnt.c b/drivers/counter/stm32-timer-cnt.c new file mode 100644 index 000000000000..644ba18a72ad --- /dev/null +++ b/drivers/counter/stm32-timer-cnt.c @@ -0,0 +1,390 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * STM32 Timer Encoder and Counter driver + * + * Copyright (C) STMicroelectronics 2018 + * + * Author: Benjamin Gaignard + * + */ +#include +#include +#include +#include +#include +#include + +#define TIM_CCMR_CCXS (BIT(8) | BIT(0)) +#define TIM_CCMR_MASK (TIM_CCMR_CC1S | TIM_CCMR_CC2S | \ + TIM_CCMR_IC1F | TIM_CCMR_IC2F) +#define TIM_CCER_MASK (TIM_CCER_CC1P | TIM_CCER_CC1NP | \ + TIM_CCER_CC2P | TIM_CCER_CC2NP) + +struct stm32_timer_cnt { + struct counter_device counter; + struct regmap *regmap; + struct clk *clk; + u32 ceiling; +}; + +/** + * stm32_count_function - enumerates stm32 timer counter encoder modes + * @STM32_COUNT_SLAVE_MODE_DISABLED: counts on internal clock when CEN=1 + * @STM32_COUNT_ENCODER_MODE_1: counts TI1FP1 edges, depending on TI2FP2 level + * @STM32_COUNT_ENCODER_MODE_2: counts TI2FP2 edges, depending on TI1FP1 level + * @STM32_COUNT_ENCODER_MODE_3: counts on both TI1FP1 and TI2FP2 edges + */ +enum stm32_count_function { + STM32_COUNT_SLAVE_MODE_DISABLED = -1, + STM32_COUNT_ENCODER_MODE_1, + STM32_COUNT_ENCODER_MODE_2, + STM32_COUNT_ENCODER_MODE_3, +}; + +static enum counter_count_function stm32_count_functions[] = { + [STM32_COUNT_ENCODER_MODE_1] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A, + [STM32_COUNT_ENCODER_MODE_2] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_B, + [STM32_COUNT_ENCODER_MODE_3] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4, +}; + +static int stm32_count_read(struct counter_device *counter, + struct counter_count *count, + struct counter_count_read_value *val) +{ + struct stm32_timer_cnt *const priv = counter->priv; + u32 cnt; + + regmap_read(priv->regmap, TIM_CNT, &cnt); + counter_count_read_value_set(val, COUNTER_COUNT_POSITION, &cnt); + + return 0; +} + +static int stm32_count_write(struct counter_device *counter, + struct counter_count *count, + struct counter_count_write_value *val) +{ + struct stm32_timer_cnt *const priv = counter->priv; + u32 cnt; + int err; + + err = counter_count_write_value_get(&cnt, COUNTER_COUNT_POSITION, val); + if (err) + return err; + + if (cnt > priv->ceiling) + return -EINVAL; + + return regmap_write(priv->regmap, TIM_CNT, cnt); +} + +static int stm32_count_function_get(struct counter_device *counter, + struct counter_count *count, + size_t *function) +{ + struct stm32_timer_cnt *const priv = counter->priv; + u32 smcr; + + regmap_read(priv->regmap, TIM_SMCR, &smcr); + + switch (smcr & TIM_SMCR_SMS) { + case 1: + *function = STM32_COUNT_ENCODER_MODE_1; + return 0; + case 2: + *function = STM32_COUNT_ENCODER_MODE_2; + return 0; + case 3: + *function = STM32_COUNT_ENCODER_MODE_3; + return 0; + } + + return -EINVAL; +} + +static int stm32_count_function_set(struct counter_device *counter, + struct counter_count *count, + size_t function) +{ + struct stm32_timer_cnt *const priv = counter->priv; + u32 cr1, sms; + + switch (function) { + case STM32_COUNT_ENCODER_MODE_1: + sms = 1; + break; + case STM32_COUNT_ENCODER_MODE_2: + sms = 2; + break; + case STM32_COUNT_ENCODER_MODE_3: + sms = 3; + break; + default: + sms = 0; + break; + } + + /* Store enable status */ + regmap_read(priv->regmap, TIM_CR1, &cr1); + + regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); + + /* TIMx_ARR register shouldn't be buffered (ARPE=0) */ + regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0); + regmap_write(priv->regmap, TIM_ARR, priv->ceiling); + + regmap_update_bits(priv->regmap, TIM_SMCR, TIM_SMCR_SMS, sms); + + /* Make sure that registers are updated */ + regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG); + + /* Restore the enable status */ + regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, cr1); + + return 0; +} + +static ssize_t stm32_count_direction_read(struct counter_device *counter, + struct counter_count *count, + void *private, char *buf) +{ + struct stm32_timer_cnt *const priv = counter->priv; + const char *direction; + u32 cr1; + + regmap_read(priv->regmap, TIM_CR1, &cr1); + direction = (cr1 & TIM_CR1_DIR) ? "backward" : "forward"; + + return scnprintf(buf, PAGE_SIZE, "%s\n", direction); +} + +static ssize_t stm32_count_ceiling_read(struct counter_device *counter, + struct counter_count *count, + void *private, char *buf) +{ + struct stm32_timer_cnt *const priv = counter->priv; + u32 arr; + + regmap_read(priv->regmap, TIM_ARR, &arr); + + return snprintf(buf, PAGE_SIZE, "%u\n", arr); +} + +static ssize_t stm32_count_ceiling_write(struct counter_device *counter, + struct counter_count *count, + void *private, + const char *buf, size_t len) +{ + struct stm32_timer_cnt *const priv = counter->priv; + unsigned int ceiling; + int ret; + + ret = kstrtouint(buf, 0, &ceiling); + if (ret) + return ret; + + /* TIMx_ARR register shouldn't be buffered (ARPE=0) */ + regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0); + regmap_write(priv->regmap, TIM_ARR, ceiling); + + priv->ceiling = ceiling; + return len; +} + +static ssize_t stm32_count_enable_read(struct counter_device *counter, + struct counter_count *count, + void *private, char *buf) +{ + struct stm32_timer_cnt *const priv = counter->priv; + u32 cr1; + + regmap_read(priv->regmap, TIM_CR1, &cr1); + + return scnprintf(buf, PAGE_SIZE, "%d\n", (bool)(cr1 & TIM_CR1_CEN)); +} + +static ssize_t stm32_count_enable_write(struct counter_device *counter, + struct counter_count *count, + void *private, + const char *buf, size_t len) +{ + struct stm32_timer_cnt *const priv = counter->priv; + int err; + u32 cr1; + bool enable; + + err = kstrtobool(buf, &enable); + if (err) + return err; + + if (enable) { + regmap_read(priv->regmap, TIM_CR1, &cr1); + if (!(cr1 & TIM_CR1_CEN)) + clk_enable(priv->clk); + + regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, + TIM_CR1_CEN); + } else { + regmap_read(priv->regmap, TIM_CR1, &cr1); + regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); + if (cr1 & TIM_CR1_CEN) + clk_disable(priv->clk); + } + + return len; +} + +static const struct counter_count_ext stm32_count_ext[] = { + { + .name = "direction", + .read = stm32_count_direction_read, + }, + { + .name = "enable", + .read = stm32_count_enable_read, + .write = stm32_count_enable_write + }, + { + .name = "ceiling", + .read = stm32_count_ceiling_read, + .write = stm32_count_ceiling_write + }, +}; + +enum stm32_synapse_action { + STM32_SYNAPSE_ACTION_NONE, + STM32_SYNAPSE_ACTION_BOTH_EDGES +}; + +static enum counter_synapse_action stm32_synapse_actions[] = { + [STM32_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE, + [STM32_SYNAPSE_ACTION_BOTH_EDGES] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES +}; + +static int stm32_action_get(struct counter_device *counter, + struct counter_count *count, + struct counter_synapse *synapse, + size_t *action) +{ + size_t function; + int err; + + /* Default action mode (e.g. STM32_COUNT_SLAVE_MODE_DISABLED) */ + *action = STM32_SYNAPSE_ACTION_NONE; + + err = stm32_count_function_get(counter, count, &function); + if (err) + return 0; + + switch (function) { + case STM32_COUNT_ENCODER_MODE_1: + /* counts up/down on TI1FP1 edge depending on TI2FP2 level */ + if (synapse->signal->id == count->synapses[0].signal->id) + *action = STM32_SYNAPSE_ACTION_BOTH_EDGES; + break; + case STM32_COUNT_ENCODER_MODE_2: + /* counts up/down on TI2FP2 edge depending on TI1FP1 level */ + if (synapse->signal->id == count->synapses[1].signal->id) + *action = STM32_SYNAPSE_ACTION_BOTH_EDGES; + break; + case STM32_COUNT_ENCODER_MODE_3: + /* counts up/down on both TI1FP1 and TI2FP2 edges */ + *action = STM32_SYNAPSE_ACTION_BOTH_EDGES; + break; + } + + return 0; +} + +static const struct counter_ops stm32_timer_cnt_ops = { + .count_read = stm32_count_read, + .count_write = stm32_count_write, + .function_get = stm32_count_function_get, + .function_set = stm32_count_function_set, + .action_get = stm32_action_get, +}; + +static struct counter_signal stm32_signals[] = { + { + .id = 0, + .name = "Channel 1 Quadrature A" + }, + { + .id = 1, + .name = "Channel 1 Quadrature B" + } +}; + +static struct counter_synapse stm32_count_synapses[] = { + { + .actions_list = stm32_synapse_actions, + .num_actions = ARRAY_SIZE(stm32_synapse_actions), + .signal = &stm32_signals[0] + }, + { + .actions_list = stm32_synapse_actions, + .num_actions = ARRAY_SIZE(stm32_synapse_actions), + .signal = &stm32_signals[1] + } +}; + +static struct counter_count stm32_counts = { + .id = 0, + .name = "Channel 1 Count", + .functions_list = stm32_count_functions, + .num_functions = ARRAY_SIZE(stm32_count_functions), + .synapses = stm32_count_synapses, + .num_synapses = ARRAY_SIZE(stm32_count_synapses), + .ext = stm32_count_ext, + .num_ext = ARRAY_SIZE(stm32_count_ext) +}; + +static int stm32_timer_cnt_probe(struct platform_device *pdev) +{ + struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent); + struct device *dev = &pdev->dev; + struct stm32_timer_cnt *priv; + + if (IS_ERR_OR_NULL(ddata)) + return -EINVAL; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->regmap = ddata->regmap; + priv->clk = ddata->clk; + priv->ceiling = ddata->max_arr; + + priv->counter.name = dev_name(dev); + priv->counter.parent = dev; + priv->counter.ops = &stm32_timer_cnt_ops; + priv->counter.counts = &stm32_counts; + priv->counter.num_counts = 1; + priv->counter.signals = stm32_signals; + priv->counter.num_signals = ARRAY_SIZE(stm32_signals); + priv->counter.priv = priv; + + /* Register Counter device */ + return devm_counter_register(dev, &priv->counter); +} + +static const struct of_device_id stm32_timer_cnt_of_match[] = { + { .compatible = "st,stm32-timer-counter", }, + {}, +}; +MODULE_DEVICE_TABLE(of, stm32_timer_cnt_of_match); + +static struct platform_driver stm32_timer_cnt_driver = { + .probe = stm32_timer_cnt_probe, + .driver = { + .name = "stm32-timer-counter", + .of_match_table = stm32_timer_cnt_of_match, + }, +}; +module_platform_driver(stm32_timer_cnt_driver); + +MODULE_AUTHOR("Benjamin Gaignard "); +MODULE_ALIAS("platform:stm32-timer-counter"); +MODULE_DESCRIPTION("STMicroelectronics STM32 TIMER counter driver"); +MODULE_LICENSE("GPL v2"); From patchwork Tue Apr 2 06:30:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Breathitt Gray X-Patchwork-Id: 10881171 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9771815AC for ; Tue, 2 Apr 2019 07:31:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6F3FF2888C for ; Tue, 2 Apr 2019 07:31:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5657F2889B; Tue, 2 Apr 2019 07:31:06 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id F2C822888C for ; Tue, 2 Apr 2019 07:31:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=eBg+qGDW7ly1MUx8eDRuh1s7Wg5RPZNH6kH9/ba/BkE=; b=LYUkZYn+qHf63y U+ML26q3mkD1VSzC9dLeNS/p2z7rWToI0Jdy11ZeIKREDXXThNR3RlJlxKJ4EzhH4sRfv5zI58Qz1 O6GY07QFfmx2rnb7gwGPPrzsTfYjGCtsMZerykmzFUJ7oHyOV8fMZ8mfhAU1jh4pxzJk/2XyfkfW0 jNXjwb9Hct1PCYagtoCwVOw2V27TI6MZUAqpU0JYOMEKM1cEgTEJQxsKDtQoLaU4Kz5RdoUrq2dDG iz2L/dvoZT4QgLey6ec1aNEBOD/K3vLym+3uvdE7rq1On9pGwrYSkYRM1QzJUT4YIDJAyIyItcS3k F+zVYnt0VUBsUnfz3Bwg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBDsp-0000vc-P4; Tue, 02 Apr 2019 07:30:59 +0000 Received: from merlin.infradead.org ([2001:8b0:10b:1231::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBDsn-0000ur-8n for linux-arm-kernel@bombadil.infradead.org; Tue, 02 Apr 2019 07:30:57 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=ADfhP5zjUuDjSW2hB90EQKoYLSBhq+Id1FV/2cN0vlY=; b=JiUsHXl40tP6ujO2udHDyck3zp M6eGs9FVraxYGxhcIfUYgwd7JBQteFqgtz0wHBZj4jX6rmzm+mBr5n5QH+7MGDj/K4jWLnHYMGi0F qCZOdrme1/wgZ/yKBGGsWFIhxxCst7TJVc7ncfHT8D6PAMj5q6oALIi5Rd1X/28zdEfF0XF+zDIej tEqtGWgDpYWdHjzhP6WdhpffLlUOVKLeVk+A6WhvfTEaBKQjH4lrhinv7Vx9WyOWl/r4c5sqI3pbc LiFEQHMRh/SVgzTBu7VkCMaSCr3Qo/JKuFz4qhNgw5KytZL/w5t+SNzpSDaQSVLeIhAuU/aABLuqD 0vqbqU5w==; Received: from mail-pf1-x444.google.com ([2607:f8b0:4864:20::444]) by merlin.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCxM-0008By-Ly for linux-arm-kernel@lists.infradead.org; Tue, 02 Apr 2019 06:31:38 +0000 Received: by mail-pf1-x444.google.com with SMTP id 188so5830899pfd.8 for ; Mon, 01 Apr 2019 23:31:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ADfhP5zjUuDjSW2hB90EQKoYLSBhq+Id1FV/2cN0vlY=; b=TvtU31Wsh2zQ/3Nh5ZDWzgedo0YgcJM73Oap3izPnwHvdW/8iC4VOTHiyrJwtlIwwX cMxP8ilL+xbsKv7pDHkGWg4cO7AAicDftKinlUH5/9JCqWjTS55bbtf8f03zI54TBDSL QNSjdqkYARq+a+aC7YNeuLTgd7GXX6xg8isXClJo+9TAJcQuXBX+5RT37jzSuTiAX5dm 4V3GZL+OtPanqMb9DARiEEgt0CBNGKy2xZQgsB5k/5s4EdBovly0TOmDHLCXPbVGK1UF 2olKuS0Zf+IGrhYm29qKTFogkg4dD7QP7Fy7lcpKCSjkzklnwK+YLYO8dC5Ugf+eDEjL Magw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ADfhP5zjUuDjSW2hB90EQKoYLSBhq+Id1FV/2cN0vlY=; b=YkKnoPgEL1gHsMqGFjf4ENyBklTBTbWx/DPCWHPJrtIIbDCCYPpw5mH815Jfs6Lsbi yqLC3cDmnYneW3A2apK4K9ldCJzetAZ8aTi9pDRKXY9FCeTAJ2I2m4hTJz3PT27A1viz yqkBmNQ8a9TpRhUsS2B72Ni2jUyJjnfbQh+f2i3Cl5EjXC9pPna1atbz/1T7Rx8IsZzp rkhpqQ80u6Bh4OfminV51y3/aSJtyBewJa1a6cL9i+LRlbbnI017GLJFB/NeD83ZEz/g +8NC3OqCkbmZ7XDlv/gDuGA3UEpoWngWGsFTeBKO7oYYQOikAPz6t1YGEtAy9l4ISKsJ 5qxQ== X-Gm-Message-State: APjAAAX8oLlsqRIw4/J/LSTD+NsltT5pzyven/7hNB71Je++tjtjmGwf grJlhP4kEm7qVnMNJTCwZX8= X-Google-Smtp-Source: APXvYqzbMDztJcOdNTyqzRYMbCs9hmjnd9YghZAZYSsUUdk+HZF7IfKegX2wxDi3hfqMSXoW+n9tRw== X-Received: by 2002:a62:ac02:: with SMTP id v2mr26546282pfe.163.1554186692246; Mon, 01 Apr 2019 23:31:32 -0700 (PDT) Received: from localhost.localdomain ([2001:268:c0a5:4ce0:c70:4af9:86e2:2]) by smtp.gmail.com with ESMTPSA id a17sm19327289pfj.123.2019.04.01.23.31.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Apr 2019 23:31:31 -0700 (PDT) From: William Breathitt Gray To: gregkh@linuxfoundation.org Subject: [PATCH v10 08/18] dt-bindings: counter: Document stm32 quadrature encoder Date: Tue, 2 Apr 2019 15:30:43 +0900 Message-Id: X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190402_023136_920227_1DFB289A X-CRM114-Status: GOOD ( 15.23 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, benjamin.gaignard@st.com, linux-pwm@vger.kernel.org, linux-iio@vger.kernel.org, patrick.havelange@essensium.com, thierry.reding@gmail.com, pmeerw@pmeerw.net, Rob Herring , lars@metafoo.de, daniel.lezcano@linaro.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, david@lechnology.com, William Breathitt Gray , robh+dt@kernel.org, tglx@linutronix.de, fabrice.gasnier@st.com, esben@haabendal.dk, shawnguo@kernel.org, linux-kernel@vger.kernel.org, leoyang.li@nxp.com, knaack.h@gmx.de, akpm@linux-foundation.org, linuxppc-dev@lists.ozlabs.org, jic23@kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Benjamin Gaignard Add bindings for STM32 Timer quadrature encoder. It is a sub-node of STM32 Timer which implement the quadratic encoder part of the hardware. Cc: Mark Rutland Signed-off-by: Benjamin Gaignard Acked-by: Rob Herring Signed-off-by: William Breathitt Gray --- .../bindings/counter/stm32-timer-cnt.txt | 31 +++++++++++++++++++ .../devicetree/bindings/mfd/stm32-timers.txt | 7 +++++ 2 files changed, 38 insertions(+) create mode 100644 Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt diff --git a/Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt b/Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt new file mode 100644 index 000000000000..c52fcdd4bf6c --- /dev/null +++ b/Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt @@ -0,0 +1,31 @@ +STMicroelectronics STM32 Timer quadrature encoder + +STM32 Timer provides quadrature encoder to detect +angular position and direction of rotary elements, +from IN1 and IN2 input signals. + +Must be a sub-node of an STM32 Timer device tree node. +See ../mfd/stm32-timers.txt for details about the parent node. + +Required properties: +- compatible: Must be "st,stm32-timer-counter". +- pinctrl-names: Set to "default". +- pinctrl-0: List of phandles pointing to pin configuration nodes, + to set CH1/CH2 pins in mode of operation for STM32 + Timer input on external pin. + +Example: + timers@40010000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "st,stm32-timers"; + reg = <0x40010000 0x400>; + clocks = <&rcc 0 160>; + clock-names = "int"; + + counter { + compatible = "st,stm32-timer-counter"; + pinctrl-names = "default"; + pinctrl-0 = <&tim1_in_pins>; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/stm32-timers.txt b/Documentation/devicetree/bindings/mfd/stm32-timers.txt index 0e900b52e895..15c3b87f51d9 100644 --- a/Documentation/devicetree/bindings/mfd/stm32-timers.txt +++ b/Documentation/devicetree/bindings/mfd/stm32-timers.txt @@ -28,6 +28,7 @@ Optional parameters: Optional subnodes: - pwm: See ../pwm/pwm-stm32.txt - timer: See ../iio/timer/stm32-timer-trigger.txt +- counter: See ../counter/stm32-timer-cnt.txt Example: timers@40010000 { @@ -48,6 +49,12 @@ Example: compatible = "st,stm32-timer-trigger"; reg = <0>; }; + + counter { + compatible = "st,stm32-timer-counter"; + pinctrl-names = "default"; + pinctrl-0 = <&tim1_in_pins>; + }; }; Example with all dmas: From patchwork Tue Apr 2 06:30:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Breathitt Gray X-Patchwork-Id: 10881095 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1C3BC17E0 for ; Tue, 2 Apr 2019 06:32:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F36C828770 for ; Tue, 2 Apr 2019 06:32:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E66D528843; Tue, 2 Apr 2019 06:32:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id EDD0828770 for ; Tue, 2 Apr 2019 06:32:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=HIooUNtCg2AJQi8hzNgelV++YYAm5bZadYW5F0BjJ08=; b=Vmf8Uo6GiXsdM4 HeUwaMDlhq4o0elB8CvvRYsWAUHNskTjbtvAW3/TQvOOtuPN3TpTLltkqYB2+ye2Nly5R09WM4e6G z2iJW1niSfj9BzjxjGKExJVF0Feuz3CCdxYt01e2ViEPQXmXRCGYscSiQzC9r0wZbSC5FaUt0sLyS kMZrLxsobF5J8i3Rt477XNC65ScMOaOrd3x8XN7/rVX3sYagYzdNVhmjcH3RjGxc0Z8UZGP1zw51G 4Q76IEObB28rNIt0jSa3Y6IG0cwWwQ0qWdS0NfWw020UPlgZHnWg8chDq5gwnB96Q5CoW694h4Y6R HdXJnze8pwFUnD/eT15g==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCxv-0001HD-PH; Tue, 02 Apr 2019 06:32:11 +0000 Received: from mail-pf1-f193.google.com ([209.85.210.193]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCxT-0000uq-LY for linux-arm-kernel@lists.infradead.org; Tue, 02 Apr 2019 06:32:09 +0000 Received: by mail-pf1-f193.google.com with SMTP id c207so5831677pfc.7 for ; Mon, 01 Apr 2019 23:31:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=tM0HdC6ZSwVatn0cIi08ZrZcncU2tT2QhFGvl3oL8LA=; b=ap5dqpt0FHsRFFju+PVFsFVfQ2vFWeyGGyMmZKXOucFiugvrOPuG7/kcIeM3rmrZvK vZf041udvPIzXgGlPnY+OjVHLOMfRJimeJf85k1vK6LQJrBaIaOTF/mcAeiahy3PGS3v I0J3UjqfoNO9qiEZu/vKXy6S3WlyTaRAIdq51NHjD6D67Rsf6Opuz6EKzdzEVL0mv0AV RXD8q22dyvN68Fh+Wb7HrPT/Fe7VGavcV8gTPNnZifITuW7U+oS7UFuFC//csncwZh/W q6dGkE9mLQBhZcW7G322QgYBVWjQ0aaXj/7dngptjxci1dJNzdhz+cVUr0KCsTkVu8dn 2NEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tM0HdC6ZSwVatn0cIi08ZrZcncU2tT2QhFGvl3oL8LA=; b=Q5ZGP6+XR/sJRCqbgca9+SP8kwZ5/hvpBxgSEFn8h7VEMClN7mAVfj7GUAFbFeWSP5 BBr8wZjxj2BToSvTvJq8Q7qkpAja0ziROT1oaGoCsT8LdMMbFTln0IKxsFA3Bb3+rFdH BWW1SEIzjgywDas6hvs3isTsCj4nbJ9zwdH70tJKDfTPzc8YyVzblCgkPscAlJgIqjvA W8DN3nJ29l0P4q93ndXx725eafBnDnh0cP0p/oS5UvCx318PWmzbtWQk8Xm3V/9uxo6x qIzERFyJnznLJUnFt7btP6uBxahqKnPPd2VLy4TCFTedlZ1nm5aXWHVVp8RTedZaDsKU 9bSg== X-Gm-Message-State: APjAAAXYWPdPox6+FRlXqoMzha8cNlYVmyrVt5HZC6tsLkFKZ8mwpLt8 BGxONNBQoYzX4NcZKxT4RY0= X-Google-Smtp-Source: APXvYqwF36gQ7JIlwbuIksIeKzq98yNiwVNzkX0a5DATDbcfhgIlDZ2Mf7HL6yahQ0Km1rlyLbvX1Q== X-Received: by 2002:a62:2046:: with SMTP id g67mr60880730pfg.121.1554186702752; Mon, 01 Apr 2019 23:31:42 -0700 (PDT) Received: from localhost.localdomain ([2001:268:c0a5:4ce0:c70:4af9:86e2:2]) by smtp.gmail.com with ESMTPSA id a17sm19327289pfj.123.2019.04.01.23.31.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Apr 2019 23:31:42 -0700 (PDT) From: William Breathitt Gray To: gregkh@linuxfoundation.org Subject: [PATCH v10 09/18] counter: stm32-lptimer: add counter device Date: Tue, 2 Apr 2019 15:30:44 +0900 Message-Id: X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190401_233143_802049_3E2A25D5 X-CRM114-Status: GOOD ( 20.19 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, benjamin.gaignard@st.com, linux-pwm@vger.kernel.org, linux-iio@vger.kernel.org, patrick.havelange@essensium.com, thierry.reding@gmail.com, pmeerw@pmeerw.net, lars@metafoo.de, daniel.lezcano@linaro.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, david@lechnology.com, William Breathitt Gray , robh+dt@kernel.org, Jonathan Cameron , tglx@linutronix.de, fabrice.gasnier@st.com, esben@haabendal.dk, shawnguo@kernel.org, linux-kernel@vger.kernel.org, leoyang.li@nxp.com, knaack.h@gmx.de, akpm@linux-foundation.org, linuxppc-dev@lists.ozlabs.org, jic23@kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Fabrice Gasnier Add support for new counter device to stm32-lptimer. Signed-off-by: Fabrice Gasnier Reviewed-by: Jonathan Cameron Signed-off-by: William Breathitt Gray --- drivers/counter/Kconfig | 10 + drivers/counter/Makefile | 1 + drivers/{iio => }/counter/stm32-lptimer-cnt.c | 361 ++++++++++++++++-- drivers/iio/Kconfig | 1 - drivers/iio/Makefile | 1 - drivers/iio/counter/Kconfig | 17 - drivers/iio/counter/Makefile | 7 - 7 files changed, 350 insertions(+), 48 deletions(-) rename drivers/{iio => }/counter/stm32-lptimer-cnt.c (51%) delete mode 100644 drivers/iio/counter/Kconfig delete mode 100644 drivers/iio/counter/Makefile diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig index 0bb2340d6087..87c491a19c63 100644 --- a/drivers/counter/Kconfig +++ b/drivers/counter/Kconfig @@ -38,4 +38,14 @@ config STM32_TIMER_CNT To compile this driver as a module, choose M here: the module will be called stm32-timer-cnt. +config STM32_LPTIMER_CNT + tristate "STM32 LP Timer encoder counter driver" + depends on (MFD_STM32_LPTIMER || COMPILE_TEST) && IIO + help + Select this option to enable STM32 Low-Power Timer quadrature encoder + and counter driver. + + To compile this driver as a module, choose M here: the + module will be called stm32-lptimer-cnt. + endif # COUNTER diff --git a/drivers/counter/Makefile b/drivers/counter/Makefile index 6b4a5be21b00..5589976d37f8 100644 --- a/drivers/counter/Makefile +++ b/drivers/counter/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_COUNTER) += counter.o obj-$(CONFIG_104_QUAD_8) += 104-quad-8.o obj-$(CONFIG_STM32_TIMER_CNT) += stm32-timer-cnt.o +obj-$(CONFIG_STM32_LPTIMER_CNT) += stm32-lptimer-cnt.o diff --git a/drivers/iio/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c similarity index 51% rename from drivers/iio/counter/stm32-lptimer-cnt.c rename to drivers/counter/stm32-lptimer-cnt.c index 2a49cce0edb4..bbc930a5962c 100644 --- a/drivers/iio/counter/stm32-lptimer-cnt.c +++ b/drivers/counter/stm32-lptimer-cnt.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -18,10 +19,11 @@ #include struct stm32_lptim_cnt { + struct counter_device counter; struct device *dev; struct regmap *regmap; struct clk *clk; - u32 preset; + u32 ceiling; u32 polarity; u32 quadrature_mode; bool enabled; @@ -57,7 +59,7 @@ static int stm32_lptim_set_enable_state(struct stm32_lptim_cnt *priv, } /* LP timer must be enabled before writing CMP & ARR */ - ret = regmap_write(priv->regmap, STM32_LPTIM_ARR, priv->preset); + ret = regmap_write(priv->regmap, STM32_LPTIM_ARR, priv->ceiling); if (ret) return ret; @@ -251,44 +253,57 @@ static const struct iio_enum stm32_lptim_cnt_polarity_en = { .set = stm32_lptim_cnt_set_polarity, }; -static ssize_t stm32_lptim_cnt_get_preset(struct iio_dev *indio_dev, - uintptr_t private, - const struct iio_chan_spec *chan, - char *buf) +static ssize_t stm32_lptim_cnt_get_ceiling(struct stm32_lptim_cnt *priv, + char *buf) { - struct stm32_lptim_cnt *priv = iio_priv(indio_dev); - - return snprintf(buf, PAGE_SIZE, "%u\n", priv->preset); + return snprintf(buf, PAGE_SIZE, "%u\n", priv->ceiling); } -static ssize_t stm32_lptim_cnt_set_preset(struct iio_dev *indio_dev, - uintptr_t private, - const struct iio_chan_spec *chan, - const char *buf, size_t len) +static ssize_t stm32_lptim_cnt_set_ceiling(struct stm32_lptim_cnt *priv, + const char *buf, size_t len) { - struct stm32_lptim_cnt *priv = iio_priv(indio_dev); int ret; if (stm32_lptim_is_enabled(priv)) return -EBUSY; - ret = kstrtouint(buf, 0, &priv->preset); + ret = kstrtouint(buf, 0, &priv->ceiling); if (ret) return ret; - if (priv->preset > STM32_LPTIM_MAX_ARR) + if (priv->ceiling > STM32_LPTIM_MAX_ARR) return -EINVAL; return len; } +static ssize_t stm32_lptim_cnt_get_preset_iio(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + char *buf) +{ + struct stm32_lptim_cnt *priv = iio_priv(indio_dev); + + return stm32_lptim_cnt_get_ceiling(priv, buf); +} + +static ssize_t stm32_lptim_cnt_set_preset_iio(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + const char *buf, size_t len) +{ + struct stm32_lptim_cnt *priv = iio_priv(indio_dev); + + return stm32_lptim_cnt_set_ceiling(priv, buf, len); +} + /* LP timer with encoder */ static const struct iio_chan_spec_ext_info stm32_lptim_enc_ext_info[] = { { .name = "preset", .shared = IIO_SEPARATE, - .read = stm32_lptim_cnt_get_preset, - .write = stm32_lptim_cnt_set_preset, + .read = stm32_lptim_cnt_get_preset_iio, + .write = stm32_lptim_cnt_set_preset_iio, }, IIO_ENUM("polarity", IIO_SEPARATE, &stm32_lptim_cnt_polarity_en), IIO_ENUM_AVAILABLE("polarity", &stm32_lptim_cnt_polarity_en), @@ -313,8 +328,8 @@ static const struct iio_chan_spec_ext_info stm32_lptim_cnt_ext_info[] = { { .name = "preset", .shared = IIO_SEPARATE, - .read = stm32_lptim_cnt_get_preset, - .write = stm32_lptim_cnt_set_preset, + .read = stm32_lptim_cnt_get_preset_iio, + .write = stm32_lptim_cnt_set_preset_iio, }, IIO_ENUM("polarity", IIO_SEPARATE, &stm32_lptim_cnt_polarity_en), IIO_ENUM_AVAILABLE("polarity", &stm32_lptim_cnt_polarity_en), @@ -331,11 +346,293 @@ static const struct iio_chan_spec stm32_lptim_cnt_channels = { .indexed = 1, }; +/** + * stm32_lptim_cnt_function - enumerates stm32 LPTimer counter & encoder modes + * @STM32_LPTIM_COUNTER_INCREASE: up count on IN1 rising, falling or both edges + * @STM32_LPTIM_ENCODER_BOTH_EDGE: count on both edges (IN1 & IN2 quadrature) + */ +enum stm32_lptim_cnt_function { + STM32_LPTIM_COUNTER_INCREASE, + STM32_LPTIM_ENCODER_BOTH_EDGE, +}; + +static enum counter_count_function stm32_lptim_cnt_functions[] = { + [STM32_LPTIM_COUNTER_INCREASE] = COUNTER_COUNT_FUNCTION_INCREASE, + [STM32_LPTIM_ENCODER_BOTH_EDGE] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4, +}; + +enum stm32_lptim_synapse_action { + STM32_LPTIM_SYNAPSE_ACTION_RISING_EDGE, + STM32_LPTIM_SYNAPSE_ACTION_FALLING_EDGE, + STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES, + STM32_LPTIM_SYNAPSE_ACTION_NONE, +}; + +static enum counter_synapse_action stm32_lptim_cnt_synapse_actions[] = { + /* Index must match with stm32_lptim_cnt_polarity[] (priv->polarity) */ + [STM32_LPTIM_SYNAPSE_ACTION_RISING_EDGE] = COUNTER_SYNAPSE_ACTION_RISING_EDGE, + [STM32_LPTIM_SYNAPSE_ACTION_FALLING_EDGE] = COUNTER_SYNAPSE_ACTION_FALLING_EDGE, + [STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES, + [STM32_LPTIM_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE, +}; + +static int stm32_lptim_cnt_read(struct counter_device *counter, + struct counter_count *count, + struct counter_count_read_value *val) +{ + struct stm32_lptim_cnt *const priv = counter->priv; + u32 cnt; + int ret; + + ret = regmap_read(priv->regmap, STM32_LPTIM_CNT, &cnt); + if (ret) + return ret; + + counter_count_read_value_set(val, COUNTER_COUNT_POSITION, &cnt); + + return 0; +} + +static int stm32_lptim_cnt_function_get(struct counter_device *counter, + struct counter_count *count, + size_t *function) +{ + struct stm32_lptim_cnt *const priv = counter->priv; + + if (!priv->quadrature_mode) { + *function = STM32_LPTIM_COUNTER_INCREASE; + return 0; + } + + if (priv->polarity == STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES) { + *function = STM32_LPTIM_ENCODER_BOTH_EDGE; + return 0; + } + + return -EINVAL; +} + +static int stm32_lptim_cnt_function_set(struct counter_device *counter, + struct counter_count *count, + size_t function) +{ + struct stm32_lptim_cnt *const priv = counter->priv; + + if (stm32_lptim_is_enabled(priv)) + return -EBUSY; + + switch (function) { + case STM32_LPTIM_COUNTER_INCREASE: + priv->quadrature_mode = 0; + return 0; + case STM32_LPTIM_ENCODER_BOTH_EDGE: + priv->quadrature_mode = 1; + priv->polarity = STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES; + return 0; + } + + return -EINVAL; +} + +static ssize_t stm32_lptim_cnt_enable_read(struct counter_device *counter, + struct counter_count *count, + void *private, char *buf) +{ + struct stm32_lptim_cnt *const priv = counter->priv; + int ret; + + ret = stm32_lptim_is_enabled(priv); + if (ret < 0) + return ret; + + return scnprintf(buf, PAGE_SIZE, "%u\n", ret); +} + +static ssize_t stm32_lptim_cnt_enable_write(struct counter_device *counter, + struct counter_count *count, + void *private, + const char *buf, size_t len) +{ + struct stm32_lptim_cnt *const priv = counter->priv; + bool enable; + int ret; + + ret = kstrtobool(buf, &enable); + if (ret) + return ret; + + /* Check nobody uses the timer, or already disabled/enabled */ + ret = stm32_lptim_is_enabled(priv); + if ((ret < 0) || (!ret && !enable)) + return ret; + if (enable && ret) + return -EBUSY; + + ret = stm32_lptim_setup(priv, enable); + if (ret) + return ret; + + ret = stm32_lptim_set_enable_state(priv, enable); + if (ret) + return ret; + + return len; +} + +static ssize_t stm32_lptim_cnt_ceiling_read(struct counter_device *counter, + struct counter_count *count, + void *private, char *buf) +{ + struct stm32_lptim_cnt *const priv = counter->priv; + + return stm32_lptim_cnt_get_ceiling(priv, buf); +} + +static ssize_t stm32_lptim_cnt_ceiling_write(struct counter_device *counter, + struct counter_count *count, + void *private, + const char *buf, size_t len) +{ + struct stm32_lptim_cnt *const priv = counter->priv; + + return stm32_lptim_cnt_set_ceiling(priv, buf, len); +} + +static const struct counter_count_ext stm32_lptim_cnt_ext[] = { + { + .name = "enable", + .read = stm32_lptim_cnt_enable_read, + .write = stm32_lptim_cnt_enable_write + }, + { + .name = "ceiling", + .read = stm32_lptim_cnt_ceiling_read, + .write = stm32_lptim_cnt_ceiling_write + }, +}; + +static int stm32_lptim_cnt_action_get(struct counter_device *counter, + struct counter_count *count, + struct counter_synapse *synapse, + size_t *action) +{ + struct stm32_lptim_cnt *const priv = counter->priv; + size_t function; + int err; + + err = stm32_lptim_cnt_function_get(counter, count, &function); + if (err) + return err; + + switch (function) { + case STM32_LPTIM_COUNTER_INCREASE: + /* LP Timer acts as up-counter on input 1 */ + if (synapse->signal->id == count->synapses[0].signal->id) + *action = priv->polarity; + else + *action = STM32_LPTIM_SYNAPSE_ACTION_NONE; + return 0; + case STM32_LPTIM_ENCODER_BOTH_EDGE: + *action = priv->polarity; + return 0; + } + + return -EINVAL; +} + +static int stm32_lptim_cnt_action_set(struct counter_device *counter, + struct counter_count *count, + struct counter_synapse *synapse, + size_t action) +{ + struct stm32_lptim_cnt *const priv = counter->priv; + size_t function; + int err; + + if (stm32_lptim_is_enabled(priv)) + return -EBUSY; + + err = stm32_lptim_cnt_function_get(counter, count, &function); + if (err) + return err; + + /* only set polarity when in counter mode (on input 1) */ + if (function == STM32_LPTIM_COUNTER_INCREASE + && synapse->signal->id == count->synapses[0].signal->id) { + switch (action) { + case STM32_LPTIM_SYNAPSE_ACTION_RISING_EDGE: + case STM32_LPTIM_SYNAPSE_ACTION_FALLING_EDGE: + case STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES: + priv->polarity = action; + return 0; + } + } + + return -EINVAL; +} + +static const struct counter_ops stm32_lptim_cnt_ops = { + .count_read = stm32_lptim_cnt_read, + .function_get = stm32_lptim_cnt_function_get, + .function_set = stm32_lptim_cnt_function_set, + .action_get = stm32_lptim_cnt_action_get, + .action_set = stm32_lptim_cnt_action_set, +}; + +static struct counter_signal stm32_lptim_cnt_signals[] = { + { + .id = 0, + .name = "Channel 1 Quadrature A" + }, + { + .id = 1, + .name = "Channel 1 Quadrature B" + } +}; + +static struct counter_synapse stm32_lptim_cnt_synapses[] = { + { + .actions_list = stm32_lptim_cnt_synapse_actions, + .num_actions = ARRAY_SIZE(stm32_lptim_cnt_synapse_actions), + .signal = &stm32_lptim_cnt_signals[0] + }, + { + .actions_list = stm32_lptim_cnt_synapse_actions, + .num_actions = ARRAY_SIZE(stm32_lptim_cnt_synapse_actions), + .signal = &stm32_lptim_cnt_signals[1] + } +}; + +/* LP timer with encoder */ +static struct counter_count stm32_lptim_enc_counts = { + .id = 0, + .name = "LPTimer Count", + .functions_list = stm32_lptim_cnt_functions, + .num_functions = ARRAY_SIZE(stm32_lptim_cnt_functions), + .synapses = stm32_lptim_cnt_synapses, + .num_synapses = ARRAY_SIZE(stm32_lptim_cnt_synapses), + .ext = stm32_lptim_cnt_ext, + .num_ext = ARRAY_SIZE(stm32_lptim_cnt_ext) +}; + +/* LP timer without encoder (counter only) */ +static struct counter_count stm32_lptim_in1_counts = { + .id = 0, + .name = "LPTimer Count", + .functions_list = stm32_lptim_cnt_functions, + .num_functions = 1, + .synapses = stm32_lptim_cnt_synapses, + .num_synapses = 1, + .ext = stm32_lptim_cnt_ext, + .num_ext = ARRAY_SIZE(stm32_lptim_cnt_ext) +}; + static int stm32_lptim_cnt_probe(struct platform_device *pdev) { struct stm32_lptimer *ddata = dev_get_drvdata(pdev->dev.parent); struct stm32_lptim_cnt *priv; struct iio_dev *indio_dev; + int ret; if (IS_ERR_OR_NULL(ddata)) return -EINVAL; @@ -348,8 +645,9 @@ static int stm32_lptim_cnt_probe(struct platform_device *pdev) priv->dev = &pdev->dev; priv->regmap = ddata->regmap; priv->clk = ddata->clk; - priv->preset = STM32_LPTIM_MAX_ARR; + priv->ceiling = STM32_LPTIM_MAX_ARR; + /* Initialize IIO device */ indio_dev->name = dev_name(&pdev->dev); indio_dev->dev.parent = &pdev->dev; indio_dev->dev.of_node = pdev->dev.of_node; @@ -360,9 +658,28 @@ static int stm32_lptim_cnt_probe(struct platform_device *pdev) indio_dev->channels = &stm32_lptim_cnt_channels; indio_dev->num_channels = 1; + /* Initialize Counter device */ + priv->counter.name = dev_name(&pdev->dev); + priv->counter.parent = &pdev->dev; + priv->counter.ops = &stm32_lptim_cnt_ops; + if (ddata->has_encoder) { + priv->counter.counts = &stm32_lptim_enc_counts; + priv->counter.num_signals = ARRAY_SIZE(stm32_lptim_cnt_signals); + } else { + priv->counter.counts = &stm32_lptim_in1_counts; + priv->counter.num_signals = 1; + } + priv->counter.num_counts = 1; + priv->counter.signals = stm32_lptim_cnt_signals; + priv->counter.priv = priv; + platform_set_drvdata(pdev, priv); - return devm_iio_device_register(&pdev->dev, indio_dev); + ret = devm_iio_device_register(&pdev->dev, indio_dev); + if (ret) + return ret; + + return devm_counter_register(&pdev->dev, &priv->counter); } #ifdef CONFIG_PM_SLEEP diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index 014006d1cbb6..4243e35c25e9 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -74,7 +74,6 @@ source "drivers/iio/afe/Kconfig" source "drivers/iio/amplifiers/Kconfig" source "drivers/iio/chemical/Kconfig" source "drivers/iio/common/Kconfig" -source "drivers/iio/counter/Kconfig" source "drivers/iio/dac/Kconfig" source "drivers/iio/dummy/Kconfig" source "drivers/iio/frequency/Kconfig" diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index cb5993251381..bff682ad1cfb 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -20,7 +20,6 @@ obj-y += amplifiers/ obj-y += buffer/ obj-y += chemical/ obj-y += common/ -obj-y += counter/ obj-y += dac/ obj-y += dummy/ obj-y += gyro/ diff --git a/drivers/iio/counter/Kconfig b/drivers/iio/counter/Kconfig deleted file mode 100644 index eeb358122cbe..000000000000 --- a/drivers/iio/counter/Kconfig +++ /dev/null @@ -1,17 +0,0 @@ -# -# Counter devices -# -# When adding new entries keep the list in alphabetical order - -menu "Counters" - -config STM32_LPTIMER_CNT - tristate "STM32 LP Timer encoder counter driver" - depends on MFD_STM32_LPTIMER || COMPILE_TEST - help - Select this option to enable STM32 Low-Power Timer quadrature encoder - and counter driver. - - To compile this driver as a module, choose M here: the - module will be called stm32-lptimer-cnt. -endmenu diff --git a/drivers/iio/counter/Makefile b/drivers/iio/counter/Makefile deleted file mode 100644 index 93933ba49280..000000000000 --- a/drivers/iio/counter/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for IIO counter devices -# - -# When adding new entries keep the list in alphabetical order - -obj-$(CONFIG_STM32_LPTIMER_CNT) += stm32-lptimer-cnt.o From patchwork Tue Apr 2 06:30:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Breathitt Gray X-Patchwork-Id: 10881097 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6FB531669 for ; Tue, 2 Apr 2019 06:32:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 555F028770 for ; Tue, 2 Apr 2019 06:32:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 497D728843; Tue, 2 Apr 2019 06:32:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E99B728770 for ; Tue, 2 Apr 2019 06:32:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=iKXTS8a+hUYYSTlVmYsuESn1xeWQaQ80heFLMIVhcTQ=; b=kK4+HfXZvwFgBK u4hGWfD9Isdus7TsxhAV8eMQvJkDv6pdyVUrDrYC1hqiNFMR0osdFe3Qv7Xl9y5vALWhBrfW5xxrB epBrZg5MQyLdwQItp0zJc217qFOfCQlA5rBA/NAsH/s4r2ohXQYQl5kUtN5fNfZZhE4wx2kxsV6sP N2kFzeNNAR7d+WuArzNZ69F1aa1H6010L6uWhL7mwE82mUGHL8yWGFX4gxMvDrAjyvE//vTNPGx9k nLK+47qX1Ea6Mr4Br9NQejwq5KriHeN0rdWZt5ZtXl2PK4s3O7aau5qPkyhn2JCrUHnl2LiYmwPis CRaiVmkM6uqct4JOczcA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCy7-0001Ri-J8; Tue, 02 Apr 2019 06:32:23 +0000 Received: from mail-pl1-x641.google.com ([2607:f8b0:4864:20::641]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCxc-0000yT-Um for linux-arm-kernel@lists.infradead.org; Tue, 02 Apr 2019 06:32:09 +0000 Received: by mail-pl1-x641.google.com with SMTP id g12so5725932pll.11 for ; Mon, 01 Apr 2019 23:31:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=e5lI6Cm8DXQohzRLyyRrBDvhGKUFb9mSBAgeXH8Sbbw=; b=PCU4LuYE1RQ8Nd35Pecg9oBVn2EQCZLJD6UIdwPRo/EiPdfnjGbRGhHB2yblcUMytF zJOAvZ4ubqtfTb9MoJX8WsWCUaKOAhmPdD6ZLduhK0O8N7GYSdQ48BtcnaZb2SVBGpbZ dPijpKmdL1+9Tx7KnC9AhQ+AzBOc8QyKT6K18UWEHIgK19NVCuAXvYGzPWWI4b+i/uwr IKdR1Z4nQR2PtsZJ022W9aV0SyVd5zXA2NKApxPTI5KCsLdaI4PkNgTe0SJcdhidcf5o Jetzj30fCnrF9ryGuzul3CUqHZxr4K0S63Ki8FvL9AdGyiFzpjqu3qjz7iUS8zzYQLjQ 6jow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=e5lI6Cm8DXQohzRLyyRrBDvhGKUFb9mSBAgeXH8Sbbw=; b=uANMCXK+j+LJLksQHb8Wrmybx1hTi/Q5zmN419W+38tdFOGhjEtJVV8mnoIh2RBlip BVXt/wngQgkg8zLu0b93rUEngHQI5zJiSI06iHSNuH3XxDXPAXITqlDoksdqPSM/eNu7 dLT98rdFURURSxQpouTY+QYa0tf9QASFDV4KB8yPK6wvJ22KtaqhFcwMTTLvp3Rdp/FK UhcCz/PB6a4jCaMjzvVwfy24r8uyd41heQt7r5ZQGKxcrJpFZUq7fbnQCJ3pX7zfK8wt 5vvYWnuimewlhqFU1OeJjT40QSgEUm2n1aVNowGM+YX7yRBzruPtxWPcGkzb2pVo0Hve 5KtQ== X-Gm-Message-State: APjAAAUFzHDuAqqmjKLcXv7OfWrKbEpvLTHUPsjlIgJ6x9SS+4huiDDn Iclmtd/I6cCcCrBgF3thg/o= X-Google-Smtp-Source: APXvYqwYR6LdnL4uy6cbUMrLOBM+U76iG5CPQ/aGeUxQ5Zjp147mg64//+odVU3qjvqueQET6xOLow== X-Received: by 2002:a17:902:b706:: with SMTP id d6mr32862396pls.250.1554186712458; Mon, 01 Apr 2019 23:31:52 -0700 (PDT) Received: from localhost.localdomain ([2001:268:c0a5:4ce0:c70:4af9:86e2:2]) by smtp.gmail.com with ESMTPSA id a17sm19327289pfj.123.2019.04.01.23.31.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Apr 2019 23:31:51 -0700 (PDT) From: William Breathitt Gray To: gregkh@linuxfoundation.org Subject: [PATCH v10 10/18] dt-bindings: counter: Adjust dt-bindings for STM32 lptimer move Date: Tue, 2 Apr 2019 15:30:45 +0900 Message-Id: <2aaee83992bcc1d29080ef6921ae6ad56856389f.1554184734.git.vilhelm.gray@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190401_233153_194603_81DC0464 X-CRM114-Status: GOOD ( 11.20 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, benjamin.gaignard@st.com, linux-pwm@vger.kernel.org, linux-iio@vger.kernel.org, patrick.havelange@essensium.com, thierry.reding@gmail.com, pmeerw@pmeerw.net, Rob Herring , lars@metafoo.de, daniel.lezcano@linaro.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, david@lechnology.com, William Breathitt Gray , robh+dt@kernel.org, tglx@linutronix.de, fabrice.gasnier@st.com, esben@haabendal.dk, shawnguo@kernel.org, linux-kernel@vger.kernel.org, leoyang.li@nxp.com, knaack.h@gmx.de, akpm@linux-foundation.org, linuxppc-dev@lists.ozlabs.org, jic23@kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Fabrice Gasnier The STM32 LP Timer counter driver now resides under the Counter subsystem. This patch adjusts dt-bindings to account for the STM32 lptimer driver move. Cc: Mark Rutland Signed-off-by: Fabrice Gasnier Acked-by: Rob Herring Signed-off-by: William Breathitt Gray --- .../devicetree/bindings/{iio => }/counter/stm32-lptimer-cnt.txt | 0 Documentation/devicetree/bindings/mfd/stm32-lptimer.txt | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename Documentation/devicetree/bindings/{iio => }/counter/stm32-lptimer-cnt.txt (100%) diff --git a/Documentation/devicetree/bindings/iio/counter/stm32-lptimer-cnt.txt b/Documentation/devicetree/bindings/counter/stm32-lptimer-cnt.txt similarity index 100% rename from Documentation/devicetree/bindings/iio/counter/stm32-lptimer-cnt.txt rename to Documentation/devicetree/bindings/counter/stm32-lptimer-cnt.txt diff --git a/Documentation/devicetree/bindings/mfd/stm32-lptimer.txt b/Documentation/devicetree/bindings/mfd/stm32-lptimer.txt index 2a9ff29db9c9..fb54e4dad5b3 100644 --- a/Documentation/devicetree/bindings/mfd/stm32-lptimer.txt +++ b/Documentation/devicetree/bindings/mfd/stm32-lptimer.txt @@ -16,7 +16,7 @@ Required properties: Optional subnodes: - pwm: See ../pwm/pwm-stm32-lp.txt -- counter: See ../iio/timer/stm32-lptimer-cnt.txt +- counter: See ../counter/stm32-lptimer-cnt.txt - trigger: See ../iio/timer/stm32-lptimer-trigger.txt Example: From patchwork Tue Apr 2 06:30:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Breathitt Gray X-Patchwork-Id: 10881103 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0BABD1669 for ; Tue, 2 Apr 2019 06:32:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E7B5C28770 for ; Tue, 2 Apr 2019 06:32:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DBC2828843; Tue, 2 Apr 2019 06:32:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 453A628770 for ; Tue, 2 Apr 2019 06:32:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=iJ9rAe2/dAQxbsThpMfR5Qp20KcBNjp2jd4CLN0ncNE=; b=IW1TJN9eWGZqsa muwKPv3+j5lBGStWo6qmtmxc6764pf/tzzZ1poUivGFiswkmN+BJ7jVhXjMPutoFADmGDwAJEds3h P+K4WaR9bkZ2m7wAbCe72baL3TfcIzo2HT4CWWUw54Qs9x7LNEMPKb5ndZESSVgtDdxgS/nN8r9tt mKUinSeIe/Iow42rVwJu3lJ6TBIiitj1YfQJBOE/W5LHXFjgaNocjCa/77IyKBSwu7SGfLgKTaAwa V4Nd3qhEvARLjeuh5atyJay1vQjPKlSzQaq0yNW6oD+JII3HRg8sWs4zlzNUR3zD5MEe2NqprYZVA thcmJANG2flV+a7ZvvNQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCyJ-0001k3-RK; Tue, 02 Apr 2019 06:32:35 +0000 Received: from mail-pg1-x543.google.com ([2607:f8b0:4864:20::543]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCxm-0001AS-M2 for linux-arm-kernel@lists.infradead.org; Tue, 02 Apr 2019 06:32:17 +0000 Received: by mail-pg1-x543.google.com with SMTP id e6so1663603pgc.4 for ; Mon, 01 Apr 2019 23:32:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=svskp7QoINQnHTiaUtBOVYrxeQ5QnKH9lu/Zsj/N//s=; b=Hw0WAlbzJsmhP/ZYLuuqIDUxu8G91MVcKWTy8fa0ekMx9gr12t/mcsw+A/DP3DhX1V l0z7FVWuNOvDfauDl3dtlj+/an3Iqrcik8h3WndhibdoAcfoZYK++qaNK42nkktj9x1G xejGpkYQAtWcYuh8kQHxqskYXrU315oP13Ozm/sZMMEz5mpGS8UTLSq83L/utKKEZ2WJ inm0ADGLe+ytH4kkWyCbsdw9EhL3/0YoBF61lb3nIf+1/yg/qdiouCWYvyIDtkg4m8hd 1b+EhkO0NrqhAPzigiqPz+4ppE2FTZO9pf9hnjJZAyzq95HCzqUztHYKkJNvP5uyazfv vkEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=svskp7QoINQnHTiaUtBOVYrxeQ5QnKH9lu/Zsj/N//s=; b=rlUvPjQ6NYYIrgO9G/6/dscYP9j2YhnffygmvPWbp2sdVwvaLLLvYsPfVJO8m6BM8m xKXTQH/OZH0ahZgfCn3cjmg3B28s6gEXCIjLkNRvsbCnQ+n5xHhULkeKeBQ95SmTmWaN QWtgAkre3w4Svy2400HhV2obvgCA/pd+3bIPIji0GP+fBFurskw3tVxwwZ8nKimF5Y3B gOHIV9EbnIgpWMLJfn2AZP9Q1+ECUjHPr4HoSCDWdjEIPTq62gTi9+fWH498Gsx7xF4E sHRjVpvVPWXb7ePynjRyNQO7R0/2u4Y044qRKktdLJ4DrP8TX9gWgWfRzxWDXmi2vvar R+2w== X-Gm-Message-State: APjAAAUCcYyhBGCMPWQLV0Nzy6sDtbtwORnA+N7755CPPosOsiuc/hEO IVWUCNq6MpIb8FXBYCsfb8kWKlWDv5k= X-Google-Smtp-Source: APXvYqyMJRpEUbsbfFckbE3oVErEbk4bfC3cfg3HieAJxmwDASP5WRC+RYolJFJE9eQ4k7wBLzWZHQ== X-Received: by 2002:a62:ae13:: with SMTP id q19mr65909898pff.152.1554186722023; Mon, 01 Apr 2019 23:32:02 -0700 (PDT) Received: from localhost.localdomain ([2001:268:c0a5:4ce0:c70:4af9:86e2:2]) by smtp.gmail.com with ESMTPSA id a17sm19327289pfj.123.2019.04.01.23.31.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Apr 2019 23:32:01 -0700 (PDT) From: William Breathitt Gray To: gregkh@linuxfoundation.org Subject: [PATCH v10 11/18] iio: counter: Add deprecation markings for IIO Counter attributes Date: Tue, 2 Apr 2019 15:30:46 +0900 Message-Id: <997556b04cbc210adf1cd202114f5064ec7bb9dd.1554184734.git.vilhelm.gray@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190401_233203_149612_3EAAF20C X-CRM114-Status: GOOD ( 12.96 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, benjamin.gaignard@st.com, linux-pwm@vger.kernel.org, linux-iio@vger.kernel.org, patrick.havelange@essensium.com, thierry.reding@gmail.com, pmeerw@pmeerw.net, lars@metafoo.de, daniel.lezcano@linaro.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, david@lechnology.com, William Breathitt Gray , robh+dt@kernel.org, Jonathan Cameron , tglx@linutronix.de, fabrice.gasnier@st.com, esben@haabendal.dk, shawnguo@kernel.org, linux-kernel@vger.kernel.org, leoyang.li@nxp.com, knaack.h@gmx.de, akpm@linux-foundation.org, linuxppc-dev@lists.ozlabs.org, jic23@kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The IIO counter subdirectory is now superceded by the Counter subsystem. This patch adds deprecation warnings to the documentation of the relevant IIO Counter sysfs attributes. Acked-by: Jonathan Cameron Signed-off-by: William Breathitt Gray --- Documentation/ABI/testing/sysfs-bus-iio | 8 ++++++++ .../ABI/testing/sysfs-bus-iio-counter-104-quad-8 | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 864f8efd12e5..6aef7dbbde44 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -1656,6 +1656,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_countY_raw KernelVersion: 4.10 Contact: linux-iio@vger.kernel.org Description: + This interface is deprecated; please use the Counter subsystem. + Raw counter device counts from channel Y. For quadrature counters, multiplication by an available [Y]_scale results in the counts of a single quadrature signal phase from channel Y. @@ -1664,6 +1666,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_indexY_raw KernelVersion: 4.10 Contact: linux-iio@vger.kernel.org Description: + This interface is deprecated; please use the Counter subsystem. + Raw counter device index value from channel Y. This attribute provides an absolute positional reference (e.g. a pulse once per revolution) which may be used to home positional systems as @@ -1673,6 +1677,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_count_count_direction_available KernelVersion: 4.12 Contact: linux-iio@vger.kernel.org Description: + This interface is deprecated; please use the Counter subsystem. + A list of possible counting directions which are: - "up" : counter device is increasing. - "down": counter device is decreasing. @@ -1681,6 +1687,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_countY_count_direction KernelVersion: 4.12 Contact: linux-iio@vger.kernel.org Description: + This interface is deprecated; please use the Counter subsystem. + Raw counter device counters direction for channel Y. What: /sys/bus/iio/devices/iio:deviceX/in_phaseY_raw diff --git a/Documentation/ABI/testing/sysfs-bus-iio-counter-104-quad-8 b/Documentation/ABI/testing/sysfs-bus-iio-counter-104-quad-8 index 7fac2c268d9a..bac3d0d48b7b 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio-counter-104-quad-8 +++ b/Documentation/ABI/testing/sysfs-bus-iio-counter-104-quad-8 @@ -6,6 +6,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_index_synchronous_mode_available KernelVersion: 4.10 Contact: linux-iio@vger.kernel.org Description: + This interface is deprecated; please use the Counter subsystem. + Discrete set of available values for the respective counter configuration are listed in this file. @@ -13,6 +15,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_countY_count_mode KernelVersion: 4.10 Contact: linux-iio@vger.kernel.org Description: + This interface is deprecated; please use the Counter subsystem. + Count mode for channel Y. Four count modes are available: normal, range limit, non-recycle, and modulo-n. The preset value for channel Y is used by the count mode where required. @@ -47,6 +51,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_countY_noise_error KernelVersion: 4.10 Contact: linux-iio@vger.kernel.org Description: + This interface is deprecated; please use the Counter subsystem. + Read-only attribute that indicates whether excessive noise is present at the channel Y count inputs in quadrature clock mode; irrelevant in non-quadrature clock mode. @@ -55,6 +61,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_countY_preset KernelVersion: 4.10 Contact: linux-iio@vger.kernel.org Description: + This interface is deprecated; please use the Counter subsystem. + If the counter device supports preset registers, the preset count for channel Y is provided by this attribute. @@ -62,6 +70,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_countY_quadrature_mode KernelVersion: 4.10 Contact: linux-iio@vger.kernel.org Description: + This interface is deprecated; please use the Counter subsystem. + Configure channel Y counter for non-quadrature or quadrature clock mode. Selecting non-quadrature clock mode will disable synchronous load mode. In quadrature clock mode, the channel Y @@ -83,6 +93,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_countY_set_to_preset_on_index KernelVersion: 4.10 Contact: linux-iio@vger.kernel.org Description: + This interface is deprecated; please use the Counter subsystem. + Whether to set channel Y counter with channel Y preset value when channel Y index input is active, or continuously count. Valid attribute values are boolean. @@ -91,6 +103,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_indexY_index_polarity KernelVersion: 4.10 Contact: linux-iio@vger.kernel.org Description: + This interface is deprecated; please use the Counter subsystem. + Active level of channel Y index input; irrelevant in non-synchronous load mode. @@ -98,6 +112,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_indexY_synchronous_mode KernelVersion: 4.10 Contact: linux-iio@vger.kernel.org Description: + This interface is deprecated; please use the Counter subsystem. + Configure channel Y counter for non-synchronous or synchronous load mode. Synchronous load mode cannot be selected in non-quadrature clock mode. From patchwork Tue Apr 2 06:30:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Breathitt Gray X-Patchwork-Id: 10881107 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9BF3F17E0 for ; Tue, 2 Apr 2019 06:32:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7CC2528770 for ; Tue, 2 Apr 2019 06:32:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6DF9F28843; Tue, 2 Apr 2019 06:32:55 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id EC31428770 for ; Tue, 2 Apr 2019 06:32:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=YW1F3cprKZa4NHXyuANCfIvkQn4jgdKZRzQcrzV773c=; b=SDK/iiJbMaYhcY mt3YXtd7SyfLW6znrQrTnSx9FMB3KcQC8cdvqEaCUwDPRL88LMpAs7GXVSKcUGxmgp11RcRDg4xtV QcA5FnmvP4P5Y3uWdJy8cCqTMxJfdbYbdZDJvPAl0PTT6lbfX3tPFFXcknJwr4gSh8wpO7BLIOMeM Ux14FaB1EU73yKL1W2U/gVbQc6AkBiSQxqCB7qvwbT5DEkCMiVv8hET0yt2ECdLQ1rTam2NStO/VZ AZjdaUBwYPfDF5YeMUhLxJRB0xNyWw2onwLyLFweIhdvmS9ndedM9fFAosRX/wmzs32lD8tcbrsHv JOAu5lWGXveW43HPUinw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCyV-0001zQ-5i; Tue, 02 Apr 2019 06:32:47 +0000 Received: from mail-pl1-x643.google.com ([2607:f8b0:4864:20::643]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCxw-0001Hd-J6 for linux-arm-kernel@lists.infradead.org; Tue, 02 Apr 2019 06:32:43 +0000 Received: by mail-pl1-x643.google.com with SMTP id b65so5727956plb.6 for ; Mon, 01 Apr 2019 23:32:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=BaIWJSTRjzWyLekqc6jwZik98Kx45p7haF3OxKPIA1o=; b=iY/rqAecGiREiE7KwkpM7WFZ9E2O5uDNptFluiCUlEkxi8HtGYA0RBDVBzWIktfM4/ 6mctHdCPeZENnSqZwNhzc4iVY8m0avdaYMCjtRtDPuzl4mIroXOspMhKxMsVxAdSZgPG XMRCUZL+0GIx9kEFF6NmI5pvOJAWrlPY0zK5LhygqyXJjJ9cnMa2dLLm/P3sW51W++H+ /0rSULTv4EFhKDI8BSsDOG6bh49x8HRZSu66yb00MViAAEsECAJGgTOCa+uzYiLF+R49 oyxD++ThX9qZ61Cdf12XjeT8RPhvNdrNhCAJB5RPiL/9GW6TjQokb4AzHs1P3Sx6n4gu lCHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=BaIWJSTRjzWyLekqc6jwZik98Kx45p7haF3OxKPIA1o=; b=MACT9hciWqm0KcPfm4Iw5Svi+WPXF9fchusjuigbYl90s2KIuw/3e/ADxNWuf3Hdu5 xBmfGEVeFQUZZTh6WP3Vs0l2e7QeLcmle0p2BWdjHhplrQ1QznJ0pv/5Qx9eRl//JyA7 6yaeTV9j9UEUOTNAtXSwJhLZZZOgsfoiRZTCpxvjDOwtlsNFxidRL16JlgGgrafPr14i zCcLDJw/LhMVlohKdVic2LWzM0Ouw3nEgLrOKrwgLvCSAMUU5oEK8bIO4OnDYylNbM4J k4yoM5MHfgfP+5KwbIKHa+FITatp/gnTNoTdmRqquzPZ/y1leLq0PTzckPx3lqtziyzJ XBUw== X-Gm-Message-State: APjAAAUbUm6D7d86KOOMaFdDAncsW2lEKaBqlU9NIIO8GUgGKIMypEDX lmvK9P1fEY+6coPyN0JD6mg= X-Google-Smtp-Source: APXvYqwVfrRByKFeOKBL9R1qbr5mt0aUWyMrsX8kZdL32AtyzhDeQxXCXY3D859wQjyCHhnQQSuqPQ== X-Received: by 2002:a17:902:2ba7:: with SMTP id l36mr69299080plb.237.1554186732097; Mon, 01 Apr 2019 23:32:12 -0700 (PDT) Received: from localhost.localdomain ([2001:268:c0a5:4ce0:c70:4af9:86e2:2]) by smtp.gmail.com with ESMTPSA id a17sm19327289pfj.123.2019.04.01.23.32.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Apr 2019 23:32:11 -0700 (PDT) From: William Breathitt Gray To: gregkh@linuxfoundation.org Subject: [PATCH v10 12/18] include/fsl: add common FlexTimer #defines in a separate header. Date: Tue, 2 Apr 2019 15:30:47 +0900 Message-Id: <4107a3897b6dc081bbf598d4faedaf3bc306a1d2.1554184734.git.vilhelm.gray@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190401_233213_636971_9514124D X-CRM114-Status: GOOD ( 12.64 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, benjamin.gaignard@st.com, linux-pwm@vger.kernel.org, linux-iio@vger.kernel.org, patrick.havelange@essensium.com, thierry.reding@gmail.com, pmeerw@pmeerw.net, lars@metafoo.de, daniel.lezcano@linaro.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, david@lechnology.com, William Breathitt Gray , robh+dt@kernel.org, tglx@linutronix.de, fabrice.gasnier@st.com, esben@haabendal.dk, shawnguo@kernel.org, linux-kernel@vger.kernel.org, leoyang.li@nxp.com, knaack.h@gmx.de, akpm@linux-foundation.org, linuxppc-dev@lists.ozlabs.org, jic23@kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Patrick Havelange Several files are/will be using the same #defines to use the Flextimer module. Regroup them in a common file. Reviewed-by: Esben Haabendal Signed-off-by: Patrick Havelange Signed-off-by: William Breathitt Gray --- include/linux/fsl/ftm.h | 88 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 include/linux/fsl/ftm.h diff --git a/include/linux/fsl/ftm.h b/include/linux/fsl/ftm.h new file mode 100644 index 000000000000..d59011acf66c --- /dev/null +++ b/include/linux/fsl/ftm.h @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef __FSL_FTM_H__ +#define __FSL_FTM_H__ + +#define FTM_SC 0x0 /* Status And Control */ +#define FTM_CNT 0x4 /* Counter */ +#define FTM_MOD 0x8 /* Modulo */ + +#define FTM_CNTIN 0x4C /* Counter Initial Value */ +#define FTM_STATUS 0x50 /* Capture And Compare Status */ +#define FTM_MODE 0x54 /* Features Mode Selection */ +#define FTM_SYNC 0x58 /* Synchronization */ +#define FTM_OUTINIT 0x5C /* Initial State For Channels Output */ +#define FTM_OUTMASK 0x60 /* Output Mask */ +#define FTM_COMBINE 0x64 /* Function For Linked Channels */ +#define FTM_DEADTIME 0x68 /* Deadtime Insertion Control */ +#define FTM_EXTTRIG 0x6C /* FTM External Trigger */ +#define FTM_POL 0x70 /* Channels Polarity */ +#define FTM_FMS 0x74 /* Fault Mode Status */ +#define FTM_FILTER 0x78 /* Input Capture Filter Control */ +#define FTM_FLTCTRL 0x7C /* Fault Control */ +#define FTM_QDCTRL 0x80 /* Quadrature Decoder Control And Status */ +#define FTM_CONF 0x84 /* Configuration */ +#define FTM_FLTPOL 0x88 /* FTM Fault Input Polarity */ +#define FTM_SYNCONF 0x8C /* Synchronization Configuration */ +#define FTM_INVCTRL 0x90 /* FTM Inverting Control */ +#define FTM_SWOCTRL 0x94 /* FTM Software Output Control */ +#define FTM_PWMLOAD 0x98 /* FTM PWM Load */ + +#define FTM_SC_CLK_MASK_SHIFT 3 +#define FTM_SC_CLK_MASK (3 << FTM_SC_CLK_MASK_SHIFT) +#define FTM_SC_TOF 0x80 +#define FTM_SC_TOIE 0x40 +#define FTM_SC_CPWMS 0x20 +#define FTM_SC_CLKS 0x18 +#define FTM_SC_PS_1 0x0 +#define FTM_SC_PS_2 0x1 +#define FTM_SC_PS_4 0x2 +#define FTM_SC_PS_8 0x3 +#define FTM_SC_PS_16 0x4 +#define FTM_SC_PS_32 0x5 +#define FTM_SC_PS_64 0x6 +#define FTM_SC_PS_128 0x7 +#define FTM_SC_PS_MASK 0x7 + +#define FTM_MODE_FAULTIE 0x80 +#define FTM_MODE_FAULTM 0x60 +#define FTM_MODE_CAPTEST 0x10 +#define FTM_MODE_PWMSYNC 0x8 +#define FTM_MODE_WPDIS 0x4 +#define FTM_MODE_INIT 0x2 +#define FTM_MODE_FTMEN 0x1 + +/* NXP Errata: The PHAFLTREN and PHBFLTREN bits are tide to zero internally + * and these bits cannot be set. Flextimer cannot use Filter in + * Quadrature Decoder Mode. + * https://community.nxp.com/thread/467648#comment-1010319 + */ +#define FTM_QDCTRL_PHAFLTREN 0x80 +#define FTM_QDCTRL_PHBFLTREN 0x40 +#define FTM_QDCTRL_PHAPOL 0x20 +#define FTM_QDCTRL_PHBPOL 0x10 +#define FTM_QDCTRL_QUADMODE 0x8 +#define FTM_QDCTRL_QUADDIR 0x4 +#define FTM_QDCTRL_TOFDIR 0x2 +#define FTM_QDCTRL_QUADEN 0x1 + +#define FTM_FMS_FAULTF 0x80 +#define FTM_FMS_WPEN 0x40 +#define FTM_FMS_FAULTIN 0x10 +#define FTM_FMS_FAULTF3 0x8 +#define FTM_FMS_FAULTF2 0x4 +#define FTM_FMS_FAULTF1 0x2 +#define FTM_FMS_FAULTF0 0x1 + +#define FTM_CSC_BASE 0xC +#define FTM_CSC_MSB 0x20 +#define FTM_CSC_MSA 0x10 +#define FTM_CSC_ELSB 0x8 +#define FTM_CSC_ELSA 0x4 +#define FTM_CSC(_channel) (FTM_CSC_BASE + ((_channel) * 8)) + +#define FTM_CV_BASE 0x10 +#define FTM_CV(_channel) (FTM_CV_BASE + ((_channel) * 8)) + +#define FTM_PS_MAX 7 + +#endif From patchwork Tue Apr 2 06:30:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Breathitt Gray X-Patchwork-Id: 10881113 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EEAEC1669 for ; Tue, 2 Apr 2019 06:33:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D462B28770 for ; Tue, 2 Apr 2019 06:33:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C880A28843; Tue, 2 Apr 2019 06:33:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6D89D28770 for ; Tue, 2 Apr 2019 06:33:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=eUTIq6uxQTZXDAZa7Xjh5n5VP8a2vJBJMKsNulLG+4s=; b=MFinmGZLsUU/84 faPSRJ98Q3mcCn60pQablNn+JcFk4dyWzdF+7LYKHT/1AJWg4EexpoUv+JSWXXg1huJe5hCl7yoEH eKyyRHD+6zW9tSRZZikAwtvphMAb4s4aS2daDwIElIxoGuw6RtRH/F7xFMbZ+6mUuRpmyYOsyUqNe TNcc4MYy+EkEpy42efKW5DK2Tpjt444btZtvMXlR4C2p1oqBt9Xy8R+3pTev7d2dV7gL1quN7GDqT sbg609nm/cawrTRt6nx32RULJv4WGt1vV84NvuDLY6sdtIW12vZPCjP6OCHKWByML44YWeWYQy0sE 3h/DFBIbjiTr2CHqVC+Q==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCyj-0002HT-W9; Tue, 02 Apr 2019 06:33:02 +0000 Received: from mail-pg1-x541.google.com ([2607:f8b0:4864:20::541]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCy9-0001W5-BE for linux-arm-kernel@lists.infradead.org; Tue, 02 Apr 2019 06:33:00 +0000 Received: by mail-pg1-x541.google.com with SMTP id q1so6006914pgv.13 for ; Mon, 01 Apr 2019 23:32:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=i/73y8EqAZm2cFjbN4yCx0AeoLF3+nbdcxL9URDqVac=; b=aNhFccOka/xlrRuJPftLIHqXOitZh0phQC2lQ3PkGChkwRIjRosI0XyI9gyfBpmmDh mwD6q5eympVCFtuDYDS7MZ5+otFqk/2UhXdKnzDl6faevAwP5SVPK/3Sjhi0Vjd/lV2/ cJ0M/d7f3FT2nMwwijOhjjdcJwdn14ucBPY1QHIF89s1WyzkVZk+FtQqOko9OPOqCBjd JqsLv2KcecLh1gf/BfB7YNn/CntblZz0K6djow3ad6zxsfC8QRjRfEoDJ/HHbqb4028K s2T+ut/jh56EHMr77XeLDv6Ebu78ODs5nSYZY65J961NBoghSEgxQiyiZoEaWpfktwAC xRqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=i/73y8EqAZm2cFjbN4yCx0AeoLF3+nbdcxL9URDqVac=; b=gBE+RgW+xPjYb6pHynVkFjtMK4Ie7C5+xicCT9Ps4ZB/J4nsJ38AbrA8RKEFXbF3NO ECwubl59DQEZWqCEtSE9AMOnNNRlBxU1CF1accerxxGJWk6JEmOgKzZF5cXgXgmr2Fzj OTtBqs9VkIM6JtV9XlsJRtMPFNDSplLpyBiKL1ow6G+Chr/Qs0cFDBFM6QcOqHFbskgR o+eUY65X3niVReO4eounf0/X6w8P0LXraP0xMNwVlHaVuJYFNAeCoK5V+fb5NtznwB/v vANMCzIyt/O7WxyzWymmmx2oXyKKUYyPtTee/pFKwtz94h2gMkF8aDGsKalOy/WLD+02 /2iA== X-Gm-Message-State: APjAAAX4f5Uv5meL0I+Fhj0kG0s+bmWHp8Qaw4DWdbOROYnQ2/uajJ9l cI2r5Ijnp+jSUH3v2Jz1Zh0= X-Google-Smtp-Source: APXvYqyKElm9IyjJOGKMpNBKoxDRtGiq9ucGRXcS1J+WRSWaSRJaHfqwX/9e/qiQu+gpOBtq8j+Zbg== X-Received: by 2002:a63:e653:: with SMTP id p19mr3469003pgj.284.1554186744528; Mon, 01 Apr 2019 23:32:24 -0700 (PDT) Received: from localhost.localdomain ([2001:268:c0a5:4ce0:c70:4af9:86e2:2]) by smtp.gmail.com with ESMTPSA id a17sm19327289pfj.123.2019.04.01.23.32.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Apr 2019 23:32:24 -0700 (PDT) From: William Breathitt Gray To: gregkh@linuxfoundation.org Subject: [PATCH v10 13/18] drivers/pwm: pwm-fsl-ftm: use common header for FlexTimer #defines Date: Tue, 2 Apr 2019 15:30:48 +0900 Message-Id: X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190401_233226_062896_DC85C13F X-CRM114-Status: GOOD ( 11.48 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, benjamin.gaignard@st.com, linux-pwm@vger.kernel.org, linux-iio@vger.kernel.org, patrick.havelange@essensium.com, thierry.reding@gmail.com, pmeerw@pmeerw.net, lars@metafoo.de, daniel.lezcano@linaro.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, david@lechnology.com, William Breathitt Gray , robh+dt@kernel.org, tglx@linutronix.de, fabrice.gasnier@st.com, esben@haabendal.dk, shawnguo@kernel.org, linux-kernel@vger.kernel.org, leoyang.li@nxp.com, knaack.h@gmx.de, akpm@linux-foundation.org, linuxppc-dev@lists.ozlabs.org, jic23@kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Patrick Havelange This also fixes the wrong value for the previously defined FTM_MODE_INIT macro (it was not used). Reviewed-by: Esben Haabendal Signed-off-by: Patrick Havelange Signed-off-by: William Breathitt Gray --- drivers/pwm/pwm-fsl-ftm.c | 44 +-------------------------------------- 1 file changed, 1 insertion(+), 43 deletions(-) diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c index 883378d055c6..f21ea1b97116 100644 --- a/drivers/pwm/pwm-fsl-ftm.c +++ b/drivers/pwm/pwm-fsl-ftm.c @@ -22,51 +22,9 @@ #include #include #include +#include -#define FTM_SC 0x00 -#define FTM_SC_CLK_MASK_SHIFT 3 -#define FTM_SC_CLK_MASK (3 << FTM_SC_CLK_MASK_SHIFT) #define FTM_SC_CLK(c) (((c) + 1) << FTM_SC_CLK_MASK_SHIFT) -#define FTM_SC_PS_MASK 0x7 - -#define FTM_CNT 0x04 -#define FTM_MOD 0x08 - -#define FTM_CSC_BASE 0x0C -#define FTM_CSC_MSB BIT(5) -#define FTM_CSC_MSA BIT(4) -#define FTM_CSC_ELSB BIT(3) -#define FTM_CSC_ELSA BIT(2) -#define FTM_CSC(_channel) (FTM_CSC_BASE + ((_channel) * 8)) - -#define FTM_CV_BASE 0x10 -#define FTM_CV(_channel) (FTM_CV_BASE + ((_channel) * 8)) - -#define FTM_CNTIN 0x4C -#define FTM_STATUS 0x50 - -#define FTM_MODE 0x54 -#define FTM_MODE_FTMEN BIT(0) -#define FTM_MODE_INIT BIT(2) -#define FTM_MODE_PWMSYNC BIT(3) - -#define FTM_SYNC 0x58 -#define FTM_OUTINIT 0x5C -#define FTM_OUTMASK 0x60 -#define FTM_COMBINE 0x64 -#define FTM_DEADTIME 0x68 -#define FTM_EXTTRIG 0x6C -#define FTM_POL 0x70 -#define FTM_FMS 0x74 -#define FTM_FILTER 0x78 -#define FTM_FLTCTRL 0x7C -#define FTM_QDCTRL 0x80 -#define FTM_CONF 0x84 -#define FTM_FLTPOL 0x88 -#define FTM_SYNCONF 0x8C -#define FTM_INVCTRL 0x90 -#define FTM_SWOCTRL 0x94 -#define FTM_PWMLOAD 0x98 enum fsl_pwm_clk { FSL_PWM_CLK_SYS, From patchwork Tue Apr 2 06:30:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Breathitt Gray X-Patchwork-Id: 10881129 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 99335139A for ; Tue, 2 Apr 2019 06:47:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7E3D728553 for ; Tue, 2 Apr 2019 06:47:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7229328797; Tue, 2 Apr 2019 06:47:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 21B3628553 for ; Tue, 2 Apr 2019 06:47:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=QsI7kDil2tFlk2p0MSM3NTMvXubH8i2L06FvoKJP/y4=; b=Ph6Z/tn2hWfNHV smI+/0ITZwb7jA0VmrmjDNE1/JSGQ12qbpWDd146KL+PWeDtQtxlnEvretma/y7DH4TIV4KWEeUGh qBY36gyd13Tp+tJi3Vm9+nw95kjZV520i0rrn1ucpBzs5JZCo3JF8e6CzZEQMtaK3fEhA+3KmXK7O ourXG2AkEDTFKs6LAI+yU0BEKfyuZCrpqr/QEboSGZJFjbnBoLFhDu2uEBKHSGFtFQppI3eHTRC8v Rk6421Fcdy0QDeEyHf+MMSUUHYdYqTRjOieDRiv/YoGLVO3aBmL2zB8xYZEIG8F+wBIpbdiUPZj0o w+ktlWTIKHK8hVQsCEyQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBDCr-0001Bo-K0; Tue, 02 Apr 2019 06:47:37 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBDC8-00006k-Qj for linux-arm-kernel@bombadil.infradead.org; Tue, 02 Apr 2019 06:46:52 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=K6TR0MKKqFzv/JFHfNJSn6dvEeDvf9PGgMl6oDHsxv8=; b=tFgALHU7GB01ZjBSINRsR8nTMH naCQDKSAy6UzmooKqf8cyQkCw50mLYa1/NfrijGE27Hq8R8tHMGD+23WY18ySKF849qfX0ugiNRYm 5uQPgmq5qYP98DhpiOK8gHo61XRjnYyqznNgnpCHANbI2XUtauaa+tIQzArFmOBq+ABVUdJvxYtnl EnkJCRFz9sdzn525vXsuaDRm47crUZjeBhuimrNPr2wQtceuPY7Y6I0eU7vqjMvag1q6dfvswR7dx u6l5RYAv9nyp8Ntth0KICDCZ9IqMV5nKmLTt5gRx1e1Fc0TyOnwbJVQrr33wmHUgvHZ4XgJFF4g74 ZBMEbzEA==; Received: from mail-pg1-x544.google.com ([2607:f8b0:4864:20::544]) by casper.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCyI-0004wE-6i for linux-arm-kernel@lists.infradead.org; Tue, 02 Apr 2019 06:32:35 +0000 Received: by mail-pg1-x544.google.com with SMTP id p6so6011658pgh.9 for ; Mon, 01 Apr 2019 23:32:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=K6TR0MKKqFzv/JFHfNJSn6dvEeDvf9PGgMl6oDHsxv8=; b=tWfpYMa96jMsAtI81uTIs8XCZhfcLaS9GLo3Dd7VzEK6cFQ/WIuOeMD0Nkb2AT+Oyr 3itfZf9n5FTWIsKsP8SDdbhoMElcO8dxM23B8Fu2bJvUXGqzpSgq0+A64JOP1gxyUalV 5s2VuiyIDl+wusnIn5wMUfuEKyWs33YFC2UoREMWi1xwRVcXlgSr5jfM5lN/WJG14ukc dHGeuSTjZwpGnK5vfWlr0XHy936RKfCewLVP4MLil/9Ksbe4JtK9Kits9FFXZS2V9vZn SsSQ4XwTQbna90UmjOiXxdUwahdDmtxjbYS411OCZINncA1cIS4jgHUJJWxYF9dygxyg 6y3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=K6TR0MKKqFzv/JFHfNJSn6dvEeDvf9PGgMl6oDHsxv8=; b=Mqt9Wz4sa3vIXxCQaWekmsYRt1K2/FjSgwqh0AS09M/p5oYDy/g1YiJ+5Hd6+xeWfc ZPlA0mwpHdbRRZTUg3tY+9dvxf8axqFYNJEiqkUg9Ur3mzurz1FCm1mYDIXHzGtEWoEH EhGiXntaZ7smas+kHYZoNuc3cuS+RkIFnCJsIgMk02qL2WNV+eFzjF3HkMSy+HdVpZ1L VKjz3SxVAtL1caUn/9arHY0j03801PU/DzV97U5d9DKapxC9CnFrltBX6a0RLDX23Klx ZIoVK84CVNypwHEQ2vQDgMYlNVIB2KGcROQ6OvClIOUQuyO2M+SF8RoURsF88IiWuKBV xZMA== X-Gm-Message-State: APjAAAWYR8moPsdM3XKBda0WOE2+v+xaAPUyTRr9cTc3/dF2j1P1pTDO Kzy5hx+01rGdj9x2r8jVvIU= X-Google-Smtp-Source: APXvYqxUCf1DUO7AHQFTZnrD2AGP+LDmUH4BvwkVqG3BeFLDf7eDaNAqWzFjlu69dzeioMteXtkqHg== X-Received: by 2002:a63:e14e:: with SMTP id h14mr63716873pgk.184.1554186752567; Mon, 01 Apr 2019 23:32:32 -0700 (PDT) Received: from localhost.localdomain ([2001:268:c0a5:4ce0:c70:4af9:86e2:2]) by smtp.gmail.com with ESMTPSA id a17sm19327289pfj.123.2019.04.01.23.32.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Apr 2019 23:32:32 -0700 (PDT) From: William Breathitt Gray To: gregkh@linuxfoundation.org Subject: [PATCH v10 14/18] drivers/clocksource: timer-fsl-ftm: use common header for FlexTimer #defines Date: Tue, 2 Apr 2019 15:30:49 +0900 Message-Id: X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190402_073234_334331_58143790 X-CRM114-Status: GOOD ( 11.79 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, benjamin.gaignard@st.com, linux-pwm@vger.kernel.org, linux-iio@vger.kernel.org, patrick.havelange@essensium.com, thierry.reding@gmail.com, pmeerw@pmeerw.net, lars@metafoo.de, daniel.lezcano@linaro.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, david@lechnology.com, William Breathitt Gray , robh+dt@kernel.org, tglx@linutronix.de, fabrice.gasnier@st.com, esben@haabendal.dk, shawnguo@kernel.org, linux-kernel@vger.kernel.org, leoyang.li@nxp.com, knaack.h@gmx.de, akpm@linux-foundation.org, linuxppc-dev@lists.ozlabs.org, jic23@kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Patrick Havelange Common #defines have been moved to "linux/fsl/ftm.h". Thus making use of this file. Also FTM_SC_CLK_SHIFT has been renamed to FTM_SC_CLK_MASK_SHIFT. Reviewed-by: Esben Haabendal Signed-off-by: Patrick Havelange Signed-off-by: William Breathitt Gray --- drivers/clocksource/timer-fsl-ftm.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/clocksource/timer-fsl-ftm.c b/drivers/clocksource/timer-fsl-ftm.c index 846d18daf893..e1c34b2f53a5 100644 --- a/drivers/clocksource/timer-fsl-ftm.c +++ b/drivers/clocksource/timer-fsl-ftm.c @@ -19,20 +19,9 @@ #include #include #include +#include -#define FTM_SC 0x00 -#define FTM_SC_CLK_SHIFT 3 -#define FTM_SC_CLK_MASK (0x3 << FTM_SC_CLK_SHIFT) -#define FTM_SC_CLK(c) ((c) << FTM_SC_CLK_SHIFT) -#define FTM_SC_PS_MASK 0x7 -#define FTM_SC_TOIE BIT(6) -#define FTM_SC_TOF BIT(7) - -#define FTM_CNT 0x04 -#define FTM_MOD 0x08 -#define FTM_CNTIN 0x4C - -#define FTM_PS_MAX 7 +#define FTM_SC_CLK(c) ((c) << FTM_SC_CLK_MASK_SHIFT) struct ftm_clock_device { void __iomem *clksrc_base; From patchwork Tue Apr 2 06:30:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Breathitt Gray X-Patchwork-Id: 10881127 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 931F0139A for ; Tue, 2 Apr 2019 06:47:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7640428553 for ; Tue, 2 Apr 2019 06:47:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6A18728797; Tue, 2 Apr 2019 06:47:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 03B9A28553 for ; Tue, 2 Apr 2019 06:47:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=ya3B0J6adnTeE6NhXr+VG0K5PZ3Zc0L/fLNp6utbf9M=; b=bdO5ro4yKKC+sq YGBQR24+q9fKZ5r1ERpyyscjqVgalhhqoAmGrObGs1Vvfq+d0U3ULGOmKo+FqlG37k5VCg9cgbdDM DzegIyJ9Z1Mas8z6Rm4Cm1D6oOXUOjvby1QicVqUmPMWTsJNSo+fHbIWoV6TJV7fPZtUKuJgFpS86 VHLRsljEIIQLqD7y6qs6I3Fu/aQtReKv8vDKObjF7B6bauldJXrn6pTRb/bdy+Pfr4529vgYWcaHE cCWYmpKRLXIi7TOyNGMDsDXWLo1ykZXdySjOacWRdC4DpsSbbwcmKdHVKsE571w4RFtgqh9MmDwgy ZhxR2V6KCaKc1bExbiuw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBDCf-0000xa-DR; Tue, 02 Apr 2019 06:47:25 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBDC7-00006k-Ov for linux-arm-kernel@bombadil.infradead.org; Tue, 02 Apr 2019 06:46:51 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=NHS2OJqKj6xRANV1sj2z+WTKmkExPEvasKWv9BLPxUI=; b=m28897psEhsFmJ8KhqRaZRGqsI P16kbrscuT9doSjjnnd+60yyPXm5PLb7nC7TBz1pIGPiZrFrQoWFxKM2jnFpgu/bKc2X32OSMhOlQ 1hS1HHLhu/Ix9gTIcX2yPzDJI9n/pMlvFbtWOGXkNxL14CG9srGlSe2UKT7P5ou+PdaBojsNcs4ki LlVk2yqrhaqhrKaTCRE06fXB8WibaleNxbk07dpeXdUyj6CMv8gKc7gHlFjIp9ewqEoFGoEiLHnTc NfiItyRs6e/fbEm6bS/IUEeTge9MYCvSUCSlxVu3tJjdPlCk1woDN/Cm+BKRzgvZZG5pv9MDZ7Uoa TKz19+dg==; Received: from mail-pf1-x441.google.com ([2607:f8b0:4864:20::441]) by casper.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCyQ-0004xr-Vt for linux-arm-kernel@lists.infradead.org; Tue, 02 Apr 2019 06:32:44 +0000 Received: by mail-pf1-x441.google.com with SMTP id t21so5839205pfe.2 for ; Mon, 01 Apr 2019 23:32:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=NHS2OJqKj6xRANV1sj2z+WTKmkExPEvasKWv9BLPxUI=; b=OtEgzesw2B0IUv5mVHvaxNwujAktKsr5w00A91ZxGIV7gsSSslrvvQxf8VWtStCEDx 7082XQx6h/pRgh6LjRwyESCB3Gv30/T5Ir2zuFlTjt6qawwCZBgxeaVsThf/GY/aLEVl CGwcgudKMRvXmGv5Y+S9vKkzW5f8CZVEeTLHWxgcLc/2MlOEOpDp3zd8RA6wvYDHxCpV LgJI1oDSPvSxazZrqSe3lLHlIvG1JUNwvKhHeBl1Kvr4yeae9TH4B4D8LuR8OEylh0qV XP25kZvfRSgiEAN/nla8HGltQFI6dLx+Ji69nS25sPQQhbozx3hTyasVMWzBOhUrUcnO NBkA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=NHS2OJqKj6xRANV1sj2z+WTKmkExPEvasKWv9BLPxUI=; b=nOIP+/rn23DFWAt+r+JjjeAnAm0PQERG0Z/7H0GcDvzS7HNvlq6JbhDSNzD0d5xuyB b+503bWVRLbh2m0zAiN9dl4OTXO7Uu7glO+X4xtJ1o4BRtaRa9Z2j2Ijc1YaIyduckb6 vqwzY9Q5kHUdJmxQPTq5dPa8gEDIyN+pNhCoiaIbSMj5stjJlF++gt+mmmUXXIYa1/qr Wmk2z3jssCx1ft2OrshcvUzrUL+/9682I/q0FFhtJX2qqD9TyKU71BoittQtfdk3wp6N ZmgpPyQFwP0vT4t/uE1NksAusqauTH4NPHQUJH4QEQZP7skBri5JcMtqAvKh73EW9VL2 n6HQ== X-Gm-Message-State: APjAAAUagDZRa6Ntg8vzm98nBn4kPBCe6frpKTxiAbSED09qc9jBFDJ5 NnT+eBQOCiUPV0E+D6VmDrk= X-Google-Smtp-Source: APXvYqwp7lbXFM74wVWgWuUn8e2AojrE5yckHl/rYqUc14StMv0sEf9qHtA/NNgvqW3iXpZdFch9yQ== X-Received: by 2002:a63:6c87:: with SMTP id h129mr65618774pgc.190.1554186761385; Mon, 01 Apr 2019 23:32:41 -0700 (PDT) Received: from localhost.localdomain ([2001:268:c0a5:4ce0:c70:4af9:86e2:2]) by smtp.gmail.com with ESMTPSA id a17sm19327289pfj.123.2019.04.01.23.32.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Apr 2019 23:32:40 -0700 (PDT) From: William Breathitt Gray To: gregkh@linuxfoundation.org Subject: [PATCH v10 15/18] dt-bindings: counter: ftm-quaddec Date: Tue, 2 Apr 2019 15:30:50 +0900 Message-Id: X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190402_073243_125189_F9D88DEF X-CRM114-Status: GOOD ( 14.34 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, benjamin.gaignard@st.com, linux-pwm@vger.kernel.org, linux-iio@vger.kernel.org, patrick.havelange@essensium.com, thierry.reding@gmail.com, pmeerw@pmeerw.net, lars@metafoo.de, daniel.lezcano@linaro.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, david@lechnology.com, William Breathitt Gray , robh+dt@kernel.org, tglx@linutronix.de, fabrice.gasnier@st.com, esben@haabendal.dk, shawnguo@kernel.org, linux-kernel@vger.kernel.org, leoyang.li@nxp.com, knaack.h@gmx.de, akpm@linux-foundation.org, linuxppc-dev@lists.ozlabs.org, jic23@kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Patrick Havelange FlexTimer quadrature decoder driver. Reviewed-by: Esben Haabendal Signed-off-by: Patrick Havelange Signed-off-by: William Breathitt Gray --- .../bindings/counter/ftm-quaddec.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 Documentation/devicetree/bindings/counter/ftm-quaddec.txt diff --git a/Documentation/devicetree/bindings/counter/ftm-quaddec.txt b/Documentation/devicetree/bindings/counter/ftm-quaddec.txt new file mode 100644 index 000000000000..4d18cd722074 --- /dev/null +++ b/Documentation/devicetree/bindings/counter/ftm-quaddec.txt @@ -0,0 +1,18 @@ +FlexTimer Quadrature decoder counter + +This driver exposes a simple counter for the quadrature decoder mode. + +Required properties: +- compatible: Must be "fsl,ftm-quaddec". +- reg: Must be set to the memory region of the flextimer. + +Optional property: +- big-endian: Access the device registers in big-endian mode. + +Example: + counter0: counter@29d0000 { + compatible = "fsl,ftm-quaddec"; + reg = <0x0 0x29d0000 0x0 0x10000>; + big-endian; + status = "disabled"; + }; From patchwork Tue Apr 2 06:30:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Breathitt Gray X-Patchwork-Id: 10881125 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0E43F13B5 for ; Tue, 2 Apr 2019 06:47:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E545828553 for ; Tue, 2 Apr 2019 06:47:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D71A92878F; Tue, 2 Apr 2019 06:47:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E6B8028553 for ; Tue, 2 Apr 2019 06:47:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=gZSYH3/Nvk2gtycCYInN3evPPmVIE6ecEuVgp6X2HdA=; b=Bm6CXxjU1BRS2r EWyI9TOL+lb6c6+NIevOrh5h9jpUoSIlTat2cwtdOVRJ19xCHySLYLhvkfsTXyY7/G106MsAvUKPN ST5jBeb+Jw4RDDPU/9n17bWjU+4unc3ZsxOlgtFgKgj37zPeRqJE9OM6eC7LJPlSvETPUdHHP4fuF 1GIa+pRHS9M1iXwXKa0jiSn7+8JSGhj7i+Mr2INevibfd1XWZwp5fl4BpMCcTv74gQb+2Slk5+G6Y vtiBDvCgcblQDoLfg0gXwVvlHXLVo2+Nu/XEjCNXgPOk/YZ3PfDrsemEtkYdyLJNmpNEx8LlL8bb2 rh4e9bAcrvm3mL41V/vg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBDCQ-0000eK-Oo; Tue, 02 Apr 2019 06:47:10 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBDC6-00006k-Ju for linux-arm-kernel@bombadil.infradead.org; Tue, 02 Apr 2019 06:46:50 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=nwor2TQ69h46++6cxhPPy3at6el1x9XKSImuwCci68E=; b=WcNH2G4iyhxqk2zQW1f2QW6J1/ Q/9Ouv+p7z8eTWtuSlUgZ+N3jEzN6me6B5Uhja9kQFVqUJQ/HtS+bKp0rE9DFcSJGNK+37VW1/xEc mJsJYOso3RVYSuAKzDNXfgzo2d5phtTIU6f1iIcVdoZ7+HNtn9LLFO1KjBMfdS+IXygfKJAAID3Mg AjZhvxAgNWUTT5L7o5+It/EWlxj9ZIp7HXUqweMs34MA03M1BuOWWmPmf+/fmutmkchcSQjeMnN7Z Y1KMCU/z5PsWf2Qt/1+LPnrPYWYNCzfULljX1hXVK6wyvCl42XwlTcmNnsEFWvBgtefqDyWAawMvj Fl1X681Q==; Received: from mail-pf1-x442.google.com ([2607:f8b0:4864:20::442]) by casper.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCyc-0004zG-IX for linux-arm-kernel@lists.infradead.org; Tue, 02 Apr 2019 06:32:56 +0000 Received: by mail-pf1-x442.google.com with SMTP id t21so5839459pfe.2 for ; Mon, 01 Apr 2019 23:32:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=nwor2TQ69h46++6cxhPPy3at6el1x9XKSImuwCci68E=; b=CblCPX8onk9DYKuc+HjlJIXuJIrng/A4a0/LnBAnQ5cmQpDYr6btfqSlDmpIwh1x2g NPmKF7s4HJFZT7ECXa72j61e2cqTYWiNFbzmB3YkavCmvDXSzP8BgUS+IwcEtXdpDJFI 3Dd5sHmch2HZVDcC9vTpUOPFk1RalTNj/TjLYjJczxyn4FqOd0C9tiBC0MSBJvaZE8OY jgmd1xCNFmXzk6Lz9oUzEPJr0/qRHEK2UXLUk7obX9Y5d7VEEq7XwoRYNQQxQ/jQ82up jfvLAUqwHRJ2zUrDUFuuxrGpkV4GYWPv8HSF1cH+3ND/uP02+K1uol+xwUxV5Xz+TyI1 UNvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=nwor2TQ69h46++6cxhPPy3at6el1x9XKSImuwCci68E=; b=IJ/Os7o6dVXbK79+Z29nh62AcgilqIeVjhOPUVeQEc5SwP+TvtSt+WUM3Uj6S70p2N dC9fZ3Z5kdqNW2AoZU3qjOIO+r9egNwrAt00PYuuLhPTkiy96JjfRmsep1O2/eC9vKJc PFg/RZnGG9GQCyjfZ9KpkPETElx5zTIPMVcvtfJGijcnlmUfizsSvPRhqJquxAbr2Emo H/ClBx8UxtneRGURI6MP3w9km3A7XTlVB93BH8KHfMk5QCm9wgqYtRTHE1F2I3cWwBWk XNCxfnkr7rnN9oyQyXZaay6SyzOBZPYNI8TslUlAjUP0JIy0kLKqjj//EX/mACl6MlZo LGSA== X-Gm-Message-State: APjAAAVjtWkYeT0pGlsGvymi8R6iG9MshRKMMptlnfkrzYYseUQkvXZd GgbsUT5XJugSn5yHwTnEuhs= X-Google-Smtp-Source: APXvYqxs4V/KKivEnwjwV5el443HKUgVOnNXeG3nG5I9wTJKAXaSTDAN2smIttyiE8VOryoJR1n4FQ== X-Received: by 2002:a63:700f:: with SMTP id l15mr19839899pgc.3.1554186772718; Mon, 01 Apr 2019 23:32:52 -0700 (PDT) Received: from localhost.localdomain ([2001:268:c0a5:4ce0:c70:4af9:86e2:2]) by smtp.gmail.com with ESMTPSA id a17sm19327289pfj.123.2019.04.01.23.32.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Apr 2019 23:32:52 -0700 (PDT) From: William Breathitt Gray To: gregkh@linuxfoundation.org Subject: [PATCH v10 16/18] counter: add FlexTimer Module Quadrature decoder counter driver Date: Tue, 2 Apr 2019 15:30:51 +0900 Message-Id: <9add1082c3c63012a13a5f9af5c6454afed26918.1554184734.git.vilhelm.gray@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190402_073254_728063_CE95E0E3 X-CRM114-Status: GOOD ( 28.71 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, benjamin.gaignard@st.com, linux-pwm@vger.kernel.org, linux-iio@vger.kernel.org, patrick.havelange@essensium.com, thierry.reding@gmail.com, pmeerw@pmeerw.net, lars@metafoo.de, daniel.lezcano@linaro.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, david@lechnology.com, William Breathitt Gray , robh+dt@kernel.org, tglx@linutronix.de, fabrice.gasnier@st.com, esben@haabendal.dk, shawnguo@kernel.org, linux-kernel@vger.kernel.org, leoyang.li@nxp.com, knaack.h@gmx.de, akpm@linux-foundation.org, linuxppc-dev@lists.ozlabs.org, jic23@kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Patrick Havelange This driver exposes the counter for the quadrature decoder of the FlexTimer Module, present in the LS1021A soc. Signed-off-by: Patrick Havelange Signed-off-by: William Breathitt Gray --- drivers/counter/Kconfig | 9 + drivers/counter/Makefile | 1 + drivers/counter/ftm-quaddec.c | 356 ++++++++++++++++++++++++++++++++++ 3 files changed, 366 insertions(+) create mode 100644 drivers/counter/ftm-quaddec.c diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig index 87c491a19c63..233ac305d878 100644 --- a/drivers/counter/Kconfig +++ b/drivers/counter/Kconfig @@ -48,4 +48,13 @@ config STM32_LPTIMER_CNT To compile this driver as a module, choose M here: the module will be called stm32-lptimer-cnt. +config FTM_QUADDEC + tristate "Flex Timer Module Quadrature decoder driver" + help + Select this option to enable the Flex Timer Quadrature decoder + driver. + + To compile this driver as a module, choose M here: the + module will be called ftm-quaddec. + endif # COUNTER diff --git a/drivers/counter/Makefile b/drivers/counter/Makefile index 5589976d37f8..0c9e622a6bea 100644 --- a/drivers/counter/Makefile +++ b/drivers/counter/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_COUNTER) += counter.o obj-$(CONFIG_104_QUAD_8) += 104-quad-8.o obj-$(CONFIG_STM32_TIMER_CNT) += stm32-timer-cnt.o obj-$(CONFIG_STM32_LPTIMER_CNT) += stm32-lptimer-cnt.o +obj-$(CONFIG_FTM_QUADDEC) += ftm-quaddec.o diff --git a/drivers/counter/ftm-quaddec.c b/drivers/counter/ftm-quaddec.c new file mode 100644 index 000000000000..c83c8875bf82 --- /dev/null +++ b/drivers/counter/ftm-quaddec.c @@ -0,0 +1,356 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Flex Timer Module Quadrature decoder + * + * This module implements a driver for decoding the FTM quadrature + * of ex. a LS1021A + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define FTM_FIELD_UPDATE(ftm, offset, mask, val) \ + ({ \ + uint32_t flags; \ + ftm_read(ftm, offset, &flags); \ + flags &= ~mask; \ + flags |= FIELD_PREP(mask, val); \ + ftm_write(ftm, offset, flags); \ + }) + +struct ftm_quaddec { + struct counter_device counter; + struct platform_device *pdev; + void __iomem *ftm_base; + bool big_endian; + struct mutex ftm_quaddec_mutex; +}; + +static void ftm_read(struct ftm_quaddec *ftm, uint32_t offset, uint32_t *data) +{ + if (ftm->big_endian) + *data = ioread32be(ftm->ftm_base + offset); + else + *data = ioread32(ftm->ftm_base + offset); +} + +static void ftm_write(struct ftm_quaddec *ftm, uint32_t offset, uint32_t data) +{ + if (ftm->big_endian) + iowrite32be(data, ftm->ftm_base + offset); + else + iowrite32(data, ftm->ftm_base + offset); +} + +/* Hold mutex before modifying write protection state */ +static void ftm_clear_write_protection(struct ftm_quaddec *ftm) +{ + uint32_t flag; + + /* First see if it is enabled */ + ftm_read(ftm, FTM_FMS, &flag); + + if (flag & FTM_FMS_WPEN) + FTM_FIELD_UPDATE(ftm, FTM_MODE, FTM_MODE_WPDIS, 1); +} + +static void ftm_set_write_protection(struct ftm_quaddec *ftm) +{ + FTM_FIELD_UPDATE(ftm, FTM_FMS, FTM_FMS_WPEN, 1); +} + +static void ftm_reset_counter(struct ftm_quaddec *ftm) +{ + /* Reset hardware counter to CNTIN */ + ftm_write(ftm, FTM_CNT, 0x0); +} + +static void ftm_quaddec_init(struct ftm_quaddec *ftm) +{ + ftm_clear_write_protection(ftm); + + /* + * Do not write in the region from the CNTIN register through the + * PWMLOAD register when FTMEN = 0. + * Also reset other fields to zero + */ + ftm_write(ftm, FTM_MODE, FTM_MODE_FTMEN); + ftm_write(ftm, FTM_CNTIN, 0x0000); + ftm_write(ftm, FTM_MOD, 0xffff); + ftm_write(ftm, FTM_CNT, 0x0); + /* Set prescaler, reset other fields to zero */ + ftm_write(ftm, FTM_SC, FTM_SC_PS_1); + + /* Select quad mode, reset other fields to zero */ + ftm_write(ftm, FTM_QDCTRL, FTM_QDCTRL_QUADEN); + + /* Unused features and reset to default section */ + ftm_write(ftm, FTM_POL, 0x0); + ftm_write(ftm, FTM_FLTCTRL, 0x0); + ftm_write(ftm, FTM_SYNCONF, 0x0); + ftm_write(ftm, FTM_SYNC, 0xffff); + + /* Lock the FTM */ + ftm_set_write_protection(ftm); +} + +static void ftm_quaddec_disable(struct ftm_quaddec *ftm) +{ + ftm_clear_write_protection(ftm); + ftm_write(ftm, FTM_MODE, 0); + ftm_write(ftm, FTM_QDCTRL, 0); + /* + * This is enough to disable the counter. No clock has been + * selected by writing to FTM_SC in init() + */ + ftm_set_write_protection(ftm); +} + +static int ftm_quaddec_get_prescaler(struct counter_device *counter, + struct counter_count *count, + size_t *cnt_mode) +{ + struct ftm_quaddec *ftm = counter->priv; + uint32_t scflags; + + ftm_read(ftm, FTM_SC, &scflags); + + *cnt_mode = FIELD_GET(FTM_SC_PS_MASK, scflags); + + return 0; +} + +static int ftm_quaddec_set_prescaler(struct counter_device *counter, + struct counter_count *count, + size_t cnt_mode) +{ + struct ftm_quaddec *ftm = counter->priv; + + mutex_lock(&ftm->ftm_quaddec_mutex); + + ftm_clear_write_protection(ftm); + FTM_FIELD_UPDATE(ftm, FTM_SC, FTM_SC_PS_MASK, cnt_mode); + ftm_set_write_protection(ftm); + + /* Also resets the counter as it is undefined anyway now */ + ftm_reset_counter(ftm); + + mutex_unlock(&ftm->ftm_quaddec_mutex); + return 0; +} + +static const char * const ftm_quaddec_prescaler[] = { + "1", "2", "4", "8", "16", "32", "64", "128" +}; + +static struct counter_count_enum_ext ftm_quaddec_prescaler_enum = { + .items = ftm_quaddec_prescaler, + .num_items = ARRAY_SIZE(ftm_quaddec_prescaler), + .get = ftm_quaddec_get_prescaler, + .set = ftm_quaddec_set_prescaler +}; + +enum ftm_quaddec_synapse_action { + FTM_QUADDEC_SYNAPSE_ACTION_BOTH_EDGES, +}; + +static enum counter_synapse_action ftm_quaddec_synapse_actions[] = { + [FTM_QUADDEC_SYNAPSE_ACTION_BOTH_EDGES] = + COUNTER_SYNAPSE_ACTION_BOTH_EDGES +}; + +enum ftm_quaddec_count_function { + FTM_QUADDEC_COUNT_ENCODER_MODE_1, +}; + +static const enum counter_count_function ftm_quaddec_count_functions[] = { + [FTM_QUADDEC_COUNT_ENCODER_MODE_1] = + COUNTER_COUNT_FUNCTION_QUADRATURE_X4 +}; + +static int ftm_quaddec_count_read(struct counter_device *counter, + struct counter_count *count, + struct counter_count_read_value *val) +{ + struct ftm_quaddec *const ftm = counter->priv; + uint32_t cntval; + + ftm_read(ftm, FTM_CNT, &cntval); + + counter_count_read_value_set(val, COUNTER_COUNT_POSITION, &cntval); + + return 0; +} + +static int ftm_quaddec_count_write(struct counter_device *counter, + struct counter_count *count, + struct counter_count_write_value *val) +{ + struct ftm_quaddec *const ftm = counter->priv; + u32 cnt; + int err; + + err = counter_count_write_value_get(&cnt, COUNTER_COUNT_POSITION, val); + if (err) + return err; + + if (cnt != 0) { + dev_warn(&ftm->pdev->dev, "Can only accept '0' as new counter value\n"); + return -EINVAL; + } + + ftm_reset_counter(ftm); + + return 0; +} + +static int ftm_quaddec_count_function_get(struct counter_device *counter, + struct counter_count *count, + size_t *function) +{ + *function = FTM_QUADDEC_COUNT_ENCODER_MODE_1; + + return 0; +} + +static int ftm_quaddec_action_get(struct counter_device *counter, + struct counter_count *count, + struct counter_synapse *synapse, + size_t *action) +{ + *action = FTM_QUADDEC_SYNAPSE_ACTION_BOTH_EDGES; + + return 0; +} + +static const struct counter_ops ftm_quaddec_cnt_ops = { + .count_read = ftm_quaddec_count_read, + .count_write = ftm_quaddec_count_write, + .function_get = ftm_quaddec_count_function_get, + .action_get = ftm_quaddec_action_get, +}; + +static struct counter_signal ftm_quaddec_signals[] = { + { + .id = 0, + .name = "Channel 1 Phase A" + }, + { + .id = 1, + .name = "Channel 1 Phase B" + } +}; + +static struct counter_synapse ftm_quaddec_count_synapses[] = { + { + .actions_list = ftm_quaddec_synapse_actions, + .num_actions = ARRAY_SIZE(ftm_quaddec_synapse_actions), + .signal = &ftm_quaddec_signals[0] + }, + { + .actions_list = ftm_quaddec_synapse_actions, + .num_actions = ARRAY_SIZE(ftm_quaddec_synapse_actions), + .signal = &ftm_quaddec_signals[1] + } +}; + +static const struct counter_count_ext ftm_quaddec_count_ext[] = { + COUNTER_COUNT_ENUM("prescaler", &ftm_quaddec_prescaler_enum), + COUNTER_COUNT_ENUM_AVAILABLE("prescaler", &ftm_quaddec_prescaler_enum), +}; + +static struct counter_count ftm_quaddec_counts = { + .id = 0, + .name = "Channel 1 Count", + .functions_list = ftm_quaddec_count_functions, + .num_functions = ARRAY_SIZE(ftm_quaddec_count_functions), + .synapses = ftm_quaddec_count_synapses, + .num_synapses = ARRAY_SIZE(ftm_quaddec_count_synapses), + .ext = ftm_quaddec_count_ext, + .num_ext = ARRAY_SIZE(ftm_quaddec_count_ext) +}; + +static int ftm_quaddec_probe(struct platform_device *pdev) +{ + struct ftm_quaddec *ftm; + + struct device_node *node = pdev->dev.of_node; + struct resource *io; + int ret; + + ftm = devm_kzalloc(&pdev->dev, sizeof(*ftm), GFP_KERNEL); + if (!ftm) + return -ENOMEM; + + platform_set_drvdata(pdev, ftm); + + io = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!io) { + dev_err(&pdev->dev, "Failed to get memory region\n"); + return -ENODEV; + } + + ftm->pdev = pdev; + ftm->big_endian = of_property_read_bool(node, "big-endian"); + ftm->ftm_base = devm_ioremap(&pdev->dev, io->start, resource_size(io)); + + if (!ftm->ftm_base) { + dev_err(&pdev->dev, "Failed to map memory region\n"); + return -EINVAL; + } + ftm->counter.name = dev_name(&pdev->dev); + ftm->counter.parent = &pdev->dev; + ftm->counter.ops = &ftm_quaddec_cnt_ops; + ftm->counter.counts = &ftm_quaddec_counts; + ftm->counter.num_counts = 1; + ftm->counter.signals = ftm_quaddec_signals; + ftm->counter.num_signals = ARRAY_SIZE(ftm_quaddec_signals); + ftm->counter.priv = ftm; + + mutex_init(&ftm->ftm_quaddec_mutex); + + ftm_quaddec_init(ftm); + + ret = counter_register(&ftm->counter); + if (ret) + ftm_quaddec_disable(ftm); + + return ret; +} + +static int ftm_quaddec_remove(struct platform_device *pdev) +{ + struct ftm_quaddec *ftm = platform_get_drvdata(pdev); + + counter_unregister(&ftm->counter); + + ftm_quaddec_disable(ftm); + + return 0; +} + +static const struct of_device_id ftm_quaddec_match[] = { + { .compatible = "fsl,ftm-quaddec" }, + {}, +}; + +static struct platform_driver ftm_quaddec_driver = { + .driver = { + .name = "ftm-quaddec", + .of_match_table = ftm_quaddec_match, + }, + .probe = ftm_quaddec_probe, + .remove = ftm_quaddec_remove, +}; + +module_platform_driver(ftm_quaddec_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Kjeld Flarup X-Patchwork-Id: 10881123 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 92B1C13B5 for ; Tue, 2 Apr 2019 06:47:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 76CB428553 for ; Tue, 2 Apr 2019 06:47:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 694CD2878F; Tue, 2 Apr 2019 06:47:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0D03828553 for ; Tue, 2 Apr 2019 06:47:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=7yuPMKdEOSbTRRJduCJkuNk/rPlkauEvpcxNcm23OxQ=; b=CiHmXk8EuLsNWW XDBw0y7nvH8BUfHO6eBP0DY4l6AZ25kVlYlsc7s3vgJGCsusev+PzbU4PjSeaG13YQ9Zb4SkWgznB AX7TgSC0Ta7k2GvJodx3O57f368PyMbYtUw2hjC3Djelwiq2k5lKG1i+MUeZQJL6vTyeEChogiCpR /Wt4ZG4I0mvhW4cKL964pBdciB7nrgjhTMqmljDxZer85fT7iv8I4NNZ571/mwbEza5B+Ucr866gi LWgVd52BZGN7a9MuOe4InwVm4TN4CN2CGiAxr3+Sle8VV0HV+bYS1WKwsTS7ohUulIColBwonj5pt 1IrBULbepPtHQUn/cTRA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBDCE-0000M7-LI; Tue, 02 Apr 2019 06:46:58 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBDC5-00006k-JA for linux-arm-kernel@bombadil.infradead.org; Tue, 02 Apr 2019 06:46:49 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=dHZ0ys7QT6DS6LbvlqKk410H9kGaWEJZlcsSa1/ZJoE=; b=Sh43jCgIh0HB4atIKzV55QeqXW J/N161DZeDwfo/augrbc3smaQTDgAUu2lhsiA0ttZza5pjFyIm8npJCmfDv7l+g07V1jGhckfh6rh 78LtaDlAe7lhdBQS+G2HevmjFp5gMeAm6XtfnlHzGhzTbqA+4lT/9cNQWgJcIr1/TA4CiIdX2SA/F zYVZzNRaDUuuj5LRIMOQgCJQd+4XVYaq8zb0yONt5yV7NX+LJHHybYTEBd+45AEmv2vb++8WQOsKb 4rZW0/Atf97cm0/8r525vQqAF3uNolzEPcsxi1ie/hGrPfzoRGi141YQ0abkBh1a9ZzrN7+zLpf9d 9VA9U/WA==; Received: from mail-pf1-x443.google.com ([2607:f8b0:4864:20::443]) by casper.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCym-0004zz-52 for linux-arm-kernel@lists.infradead.org; Tue, 02 Apr 2019 06:33:05 +0000 Received: by mail-pf1-x443.google.com with SMTP id 9so5815731pfj.13 for ; Mon, 01 Apr 2019 23:33:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=dHZ0ys7QT6DS6LbvlqKk410H9kGaWEJZlcsSa1/ZJoE=; b=FX6JIZqz0xEX86ficCeBVsIIY/NYiOZpzl/XHvjJ6TU8RYpOvRwUlwPkKEFUL9uOR/ moSQzqJ5yuOrjJAYZeym+ZuP9M3TPlLGgtRtvEwF1lngzxMM/4SF6R68O8+LweVtSCK6 hq0Dv6XVHuw2EXQ2Iduf1MctTp41niv4mFVEGRR5V2mSNK2s6o4dbCzkRG4wdDmV0RgO Okbavz9RaJc/Vn7fTxoLfkMdVPcAuJp+zVs8N1pqSx+nMoHVAOiecRJQ23BMlsCnN71d xcwhGHgckkSshU9sUBZqhd86yQk+TLDvcK6Gpc/O2MdIth2kFA2ymvxtS8JZH0+zqaNM reDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=dHZ0ys7QT6DS6LbvlqKk410H9kGaWEJZlcsSa1/ZJoE=; b=PdIdCZHIHRiWvp8FPnfjbssN+YvBSrFlq/D/wV9VLbSTeUR4tAhI5b09I/kJwgmyyj bDPuL0ixKqhpyt5WAnouQ3+MpRMYisK4XVGfUeRI+WJyCuqIvTZsjUlushN+JMaGEYuq 4yoHqa8xJU/wsVK8W20hNPx5Szl+yoxk2pc4FHXGTizM6dt4C+7EH8F0dIvGY2MOdgxr qOE2ebPV22gvdVDtJR2Zrh1W6zfR6O/aFq3KG0/RpUBJs1c4EFz6L8ciJ05txWCGRVm6 YjPOM+zYb+whlan0jGDeCiD6HZB3RwaC76vPHWLm/nsrvgUMTdRRnNfVhULOQiVL/MZf 2qGQ== X-Gm-Message-State: APjAAAVyYzwG6HTWyY1ju1j3/qSrlAzMXF5cYWKeWM/fvYwi7DT5n1Im A04h4PNK3JqS1SXJa8jLy1w= X-Google-Smtp-Source: APXvYqzxU/1cn6HqqwqwGRcNz4T2n8y3agd6WUAA5BYTS+jULwsi9YHs0mVX43LpBeAFRJ3Mo+hlOA== X-Received: by 2002:a63:7444:: with SMTP id e4mr46906923pgn.261.1554186782569; Mon, 01 Apr 2019 23:33:02 -0700 (PDT) Received: from localhost.localdomain ([2001:268:c0a5:4ce0:c70:4af9:86e2:2]) by smtp.gmail.com with ESMTPSA id a17sm19327289pfj.123.2019.04.01.23.32.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Apr 2019 23:33:02 -0700 (PDT) From: William Breathitt Gray To: gregkh@linuxfoundation.org Subject: [PATCH v10 17/18] counter: ftm-quaddec: Documentation: Add specific counter sysfs documentation Date: Tue, 2 Apr 2019 15:30:52 +0900 Message-Id: <3273619b1e22d8dbcd0beccd9a887f14a8aa38e0.1554184734.git.vilhelm.gray@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190402_073304_260998_910980E0 X-CRM114-Status: GOOD ( 14.21 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, benjamin.gaignard@st.com, linux-pwm@vger.kernel.org, linux-iio@vger.kernel.org, patrick.havelange@essensium.com, thierry.reding@gmail.com, pmeerw@pmeerw.net, lars@metafoo.de, daniel.lezcano@linaro.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, david@lechnology.com, William Breathitt Gray , robh+dt@kernel.org, tglx@linutronix.de, fabrice.gasnier@st.com, esben@haabendal.dk, shawnguo@kernel.org, linux-kernel@vger.kernel.org, leoyang.li@nxp.com, knaack.h@gmx.de, akpm@linux-foundation.org, linuxppc-dev@lists.ozlabs.org, jic23@kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Patrick Havelange This adds documentation for the specific prescaler entry. Signed-off-by: Patrick Havelange Signed-off-by: William Breathitt Gray --- .../ABI/testing/sysfs-bus-counter-ftm-quaddec | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-counter-ftm-quaddec diff --git a/Documentation/ABI/testing/sysfs-bus-counter-ftm-quaddec b/Documentation/ABI/testing/sysfs-bus-counter-ftm-quaddec new file mode 100644 index 000000000000..7d2e7b363467 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-counter-ftm-quaddec @@ -0,0 +1,16 @@ +What: /sys/bus/counter/devices/counterX/countY/prescaler_available +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Discrete set of available values for the respective Count Y + configuration are listed in this file. Values are delimited by + newline characters. + +What: /sys/bus/counter/devices/counterX/countY/prescaler +KernelVersion: 5.2 +Contact: linux-iio@vger.kernel.org +Description: + Configure the prescaler value associated with Count Y. + On the FlexTimer, the counter clock source passes through a + prescaler (i.e. a counter). This acts like a clock + divider. From patchwork Tue Apr 2 06:30:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Breathitt Gray X-Patchwork-Id: 10881121 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7DFEB139A for ; Tue, 2 Apr 2019 06:46:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 612C028553 for ; Tue, 2 Apr 2019 06:46:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5462F2878F; Tue, 2 Apr 2019 06:46:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,DKIM_VALID,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 02EDF28553 for ; Tue, 2 Apr 2019 06:46:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=3heWHn7ssZ6P+Kct+oJ95aG3PnP+GVthtoaRgdeG/R8=; b=q8CtfNaVEOYxRv esC4i4hEfpFZd6w+DHKi229bqPnzqKX848bgqNgShxQK8blziLu29ak0k0gaLBjGWjsYuboOXK9bJ nN51B+qHhp1UWVlBTO6WahPw2BSjtKIfIGiF7i8QSLS+0nAcvwCImU4SasS4VKmpv70u3/Y/9OedX e45Z5yfmNneya25fGkRiqqYel2HMJbna8nGOjDuR4kymoSJseuVe8Ru78+BRi+ob5XMK+ZaGO42Zl 6cHh2ZCx9K6sz/KnJmExNM8qy5wDw4LEXT3ey8Scrw245Gv5are66FjWQeMzO5LQYTPSfYMh8/Ag5 FjL05+pkLBqzx3rUKTKg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBDC6-00009j-FW; Tue, 02 Apr 2019 06:46:50 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBDC4-00006k-HV for linux-arm-kernel@bombadil.infradead.org; Tue, 02 Apr 2019 06:46:48 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=/SViyYrS1FftN56nFj/LUBMdZmL6citnsb/V8UFB/zw=; b=uhUN26y/KEVLFFm6fNgSImxRda lqgQiShIRgVLaCXO1Z/J28y40XYC09yC/z9iKGrR6mBnPMSP+v2AOz41EZyJBq5KlD5KjyHlHyZ7Q Kvf1CiOhyuXBU502lF5wcTSxAmvcGL1ZCzibaifH0v7vLySxKL91pVq4LsPJJT9nxXjBDoHzyhQAF 62DiapJN8kB3rhB7SwEjVtx4UQcTxVcbvOhbAWfwGhzo3H48cedsNqvtk0unLJConmhe683oGHXy2 HyCuGmjge7clb13uJ/mHxslTTzoAdDc83fbJOjgvUnRhkxYOEIYJmgonPEtGaXjb0owbAdUROQu6D cD/MMWog==; Received: from mail-pl1-x641.google.com ([2607:f8b0:4864:20::641]) by casper.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBCyu-000510-Ae for linux-arm-kernel@lists.infradead.org; Tue, 02 Apr 2019 06:33:14 +0000 Received: by mail-pl1-x641.google.com with SMTP id m10so5728839plt.10 for ; Mon, 01 Apr 2019 23:33:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/SViyYrS1FftN56nFj/LUBMdZmL6citnsb/V8UFB/zw=; b=fhk+UoUSzOrDtXSxqqb3QYerakbuvYA/XLrrnRu2go7f0rY0KK4Eq1j0EjG7l9mctI MPxxWV45JWRPcRASmeIznO0nXcm03KnfzZIlpzxUQXbf7l16Hd6RPPb8fFP9ikw+FlYm zuVVSEVUzzyy52gVcfrI7d9qL5FBr/mp2ww+ig67ad/9j4RzixtxIoB20uGkiMK1pgRd p5O/1phRXB9Gmr64ZC26q8zE7rMt9QcfbIVZL5oZ+LbdGKR4b7y+9le3b6mdTmYKLEns 6bpNwg2lE1x01CDTK9Ok/tirWTdKP02Et/Ym+o8xHkCN5xWXYmITdCHZmtUSyZqXVfwS D6EA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/SViyYrS1FftN56nFj/LUBMdZmL6citnsb/V8UFB/zw=; b=WIvpG9esDHsBJcJgjKN9bZ6QP19MhI1NmjU75TmFLsbIqMqkMSO+5TVMtCUUdvNrJ0 hGwXBgVzxw7ciBGRY/W4QE0NYkEKccxnxhRwecX+8Y9u+pEcQ+TqUdxyzMGrKU5Otpa5 ofpbjDSQ0XsqVWMwYNTjh4X2LMY1z0Z9WSxXnM1JOgTZO7x+DIIKaob7MJBis7wf+4wW CPD9Wc8yErUHF+WH/OCWjzdRykzDmKQejqRZowWtWX+cG6M8AyTYkLnNAzLto2hze0U4 DdI42ITZcijyXbLe08sd3xOzk8DA2t/0UUHEgbgI3hVDN0k0UQm1S4m4y5RFrGCQOPax 8cMg== X-Gm-Message-State: APjAAAVTvWGDXoWpUpQf5mgMtZ0mMq1XSMb+MWkomMuEwqYHXTutWrPa 6hJSlkehjWTNuFqVM1ofEeA= X-Google-Smtp-Source: APXvYqx+LDaXvVGOMIPeO233vrs3m+tOzvhaXEMY4h32Y28CavB8ya4LXqA/dRJssrqtXHZkbEdfaw== X-Received: by 2002:a17:902:2a29:: with SMTP id i38mr70041345plb.22.1554186790652; Mon, 01 Apr 2019 23:33:10 -0700 (PDT) Received: from localhost.localdomain ([2001:268:c0a5:4ce0:c70:4af9:86e2:2]) by smtp.gmail.com with ESMTPSA id a17sm19327289pfj.123.2019.04.01.23.33.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Apr 2019 23:33:10 -0700 (PDT) From: William Breathitt Gray To: gregkh@linuxfoundation.org Subject: [PATCH v10 18/18] LS1021A: dtsi: add ftm quad decoder entries Date: Tue, 2 Apr 2019 15:30:53 +0900 Message-Id: <58aec84fb201e7ba2e24ff51f8fd1b4261d6b895.1554184734.git.vilhelm.gray@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190402_073312_539369_B7079FC9 X-CRM114-Status: GOOD ( 11.12 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, benjamin.gaignard@st.com, linux-pwm@vger.kernel.org, linux-iio@vger.kernel.org, patrick.havelange@essensium.com, thierry.reding@gmail.com, pmeerw@pmeerw.net, lars@metafoo.de, daniel.lezcano@linaro.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, david@lechnology.com, William Breathitt Gray , robh+dt@kernel.org, tglx@linutronix.de, fabrice.gasnier@st.com, esben@haabendal.dk, shawnguo@kernel.org, linux-kernel@vger.kernel.org, leoyang.li@nxp.com, knaack.h@gmx.de, akpm@linux-foundation.org, linuxppc-dev@lists.ozlabs.org, jic23@kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Patrick Havelange Add the 4 Quadrature counters for this board. Reviewed-by: Esben Haabendal Signed-off-by: Patrick Havelange Signed-off-by: William Breathitt Gray --- arch/arm/boot/dts/ls1021a.dtsi | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index ed0941292172..0168fb62590a 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -433,6 +433,34 @@ status = "disabled"; }; + counter0: counter@29d0000 { + compatible = "fsl,ftm-quaddec"; + reg = <0x0 0x29d0000 0x0 0x10000>; + big-endian; + status = "disabled"; + }; + + counter1: counter@29e0000 { + compatible = "fsl,ftm-quaddec"; + reg = <0x0 0x29e0000 0x0 0x10000>; + big-endian; + status = "disabled"; + }; + + counter2: counter@29f0000 { + compatible = "fsl,ftm-quaddec"; + reg = <0x0 0x29f0000 0x0 0x10000>; + big-endian; + status = "disabled"; + }; + + counter3: counter@2a00000 { + compatible = "fsl,ftm-quaddec"; + reg = <0x0 0x2a00000 0x0 0x10000>; + big-endian; + status = "disabled"; + }; + gpio0: gpio@2300000 { compatible = "fsl,ls1021a-gpio", "fsl,qoriq-gpio"; reg = <0x0 0x2300000 0x0 0x10000>;