From patchwork Tue Dec 20 10:32:14 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 132387 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 9A38CB7035 for ; Tue, 20 Dec 2011 21:33:11 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753410Ab1LTKdL (ORCPT ); Tue, 20 Dec 2011 05:33:11 -0500 Received: from moutng.kundenserver.de ([212.227.17.9]:53945 "EHLO moutng.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753371Ab1LTKdK (ORCPT ); Tue, 20 Dec 2011 05:33:10 -0500 Received: from benhur.adnet.avionic-design.de (p548E07FD.dip0.t-ipconnect.de [84.142.7.253]) by mrelayeu.kundenserver.de (node=mrbap0) with ESMTP (Nemesis) id 0LdKy1-1QvKhd3Wsb-00i2OO; Tue, 20 Dec 2011 11:32:25 +0100 Received: from mailbox.adnet.avionic-design.de (add-virt-zarafa.adnet.avionic-design.de [172.20.129.9]) by benhur.adnet.avionic-design.de (Postfix) with ESMTP id 7EA9B2C4123; Tue, 20 Dec 2011 11:32:26 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by mailbox.adnet.avionic-design.de (Postfix) with ESMTP id 3B4DA2A2824F; Tue, 20 Dec 2011 11:32:24 +0100 (CET) X-Virus-Scanned: amavisd-new at avionic-design.de Received: from mailbox.adnet.avionic-design.de ([127.0.0.1]) by localhost (mailbox.avionic-design.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id wMVUT21JuqKP; Tue, 20 Dec 2011 11:32:22 +0100 (CET) Received: from localhost (avionic-0098.adnet.avionic-design.de [172.20.31.233]) (Authenticated sender: thierry.reding) by mailbox.adnet.avionic-design.de (Postfix) with ESMTPA id 12D512A2821F; Tue, 20 Dec 2011 11:32:21 +0100 (CET) From: Thierry Reding To: devicetree-discuss@lists.ozlabs.org Cc: linux-tegra@vger.kernel.org, Sascha Hauer , Arnd Bergmann , Matthias Kaehlcke , Kurt Van Dijck , Rob Herring , Grant Likely , Colin Cross , Olof Johansson , Richard Purdie Subject: [RFC 3/7] of: Add PWM support. Date: Tue, 20 Dec 2011 11:32:14 +0100 Message-Id: <1324377138-32129-4-git-send-email-thierry.reding@avionic-design.de> X-Mailer: git-send-email 1.7.8 In-Reply-To: <1324377138-32129-1-git-send-email-thierry.reding@avionic-design.de> References: <1324377138-32129-1-git-send-email-thierry.reding@avionic-design.de> X-Provags-ID: V02:K0:fnSZHZf1XP2A/b2mQpGGHQXl53zEAmjY26FnU43X3wX wACCQb24iYn7ww7R3cdoxaXcn15xCYmOlrBjgazP9fcimJXmE7 o4IzzbEKvrz4Dq9NyxoBthHTwGINgYB+MQM62J36VWFiHW6Fqt 6qEYcv/VjSBL0ddfQqLxzKg0xUXEnmcHhYZVBgfnJcPOXWhVe3 MFU6F8GNrfjleLg0ewielKIVMc5njQizIUY1kYe8jOsAuzNBoz F6jEMAA0yvIXefRMc41BxVHOHSjbiQLOmrS2TOYZeFxqEDErty 0vny/hgEBDG0DfValPCqg5StRMkIWOJWKhMd4y2gVjYIx1vvII UiF30wmGeyrSMop8tBUnKXGNiEfZbHi0djgSavpMeLWZ55PlpV RYAe5gPZjqjENmyis8IgfHDhjNs95R5Vz5vFA/rbcRCfKyxegL QZ95T Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org This patch adds helpers to support device-tree bindings for the generic PWM API. Signed-off-by: Thierry Reding --- drivers/of/Kconfig | 6 +++ drivers/of/Makefile | 1 + drivers/of/pwm.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/of_pwm.h | 41 ++++++++++++++++++++++ include/linux/pwm.h | 4 ++ 5 files changed, 140 insertions(+), 0 deletions(-) create mode 100644 drivers/of/pwm.c create mode 100644 include/linux/of_pwm.h diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index cac63c9..62a2073 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -47,6 +47,12 @@ config OF_GPIO help OpenFirmware GPIO accessors +config OF_PWM + def_bool y + depends on PWM + help + OpenFirmware PWM accessors + config OF_I2C def_tristate I2C depends on I2C && !SPARC diff --git a/drivers/of/Makefile b/drivers/of/Makefile index dccb117..c3acf27 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_OF_ADDRESS) += address.o obj-$(CONFIG_OF_IRQ) += irq.o obj-$(CONFIG_OF_DEVICE) += device.o platform.o obj-$(CONFIG_OF_GPIO) += gpio.o +obj-$(CONFIG_OF_PWM) += pwm.o obj-$(CONFIG_OF_I2C) += of_i2c.o obj-$(CONFIG_OF_NET) += of_net.o obj-$(CONFIG_OF_SPI) += of_spi.o diff --git a/drivers/of/pwm.c b/drivers/of/pwm.c new file mode 100644 index 0000000..c0ef302 --- /dev/null +++ b/drivers/of/pwm.c @@ -0,0 +1,88 @@ +/* + * OF helpers for the PWM API + * + * Copyright (c) 2011 Avionic Design GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include + +static int of_pwmchip_is_match(struct pwm_chip *chip, void *data) +{ + return chip->of_node == data; +} + +/** + * of_node_to_pwmchip() - finds the PWM chip associated with a device node + * @np: device node of the PWM chip + * + * Returns a pointer to the PWM chip associated with the specified device + * node or NULL if the device node doesn't represent a PWM chip. + */ +struct pwm_chip *of_node_to_pwmchip(struct device_node *np) +{ + return pwmchip_find(np, of_pwmchip_is_match); +} + +/** + * of_get_named_pwm() - get a PWM number and period to use with the PWM API + * @np: device node to get the PWM from + * @propname: property name containing PWM specifier(s) + * @index: index of the PWM + * @period_ns: a pointer to the PWM period (in ns) to fill in + * + * Returns PWM number to use with the Linux generic PWM API or a negative + * error code on failure. If @period_ns is not NULL the function fills in + * the value parsed from the period-ns property. + */ +int of_get_named_pwm(struct device_node *np, const char *propname, + int index, unsigned int *period_ns) +{ + struct device_node *pwm_np; + const void *pwm_spec; + struct pwm_chip *pc; + const __be32 *spec; + u32 cells; + u32 pwm; + int ret; + + ret = of_parse_phandles_with_args(np, propname, "#pwm-cells", index, + &pwm_np, &pwm_spec); + if (ret) { + pr_debug("%s(): can't parse pwms property\n", __func__); + goto out; + } + + pc = of_node_to_pwmchip(pwm_np); + if (!pc) { + ret = -ENODEV; + goto put; + } + + ret = of_property_read_u32(pwm_np, "#pwm-cells", &cells); + if (ret < 0) + goto put; + + spec = (const __be32 *)pwm_spec; + pwm = be32_to_cpup(pwm_spec); + + if ((cells > 1) && period_ns) + *period_ns = be32_to_cpu(spec[1]); + + ret = pc->base + pwm; + +put: + of_node_put(pwm_np); +out: + pr_debug("%s() exited with status %d\n", __func__, ret); + return ret; +} +EXPORT_SYMBOL(of_get_named_pwm); diff --git a/include/linux/of_pwm.h b/include/linux/of_pwm.h new file mode 100644 index 0000000..8d6d569 --- /dev/null +++ b/include/linux/of_pwm.h @@ -0,0 +1,41 @@ +/* + * OF helpers for the PWM API + * + * Copyright (c) 2011 Avionic Design GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __LINUX_OF_PWM_H +#define __LINUX_OF_PWM_H + +#include + +struct device_node; + +#ifdef CONFIG_OF_PWM + +struct pwm_chip *of_node_to_pwmchip(struct device_node *np); +int of_get_named_pwm(struct device_node *np, const char *propname, + int index, unsigned int *period_ns); + +#else + +static inline struct pwm_chip *of_node_to_pwmchip(struct device_node *np) +{ + return NULL; +} + +static inline int of_get_named_pwm(struct device_node *np, + const char *propname, int index, + unsigned int *period_ns) +{ + return -ENOSYS; +} + +#endif /* CONFIG_OF_PWM */ + +#endif /* __LINUX_OF_PWM_H */ diff --git a/include/linux/pwm.h b/include/linux/pwm.h index 01c0153..d6be4e4 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -65,6 +65,10 @@ struct pwm_chip { struct pwm_ops *ops; int base; unsigned int npwm; + +#ifdef CONFIG_OF_PWM + struct device_node *of_node; +#endif }; int pwmchip_add(struct pwm_chip *chip);