From patchwork Wed Nov 8 06:47:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yixun Lan X-Patchwork-Id: 10047851 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 7B54960247 for ; Wed, 8 Nov 2017 06:48:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 699252A4D8 for ; Wed, 8 Nov 2017 06:48:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5D3522A4E6; Wed, 8 Nov 2017 06:48:51 +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=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.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 B981A2A4D8 for ; Wed, 8 Nov 2017 06:48: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: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:In-Reply-To:References: List-Owner; bh=2E4QVOxf9L4VgH6GI2qteb+/cVSlsfEiIUEWbtHN190=; b=jzY7RpVOlld2Hh 16mMV5yYCu58/DgcxVp2c9p4skor8JAUObIvgVlDTsZ1i1oktdQixTlUx2LMouLInGADYUczZbexr MEpLzXNE4vDDGHg1QVcqiH2hK1OLz1U1wDyOEM8dBoZszPgVhRjpbIpyxJoCZoCn88FR+6zDqNtOj 1umBCINC6OrJ+KGfOOt/lpwaTCyh17yNVTi8kGP6b/5aPaLlLEkoQW+6fsPVNv2QqCx/6Mr7r+WXM yDXFYENWXa3C+lc9Nbrz+kZLASrjs4OliN4vp4yxpGFSqvN913fZiP2YsEWBf677Diiom+J7MNETd RF2LSxyUClFr1/PuhaHg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1eCKAG-00081a-2g; Wed, 08 Nov 2017 06:48:44 +0000 Received: from mail-sh2.amlogic.com ([58.32.228.45]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1eCK9c-0007Ke-1D; Wed, 08 Nov 2017 06:48:08 +0000 Received: from localhost.localdomain (10.18.20.164) by mail-sh2.amlogic.com (10.18.11.6) with Microsoft SMTP Server id 15.0.1320.4; Wed, 8 Nov 2017 14:46:58 +0800 From: Yixun Lan To: Neil Armstrong , Jerome Brunet , Linus Walleij Subject: [PATCH 2/4] pinctrl: meson-axg: Introduce a pinctrl pinmux ops for Meson-AXG SoC Date: Wed, 8 Nov 2017 14:47:16 +0800 Message-ID: <20171108064717.32577-1-yixun.lan@amlogic.com> X-Mailer: git-send-email 2.14.1 MIME-Version: 1.0 X-Originating-IP: [10.18.20.164] X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171107_224804_353564_63C0EA88 X-CRM114-Status: GOOD ( 17.60 ) X-BeenThere: linux-amlogic@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Hilman , Yixun Lan , linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Carlo Caione , linux-amlogic@lists.infradead.org, Xingyu Chen Sender: "linux-amlogic" Errors-To: linux-amlogic-bounces+patchwork-linux-amlogic=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Xingyu Chen The pin controller has been updated in the Amlogic Meson AXG series, which use continuous 4-bit register to select function for each pin. In order to support this, a new pinmux operations "meson_axg_pmx_ops" has been added. Signed-off-by: Xingyu Chen Signed-off-by: Yixun Lan Reviewed-by: Neil Armstrong --- drivers/pinctrl/meson/Kconfig | 3 + drivers/pinctrl/meson/Makefile | 1 + drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c | 118 ++++++++++++++++++++++++++ drivers/pinctrl/meson/pinctrl-meson-axg-pmx.h | 62 ++++++++++++++ drivers/pinctrl/meson/pinctrl-meson.h | 1 + 5 files changed, 185 insertions(+) create mode 100644 drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c create mode 100644 drivers/pinctrl/meson/pinctrl-meson-axg-pmx.h diff --git a/drivers/pinctrl/meson/Kconfig b/drivers/pinctrl/meson/Kconfig index 1a51778759ea..fe5e6ca88412 100644 --- a/drivers/pinctrl/meson/Kconfig +++ b/drivers/pinctrl/meson/Kconfig @@ -38,4 +38,7 @@ config PINCTRL_MESON_GXL config PINCTRL_MESON8_PMX bool +config PINCTRL_MESON_AXG_PMX + bool + endif diff --git a/drivers/pinctrl/meson/Makefile b/drivers/pinctrl/meson/Makefile index cbd47bb74549..8de839512677 100644 --- a/drivers/pinctrl/meson/Makefile +++ b/drivers/pinctrl/meson/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_PINCTRL_MESON8) += pinctrl-meson8.o obj-$(CONFIG_PINCTRL_MESON8B) += pinctrl-meson8b.o obj-$(CONFIG_PINCTRL_MESON_GXBB) += pinctrl-meson-gxbb.o obj-$(CONFIG_PINCTRL_MESON_GXL) += pinctrl-meson-gxl.o +obj-$(CONFIG_PINCTRL_MESON_AXG_PMX) += pinctrl-meson-axg-pmx.o diff --git a/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c b/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c new file mode 100644 index 000000000000..e8931d9cf863 --- /dev/null +++ b/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c @@ -0,0 +1,118 @@ +/* + * Second generation of pinmux driver for Amlogic Meson-AXG SoC. + * + * Copyright (c) 2017 Baylibre SAS. + * Author: Jerome Brunet + * + * Copyright (c) 2017 Amlogic, Inc. All rights reserved. + * Author: Xingyu Chen + * + * SPDX-License-Identifier: (GPL-2.0+ or MIT) + */ + +/* + * This new generation of pinctrl IP is mainly adopted by the + * Meson-AXG SoC and later series, which use 4-width continuous + * register bit to select the function for each pin. + * + * The value 0 is always selecting the GPIO mode, while other + * values (start from 1) for selecting the function mode. + */ +#include +#include +#include +#include + +#include "pinctrl-meson.h" +#include "pinctrl-meson-axg-pmx.h" + +static int meson_axg_pmx_get_bank(struct meson_pinctrl *pc, + unsigned int pin, + struct meson_pmx_bank **bank) +{ + int i; + struct meson_axg_pmx_data *pmx = pc->data->pmx_data; + + for (i = 0; i < pmx->num_pmx_banks; i++) + if (pin >= pmx->pmx_banks[i].first && + pin <= pmx->pmx_banks[i].last) { + *bank = &pmx->pmx_banks[i]; + return 0; + } + + return -EINVAL; +} + +static int meson_pmx_calc_reg_and_offset(struct meson_pmx_bank *bank, + unsigned int pin, unsigned int *reg, + unsigned int *offset) +{ + int shift; + + shift = pin - bank->first; + + *reg = bank->reg + (bank->offset + (shift << 2)) / 32; + *offset = (bank->offset + (shift << 2)) % 32; + + return 0; +} + +static int meson_axg_pmx_update_function(struct meson_pinctrl *pc, + unsigned int pin, unsigned int func) +{ + int ret; + int reg; + int offset; + struct meson_pmx_bank *bank; + + ret = meson_axg_pmx_get_bank(pc, pin, &bank); + if (ret) + return ret; + + meson_pmx_calc_reg_and_offset(bank, pin, ®, &offset); + + ret = regmap_update_bits(pc->reg_mux, reg << 2, + 0xf << offset, (func & 0xf) << offset); + + return ret; +} + +static int meson_axg_pmx_set_mux(struct pinctrl_dev *pcdev, + unsigned int func_num, unsigned int group_num) +{ + int i; + int ret; + struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev); + struct meson_pmx_func *func = &pc->data->funcs[func_num]; + struct meson_pmx_group *group = &pc->data->groups[group_num]; + struct meson_pmx_axg_data *pmx_data = + (struct meson_pmx_axg_data *)group->data; + + dev_dbg(pc->dev, "enable function %s, group %s\n", func->name, + group->name); + + for (i = 0; i < group->num_pins; i++) { + ret = meson_axg_pmx_update_function(pc, group->pins[i], + pmx_data->func); + if (ret) + return ret; + } + + return 0; +} + +static int meson_axg_pmx_request_gpio(struct pinctrl_dev *pcdev, + struct pinctrl_gpio_range *range, unsigned int offset) +{ + struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev); + + return meson_axg_pmx_update_function(pc, offset, 0); +} + +const struct pinmux_ops meson_axg_pmx_ops = { + .set_mux = meson_axg_pmx_set_mux, + .get_functions_count = meson_pmx_get_funcs_count, + .get_function_name = meson_pmx_get_func_name, + .get_function_groups = meson_pmx_get_groups, + .gpio_request_enable = meson_axg_pmx_request_gpio, +}; diff --git a/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.h b/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.h new file mode 100644 index 000000000000..8ff88bf2e849 --- /dev/null +++ b/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2017 Baylibre SAS. + * Author: Jerome Brunet + * + * Copyright (c) 2017 Amlogic, Inc. All rights reserved. + * Author: Xingyu Chen + * + * SPDX-License-Identifier: (GPL-2.0+ or MIT) + */ + +struct meson_pmx_bank { + const char *name; + unsigned int first; + unsigned int last; + unsigned int reg; + unsigned int offset; +}; + +struct meson_axg_pmx_data { + struct meson_pmx_bank *pmx_banks; + unsigned int num_pmx_banks; +}; + +#define BANK_PMX(n, f, l, r, o) \ + { \ + .name = n, \ + .first = f, \ + .last = l, \ + .reg = r, \ + .offset = o, \ + } + +struct meson_pmx_axg_data { + unsigned int func; +}; + +#define PMX_DATA(f) \ + { \ + .func = f, \ + } + +#define GROUP(grp, f) \ + { \ + .name = #grp, \ + .pins = grp ## _pins, \ + .num_pins = ARRAY_SIZE(grp ## _pins), \ + .data = (const struct meson_pmx_axg_data[]){ \ + PMX_DATA(f), \ + }, \ + } + +#define GPIO_GROUP(gpio) \ + { \ + .name = #gpio, \ + .pins = (const unsigned int[]){ gpio }, \ + .num_pins = 1, \ + .data = (const struct meson_pmx_axg_data[]){ \ + PMX_DATA(0), \ + }, \ + } + +extern const struct pinmux_ops meson_axg_pmx_ops; diff --git a/drivers/pinctrl/meson/pinctrl-meson.h b/drivers/pinctrl/meson/pinctrl-meson.h index 183b6e471635..12a391109329 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.h +++ b/drivers/pinctrl/meson/pinctrl-meson.h @@ -108,6 +108,7 @@ struct meson_pinctrl_data { struct meson_bank *banks; unsigned int num_banks; const struct pinmux_ops *pmx_ops; + void *pmx_data; }; struct meson_pinctrl {