From patchwork Tue Jun 11 22:22:30 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2707241 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 432519F1E2 for ; Tue, 11 Jun 2013 22:24:34 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 324152040A for ; Tue, 11 Jun 2013 22:24:33 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C9789203FB for ; Tue, 11 Jun 2013 22:24:27 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UmWya-0001xW-DS; Tue, 11 Jun 2013 22:23:41 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UmWyM-0007bR-MG; Tue, 11 Jun 2013 22:23:26 +0000 Received: from perceval.ideasonboard.com ([95.142.166.194]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UmWyJ-0007Zn-JX for linux-arm-kernel@lists.infradead.org; Tue, 11 Jun 2013 22:23:24 +0000 Received: from avalon.ideasonboard.com (unknown [91.177.151.179]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 5445835A4E; Wed, 12 Jun 2013 00:22:56 +0200 (CEST) From: Laurent Pinchart To: linux-sh@vger.kernel.org Subject: [PATCH v5 01/22] pinctrl: generic: Add DT bindings Date: Wed, 12 Jun 2013 00:22:30 +0200 Message-Id: <1370989371-30846-2-git-send-email-laurent.pinchart+renesas@ideasonboard.com> X-Mailer: git-send-email 1.8.1.5 In-Reply-To: <1370989371-30846-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com> References: <1370989371-30846-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130611_182323_910866_92E0B832 X-CRM114-Status: GOOD ( 18.39 ) X-Spam-Score: -2.1 (--) Cc: James Hogan , devicetree-discuss@lists.ozlabs.org, Guennadi Liakhovetski , Magnus Damm , Linus Walleij , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Document DT properties for the generic pinctrl parameters and add a parser function. Signed-off-by: Laurent Pinchart --- .../bindings/pinctrl/pinctrl-bindings.txt | 29 +++++++ drivers/pinctrl/pinconf-generic.c | 94 ++++++++++++++++++++++ drivers/pinctrl/pinconf.h | 17 ++++ 3 files changed, 140 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt index c95ea82..e499ff0 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt @@ -126,3 +126,32 @@ device; they may be grandchildren, for example. Whether this is legal, and whether there is any interaction between the child and intermediate parent nodes, is again defined entirely by the binding for the individual pin controller device. + +== Generic pinconf parameters == + +Pin configuration parameters are expressed by DT properties in the pin +controller device state nodes and child nodes. For devices that use the generic +pinconf parameters the following properties are defined. + +- tristate: A boolean, put the pin into high impedance state when set. + +- pull-up: An integer representing the pull-up strength. 0 disables the pull-up, + non-zero values enable it. + +- pull-down: An integer representing the pull-down strength. 0 disables the + pull-down, non-zero values enables it. + +- schmitt: An integer, enable or disable Schmitt trigger mode for the pins. + Valid values are + 0: Schmitt trigger disabled (no hysteresis) + 1: Schmitt trigger enabled + +- slew-rate: An integer controlling the pin slew rate. Values are device- + dependent. + +- drive-strength: An integer representing the drive strength of pins in mA. + Valid values are device-dependent. + +The pinctrl device DT bindings documentation must list the properties that +apply to the device, and define the valid range for all device-dependent +values. diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c index 2ad5a8d..bd0e41d 100644 --- a/drivers/pinctrl/pinconf-generic.c +++ b/drivers/pinctrl/pinconf-generic.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -135,3 +136,96 @@ void pinconf_generic_dump_config(struct pinctrl_dev *pctldev, } EXPORT_SYMBOL_GPL(pinconf_generic_dump_config); #endif + +struct pinconf_generic_param { + const char *property; + enum pin_config_param param; + bool flag; +}; + +static const struct pinconf_generic_param pinconf_generic_params[] = { + { "tristate", PIN_CONFIG_BIAS_HIGH_IMPEDANCE, true }, + { "pull-up", PIN_CONFIG_BIAS_PULL_UP, false }, + { "pull-down", PIN_CONFIG_BIAS_PULL_DOWN, false }, + { "schmitt", PIN_CONFIG_INPUT_SCHMITT_ENABLE, true }, + { "slew-rate", PIN_CONFIG_SLEW_RATE, false }, + { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, false }, +}; + +static int pinconf_generic_add_config(unsigned long **configs, + unsigned int *num_configs, + unsigned long config) +{ + unsigned int count = *num_configs + 1; + unsigned long *cfgs; + + cfgs = krealloc(*configs, sizeof(*cfgs) * count, GFP_KERNEL); + if (cfgs == NULL) + return -ENOMEM; + + cfgs[count - 1] = config; + + *configs = cfgs; + *num_configs = count; + + return 0; +} + +/** + * pinconf_generic_parse_params - Parse generic pinconf parameters from DT + * @dev: the device, used to print error messages + * @np: the DT node that contains generic pinconf parameters + * @cfgs: the returned array of pinconf parameters + * + * The parameters array is allocated dynamically and returned through the cfgs + * argument. The caller is responsible for freeing the array with kfree(). If no + * configuration parameter is found, or if an error occurs, no parameters array + * will be allocated and the cfgs argument will be set to NULL. + * + * Return the number of configuration parameters successfully parsed, or a + * negative value if an error occurred. Used error codes are + * + * -ENOMEM if memory can't be allocated for the parameters array + */ +int pinconf_generic_parse_params(struct device *dev, struct device_node *np, + unsigned long **cfgs) +{ + unsigned long *configs = NULL; + unsigned int num_configs = 0; + unsigned int i; + int ret; + + for (i = 0; i < ARRAY_SIZE(pinconf_generic_params); ++i) { + const struct pinconf_generic_param *param = + &pinconf_generic_params[i]; + unsigned long config; + u32 val; + + if (param->flag) { + ret = of_property_read_bool(np, param->property) + ? 0 : -EINVAL; + val = 1; + } else { + ret = of_property_read_u32(np, param->property, &val); + } + + if (ret) { + if (ret != -EINVAL) + dev_err(dev, "failed to parse property %s\n", + param->property); + continue; + } + + config = pinconf_to_config_packed(param->param, val); + ret = pinconf_generic_add_config(&configs, &num_configs, config); + if (ret < 0) { + kfree(configs); + *cfgs = NULL; + return ret; + } + } + + *cfgs = configs; + return num_configs; +} +EXPORT_SYMBOL_GPL(pinconf_generic_parse_params); diff --git a/drivers/pinctrl/pinconf.h b/drivers/pinctrl/pinconf.h index 92c7267..eb8550b 100644 --- a/drivers/pinctrl/pinconf.h +++ b/drivers/pinctrl/pinconf.h @@ -90,6 +90,23 @@ static inline void pinconf_init_device_debugfs(struct dentry *devroot, * pin config. */ +#if defined(CONFIG_GENERIC_PINCONF) + +int pinconf_generic_parse_params(struct device *dev, struct device_node *np, + unsigned long **cfgs); + +#else + +static inline int pinconf_generic_parse_params(struct device *dev, + struct device_node *np, + unsigned long **cfgs) +{ + *cfgs = NULL; + return 0; +} + +#endif + #if defined(CONFIG_GENERIC_PINCONF) && defined(CONFIG_DEBUG_FS) void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev,