From patchwork Wed Sep 18 02:39:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?TGlnaHQgSHNpZWggKOisneaYjueHiCk=?= X-Patchwork-Id: 1163698 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 46Y41v0H81z9sN1 for ; Wed, 18 Sep 2019 12:39:31 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727463AbfIRCjS (ORCPT ); Tue, 17 Sep 2019 22:39:18 -0400 Received: from mailgw01.mediatek.com ([210.61.82.183]:17967 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1727354AbfIRCjS (ORCPT ); Tue, 17 Sep 2019 22:39:18 -0400 X-UUID: a4a7e7bae23c481daa2475ff900a1fab-20190918 X-UUID: a4a7e7bae23c481daa2475ff900a1fab-20190918 Received: from mtkexhb01.mediatek.inc [(172.21.101.102)] by mailgw01.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) with ESMTP id 1347887542; Wed, 18 Sep 2019 10:39:11 +0800 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs08n2.mediatek.inc (172.21.101.56) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Wed, 18 Sep 2019 10:39:06 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via Frontend Transport; Wed, 18 Sep 2019 10:39:06 +0800 From: Light Hsieh To: CC: , , , , Light Hsieh Subject: [PATCH v5 1/5] pinctrl: mediatek: Check gpio pin number and use binary search in mtk_hw_pin_field_lookup() Date: Wed, 18 Sep 2019 10:39:04 +0800 Message-ID: <1568774348-24363-1-git-send-email-light.hsieh@mediatek.com> X-Mailer: git-send-email 1.8.1.1.dirty MIME-Version: 1.0 X-TM-SNTS-SMTP: 5B4894C816F6683EC50A23CED134C29014FA31E617B040CF8A35F4D76A778BE52000:8 X-MTK: N Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org 1. Check if gpio pin number is in valid range to prevent from get invalid pointer 'desc' in the following code: desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio]; 2. Use binary search in mtk_hw_pin_field_lookup() Modify mtk_hw_pin_field_lookup() to use binary search for accelerating search. --- drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 24 +++++++++++++++++++----- drivers/pinctrl/mediatek/pinctrl-paris.c | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c index 20e1c89..4687f63 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c @@ -68,7 +68,7 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw, { const struct mtk_pin_field_calc *c, *e; const struct mtk_pin_reg_calc *rc; - u32 bits; + u32 bits, start = 0, end, found = 0, check; if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) { rc = &hw->soc->reg_cal[field]; @@ -79,21 +79,32 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw, return -ENOTSUPP; } + end = rc->nranges - 1; c = rc->range; e = c + rc->nranges; - while (c < e) { - if (desc->number >= c->s_pin && desc->number <= c->e_pin) + while (start <= end) { + check = (start + end) >> 1; + if (desc->number >= rc->range[check].s_pin + && desc->number <= rc->range[check].e_pin) { + found = 1; break; - c++; + } else if (start == end) + break; + else if (desc->number < rc->range[check].s_pin) + end = check - 1; + else + start = check + 1; } - if (c >= e) { + if (!found) { dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n", field, desc->number, desc->name); return -ENOTSUPP; } + c = rc->range + check; + if (c->i_base > hw->nbase - 1) { dev_err(hw->dev, "Invalid base for field %d for pin = %d (%s)\n", @@ -182,6 +193,9 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, if (err) return err; + if (value < 0 || value > pf.mask) + return -EINVAL; + if (!pf.next) mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos, (value & pf.mask) << pf.bitpos); diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c index 923264d..28b4951 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -693,6 +693,9 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio) const struct mtk_pin_desc *desc; int value, err; + if (gpio > hw->soc->npins) + return -EINVAL; + desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio]; err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value); @@ -708,6 +711,9 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio) const struct mtk_pin_desc *desc; int value, err; + if (gpio > hw->soc->npins) + return -EINVAL; + desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio]; err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value); @@ -722,6 +728,9 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value) struct mtk_pinctrl *hw = gpiochip_get_data(chip); const struct mtk_pin_desc *desc; + if (gpio > hw->soc->npins) + return; + desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio]; mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value); @@ -729,12 +738,22 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value) static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio) { + struct mtk_pinctrl *hw = gpiochip_get_data(chip); + + if (gpio > hw->soc->npins) + return -EINVAL; + return pinctrl_gpio_direction_input(chip->base + gpio); } static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio, int value) { + struct mtk_pinctrl *hw = gpiochip_get_data(chip); + + if (gpio > hw->soc->npins) + return -EINVAL; + mtk_gpio_set(chip, gpio, value); return pinctrl_gpio_direction_output(chip->base + gpio); From patchwork Wed Sep 18 02:39:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?TGlnaHQgSHNpZWggKOisneaYjueHiCk=?= X-Patchwork-Id: 1163694 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 46Y41f2KBdz9sN1 for ; Wed, 18 Sep 2019 12:39:18 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727416AbfIRCjR (ORCPT ); Tue, 17 Sep 2019 22:39:17 -0400 Received: from mailgw02.mediatek.com ([210.61.82.184]:43113 "EHLO mailgw02.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1727264AbfIRCjR (ORCPT ); Tue, 17 Sep 2019 22:39:17 -0400 X-UUID: 85dc673ca7c147bd80e7adf6878c3347-20190918 X-UUID: 85dc673ca7c147bd80e7adf6878c3347-20190918 Received: from mtkcas07.mediatek.inc [(172.21.101.84)] by mailgw02.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) with ESMTP id 498736375; Wed, 18 Sep 2019 10:39:11 +0800 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs08n1.mediatek.inc (172.21.101.55) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Wed, 18 Sep 2019 10:39:07 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via Frontend Transport; Wed, 18 Sep 2019 10:39:07 +0800 From: Light Hsieh To: CC: , , , , Light Hsieh Subject: [PATCH v5 2/5] pinctrl: mediatek: Supporting driving setting without mapping current to register value Date: Wed, 18 Sep 2019 10:39:05 +0800 Message-ID: <1568774348-24363-2-git-send-email-light.hsieh@mediatek.com> X-Mailer: git-send-email 1.8.1.1.dirty In-Reply-To: <1568774348-24363-1-git-send-email-light.hsieh@mediatek.com> References: <1568774348-24363-1-git-send-email-light.hsieh@mediatek.com> MIME-Version: 1.0 X-MTK: N Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Mediatek's smarphone project actual usage does need to know current value (in mA) in procedure of finding the best driving setting. The steps in the procedure is like as follow: 1. set driving setting field in setting register as 0, measure waveform, perform test, and etc. 2. set driving setting field in setting register as 1, measure waveform, perform test, and etc. ... n. set driving setting field in setting register as n-1, measure waveform, perform test, and etc. Check the results of steps 1~n and adopt the setting that get best result. This procedure does need to know the mapping between current to register value. Therefore, setting driving without mapping current is more pratical for Mediatek's smartphone usage. --- drivers/pinctrl/mediatek/pinctrl-mt6765.c | 4 ++-- drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 21 +++++++++++++++++++++ drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 5 +++++ drivers/pinctrl/mediatek/pinctrl-paris.c | 1 + 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c index 32451e8..e024ebc 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c @@ -1077,8 +1077,8 @@ .bias_disable_get = mtk_pinconf_bias_disable_get, .bias_set = mtk_pinconf_bias_set, .bias_get = mtk_pinconf_bias_get, - .drive_set = mtk_pinconf_drive_set_rev1, - .drive_get = mtk_pinconf_drive_get_rev1, + .drive_set = mtk_pinconf_drive_set_direct_val, + .drive_get = mtk_pinconf_drive_get_direct_val, .adv_pull_get = mtk_pinconf_adv_pull_get, .adv_pull_set = mtk_pinconf_adv_pull_set, }; diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c index 4687f63..23a9529 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c @@ -607,6 +607,27 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw, return 0; } +/* Revision direct value */ +int mtk_pinconf_drive_set_direct_val(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 arg) +{ + int err; + + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg); + + return err; +} + +int mtk_pinconf_drive_get_direct_val(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, int *val) +{ + int err; + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val); + + return err; +} + int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, bool pullup, u32 arg) diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h index 1b7da42..b3bada0 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h @@ -288,6 +288,11 @@ int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw, int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, int *val); +int mtk_pinconf_drive_set_direct_val(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 arg); +int mtk_pinconf_drive_get_direct_val(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, int *val); + int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, bool pullup, u32 arg); diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c index 28b4951..71c94b2 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -964,3 +964,4 @@ static int mtk_paris_pinctrl_resume(struct device *device) .suspend_noirq = mtk_paris_pinctrl_suspend, .resume_noirq = mtk_paris_pinctrl_resume, }; + From patchwork Wed Sep 18 02:39:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?TGlnaHQgSHNpZWggKOisneaYjueHiCk=?= X-Patchwork-Id: 1163697 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 46Y41r4D6Hz9sN1 for ; Wed, 18 Sep 2019 12:39:28 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727973AbfIRCjW (ORCPT ); Tue, 17 Sep 2019 22:39:22 -0400 Received: from mailgw01.mediatek.com ([210.61.82.183]:17967 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1727264AbfIRCjW (ORCPT ); Tue, 17 Sep 2019 22:39:22 -0400 X-UUID: 5004ac12d29b460c94d38dc0802936e8-20190918 X-UUID: 5004ac12d29b460c94d38dc0802936e8-20190918 Received: from mtkexhb01.mediatek.inc [(172.21.101.102)] by mailgw01.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) with ESMTP id 1485398588; Wed, 18 Sep 2019 10:39:11 +0800 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs08n2.mediatek.inc (172.21.101.56) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Wed, 18 Sep 2019 10:39:07 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via Frontend Transport; Wed, 18 Sep 2019 10:39:07 +0800 From: Light Hsieh To: CC: , , , , Light Hsieh Subject: [PATCH v5 3/5] pinctrl: mediatek: Refine mtk_pinconf_get() and mtk_pinconf_set() Date: Wed, 18 Sep 2019 10:39:06 +0800 Message-ID: <1568774348-24363-3-git-send-email-light.hsieh@mediatek.com> X-Mailer: git-send-email 1.8.1.1.dirty In-Reply-To: <1568774348-24363-1-git-send-email-light.hsieh@mediatek.com> References: <1568774348-24363-1-git-send-email-light.hsieh@mediatek.com> MIME-Version: 1.0 X-TM-SNTS-SMTP: 6072E1B6A7F33AFB4456D6CE4D5480ECC7C84CA883F4C2FC98DF824AB776670E2000:8 X-MTK: N Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org 1.Refine mtk_pinconf_get(): 1.1 Use only one occurrence of return at end of this function. 1.2 Correct cases for PIN_CONFIG_SLEW_RATE, PIN_CONFIG_INPUT_SCHMITT_ENABLE, and PIN_CONFIG_OUTPUT_ENABLE - Use variable ret to receive value in mtk_hw_get_value() (instead of variable val) since pinconf_to_config_packed() at end of this function use variable ret to pack config value. 2.Refine mtk_pinconf_set(): 2.1 Use only one occurrence of return at end of this function. 2.2 Modify case of PIN_CONFIG_INPUT_ENABLE - Remove check of ies_present flag and always invoke mtk_hw_set_value() since mtk_hw_pin_field_lookup() invoked inside mtk_hw_set_value() has the same effect of checking if ies control is supported. [The rationale is that: available of a control is always checked in mtk_hw_pin_field_lookup() and no need to add ies_present flag specially for ies control.] 2.3 Simply code logic for case of PIN_CONFIG_INPUT_SCHMITT. 2.4 Add case for PIN_CONFIG_INPUT_SCHMITT_ENABLE and process it with the same code for case of PIN_CONFIG_INPUT_SCHMITT. --- drivers/pinctrl/mediatek/pinctrl-mt6765.c | 1 - drivers/pinctrl/mediatek/pinctrl-paris.c | 205 +++++++++++------------------- 2 files changed, 75 insertions(+), 131 deletions(-) diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c index e024ebc..bada37f 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c @@ -1070,7 +1070,6 @@ .ngrps = ARRAY_SIZE(mtk_pins_mt6765), .eint_hw = &mt6765_eint_hw, .gpio_m = 0, - .ies_present = true, .base_names = mt6765_pinctrl_register_base_names, .nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names), .bias_disable_set = mtk_pinconf_bias_disable_set, diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c index 71c94b2..9433b72 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -78,93 +78,75 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, { struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev); u32 param = pinconf_to_config_param(*config); - int val, val2, err, reg, ret = 1; + int err, reg, ret = 1; const struct mtk_pin_desc *desc; desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin]; switch (param) { case PIN_CONFIG_BIAS_DISABLE: - if (hw->soc->bias_disable_get) { + if (hw->soc->bias_disable_get) err = hw->soc->bias_disable_get(hw, desc, &ret); - if (err) - return err; - } else { - return -ENOTSUPP; - } + else + err = -ENOTSUPP; break; case PIN_CONFIG_BIAS_PULL_UP: - if (hw->soc->bias_get) { + if (hw->soc->bias_get) err = hw->soc->bias_get(hw, desc, 1, &ret); - if (err) - return err; - } else { - return -ENOTSUPP; - } + else + err = -ENOTSUPP; break; case PIN_CONFIG_BIAS_PULL_DOWN: - if (hw->soc->bias_get) { + if (hw->soc->bias_get) err = hw->soc->bias_get(hw, desc, 0, &ret); - if (err) - return err; - } else { - return -ENOTSUPP; - } + else + err = -ENOTSUPP; break; case PIN_CONFIG_SLEW_RATE: - err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &val); - if (err) - return err; - - if (!val) - return -EINVAL; - + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret); break; case PIN_CONFIG_INPUT_ENABLE: case PIN_CONFIG_OUTPUT_ENABLE: - err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val); + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret); if (err) - return err; - - /* HW takes input mode as zero; output mode as non-zero */ - if ((val && param == PIN_CONFIG_INPUT_ENABLE) || - (!val && param == PIN_CONFIG_OUTPUT_ENABLE)) - return -EINVAL; + goto out; + /* CONFIG Current direction return value + * ------------- ----------------- ---------------------- + * OUTPUT_ENABLE output 1 (= HW value) + * input 0 (= HW value) + * INPUT_ENABLE output 0 (= reverse HW value) + * input 1 (= reverse HW value) + */ + if (param == PIN_CONFIG_INPUT_ENABLE) + ret = !ret; break; case PIN_CONFIG_INPUT_SCHMITT_ENABLE: - err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val); - if (err) - return err; - - err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &val2); + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret); if (err) - return err; + goto out; + /* return error when in output mode + * because schmitt trigger only work in input mode + */ + if (ret) { + err = -EINVAL; + goto out; + } - if (val || !val2) - return -EINVAL; + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &ret); break; case PIN_CONFIG_DRIVE_STRENGTH: - if (hw->soc->drive_get) { + if (hw->soc->drive_get) err = hw->soc->drive_get(hw, desc, &ret); - if (err) - return err; - } else { + else err = -ENOTSUPP; - } break; case MTK_PIN_CONFIG_TDSEL: case MTK_PIN_CONFIG_RDSEL: reg = (param == MTK_PIN_CONFIG_TDSEL) ? PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL; - - err = mtk_hw_get_value(hw, desc, reg, &val); - if (err) - return err; - - ret = val; - + err = mtk_hw_get_value(hw, desc, reg, &ret); break; case MTK_PIN_CONFIG_PU_ADV: case MTK_PIN_CONFIG_PD_ADV: @@ -173,28 +155,24 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, pullup = param == MTK_PIN_CONFIG_PU_ADV; err = hw->soc->adv_pull_get(hw, desc, pullup, &ret); - if (err) - return err; - } else { - return -ENOTSUPP; - } + } else + err = -ENOTSUPP; break; case MTK_PIN_CONFIG_DRV_ADV: - if (hw->soc->adv_drive_get) { + if (hw->soc->adv_drive_get) err = hw->soc->adv_drive_get(hw, desc, &ret); - if (err) - return err; - } else { - return -ENOTSUPP; - } + else + err = -ENOTSUPP; break; default: - return -ENOTSUPP; + err = -ENOTSUPP; } - *config = pinconf_to_config_packed(param, ret); +out: + if (!err) + *config = pinconf_to_config_packed(param, ret); - return 0; + return err; } static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, @@ -210,60 +188,45 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, switch ((u32)param) { case PIN_CONFIG_BIAS_DISABLE: - if (hw->soc->bias_disable_set) { + if (hw->soc->bias_disable_set) err = hw->soc->bias_disable_set(hw, desc); - if (err) - return err; - } else { - return -ENOTSUPP; - } + else + err = -ENOTSUPP; break; case PIN_CONFIG_BIAS_PULL_UP: - if (hw->soc->bias_set) { + if (hw->soc->bias_set) err = hw->soc->bias_set(hw, desc, 1); - if (err) - return err; - } else { - return -ENOTSUPP; - } + else + err = -ENOTSUPP; break; case PIN_CONFIG_BIAS_PULL_DOWN: - if (hw->soc->bias_set) { + if (hw->soc->bias_set) err = hw->soc->bias_set(hw, desc, 0); - if (err) - return err; - } else { - return -ENOTSUPP; - } + else + err = -ENOTSUPP; break; case PIN_CONFIG_OUTPUT_ENABLE: err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, MTK_DISABLE); - if (err) + /* keep set direction to if SMT is not supported on this pin */ + if (err != -ENOTSUPP) goto err; err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, MTK_OUTPUT); - if (err) - goto err; break; case PIN_CONFIG_INPUT_ENABLE: - if (hw->soc->ies_present) { - mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, - MTK_ENABLE); - } + /* regard all non-zero value as enable */ + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, !!arg); + if (err) + goto err; err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, MTK_INPUT); - if (err) - goto err; break; case PIN_CONFIG_SLEW_RATE: - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR, - arg); - if (err) - goto err; - + /* regard all non-zero value as enable */ + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR, !!arg); break; case PIN_CONFIG_OUTPUT: err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, @@ -273,41 +236,29 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, arg); - if (err) - goto err; break; + case PIN_CONFIG_INPUT_SCHMITT: case PIN_CONFIG_INPUT_SCHMITT_ENABLE: - /* arg = 1: Input mode & SMT enable ; + /* arg = 1: Input mode & SMT enable * arg = 0: Output mode & SMT disable */ - arg = arg ? 2 : 1; - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, - arg & 1); + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !arg); if (err) goto err; - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, - !!(arg & 2)); - if (err) - goto err; + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, !!arg); break; case PIN_CONFIG_DRIVE_STRENGTH: - if (hw->soc->drive_set) { + if (hw->soc->drive_set) err = hw->soc->drive_set(hw, desc, arg); - if (err) - return err; - } else { - return -ENOTSUPP; - } + else + err = -ENOTSUPP; break; case MTK_PIN_CONFIG_TDSEL: case MTK_PIN_CONFIG_RDSEL: reg = (param == MTK_PIN_CONFIG_TDSEL) ? PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL; - err = mtk_hw_set_value(hw, desc, reg, arg); - if (err) - goto err; break; case MTK_PIN_CONFIG_PU_ADV: case MTK_PIN_CONFIG_PD_ADV: @@ -317,20 +268,14 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, pullup = param == MTK_PIN_CONFIG_PU_ADV; err = hw->soc->adv_pull_set(hw, desc, pullup, arg); - if (err) - return err; - } else { - return -ENOTSUPP; - } + } else + err = -ENOTSUPP; break; case MTK_PIN_CONFIG_DRV_ADV: - if (hw->soc->adv_drive_set) { + if (hw->soc->adv_drive_set) err = hw->soc->adv_drive_set(hw, desc, arg); - if (err) - return err; - } else { - return -ENOTSUPP; - } + else + err = -ENOTSUPP; break; default: err = -ENOTSUPP; @@ -946,6 +891,7 @@ int mtk_paris_pinctrl_probe(struct platform_device *pdev, return 0; } + static int mtk_paris_pinctrl_suspend(struct device *device) { struct mtk_pinctrl *pctl = dev_get_drvdata(device); @@ -964,4 +910,3 @@ static int mtk_paris_pinctrl_resume(struct device *device) .suspend_noirq = mtk_paris_pinctrl_suspend, .resume_noirq = mtk_paris_pinctrl_resume, }; - From patchwork Wed Sep 18 02:39:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?TGlnaHQgSHNpZWggKOisneaYjueHiCk=?= X-Patchwork-Id: 1163696 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 46Y41l5FVzz9sP3 for ; Wed, 18 Sep 2019 12:39:23 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727965AbfIRCjW (ORCPT ); Tue, 17 Sep 2019 22:39:22 -0400 Received: from mailgw02.mediatek.com ([210.61.82.184]:15087 "EHLO mailgw02.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1727400AbfIRCjV (ORCPT ); Tue, 17 Sep 2019 22:39:21 -0400 X-UUID: 5631aca3a3d84d18b13dbb0a145779d3-20190918 X-UUID: 5631aca3a3d84d18b13dbb0a145779d3-20190918 Received: from mtkcas07.mediatek.inc [(172.21.101.84)] by mailgw02.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) with ESMTP id 1999550291; Wed, 18 Sep 2019 10:39:11 +0800 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs08n1.mediatek.inc (172.21.101.55) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Wed, 18 Sep 2019 10:39:07 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via Frontend Transport; Wed, 18 Sep 2019 10:39:07 +0800 From: Light Hsieh To: CC: , , , , Light Hsieh Subject: [PATCH v5 4/5] pinctrl: mediatek: Backward compatible to previous Mediatek's bias-pull usage Date: Wed, 18 Sep 2019 10:39:07 +0800 Message-ID: <1568774348-24363-4-git-send-email-light.hsieh@mediatek.com> X-Mailer: git-send-email 1.8.1.1.dirty In-Reply-To: <1568774348-24363-1-git-send-email-light.hsieh@mediatek.com> References: <1568774348-24363-1-git-send-email-light.hsieh@mediatek.com> MIME-Version: 1.0 X-MTK: N Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Refine mtk_pinconf_set()/mtk_pinconf_get() for backward compatibility to previous Mediatek's bias-pull usage. In PINCTRL_MTK that use pinctrl-mtk-common.c, bias-pull setting for pins with 2 pull resistors can be specified as value for bias-pull-up and bias-pull-down. For example: bias-pull-up = ; bias-pull-up = ; bias-pull-up = ; bias-pull-up = ; bias-pull-down = ; bias-pull-down = ; bias-pull-down = ; bias-pull-down = ; On the other hand, PINCTRL_MTK_PARIS use customized properties "mediatek,pull-up-adv" and "mediatek,pull-down-adv" to specify bias-pull setting for pins with 2 pull resistors. This introduce in-compatibility in device tree and increatse porting effort to Mediatek's customer that had already used PINCTRL_MTK version. Besides, if customers are not awared of this change and still write devicetree for PINCTRL_MTK version, they may encounter runtime failure with pinctrl and spent time to debug. This patch add backward compatible to previous Mediatek's bias-pull usage so that Mediatek's customer need not use a new devicetree property name. The rationale is that: changing driver implemenation had better leave interface unchanged. --- drivers/pinctrl/mediatek/pinctrl-mt6765.c | 6 +- drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 285 +++++++++++++++++++++++ drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 11 + drivers/pinctrl/mediatek/pinctrl-paris.c | 49 ++-- 4 files changed, 327 insertions(+), 24 deletions(-) diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c index bada37f..ae85fdc 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c @@ -1072,10 +1072,8 @@ .gpio_m = 0, .base_names = mt6765_pinctrl_register_base_names, .nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names), - .bias_disable_set = mtk_pinconf_bias_disable_set, - .bias_disable_get = mtk_pinconf_bias_disable_get, - .bias_set = mtk_pinconf_bias_set, - .bias_get = mtk_pinconf_bias_get, + .bias_set_combo = mtk_pinconf_bias_set_combo, + .bias_get_combo = mtk_pinconf_bias_get_combo, .drive_set = mtk_pinconf_drive_set_direct_val, .drive_get = mtk_pinconf_drive_get_direct_val, .adv_pull_get = mtk_pinconf_adv_pull_get, diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c index 23a9529..dab8418 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c @@ -13,6 +13,8 @@ #include #include +#include + #include "mtk-eint.h" #include "pinctrl-mtk-common-v2.h" @@ -205,6 +207,20 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, return 0; } +void mtk_hw_set_value_no_lookup(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + int value, struct mtk_pin_field *pf) +{ + if (value < 0 || value > pf->mask) + return; + + if (!pf->next) + mtk_rmw(hw, pf->index, pf->offset, pf->mask << pf->bitpos, + (value & pf->mask) << pf->bitpos); + else + mtk_hw_write_cross_field(hw, pf, value); +} + int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, int field, int *value) { @@ -224,6 +240,17 @@ int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, return 0; } +void mtk_hw_get_value_no_lookup(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + int *value, struct mtk_pin_field *pf) +{ + if (!pf->next) + *value = (mtk_r32(hw, pf->index, pf->offset) + >> pf->bitpos) & pf->mask; + else + mtk_hw_read_cross_field(hw, pf, value); +} + static int mtk_xt_find_eint_num(struct mtk_pinctrl *hw, unsigned long eint_n) { const struct mtk_pin_desc *desc; @@ -516,6 +543,264 @@ int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw, return 0; } +/* Combo for the following pull register type: + * 1. PU + PD + * 2. PULLSEL + PULLEN + * 3. PUPD + R0 + R1 + */ +int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 pullup, u32 arg) +{ + struct mtk_pin_field pf; + int err = -EINVAL; + int pu, pd; + + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PU, &pf); + if (err) + goto out; + + if (arg == MTK_DISABLE) { + pu = 0; + pd = 0; + } else if ((arg == MTK_ENABLE) && pullup) { + pu = 1; + pd = 0; + } else if ((arg == MTK_ENABLE) && !pullup) { + pu = 0; + pd = 1; + } else { + goto out; + } + + mtk_hw_set_value_no_lookup(hw, desc, pu, &pf); + + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PD, &pf); + if (err) + goto out; + + mtk_hw_set_value_no_lookup(hw, desc, pd, &pf); + +out: + return err; +} + +int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 pullup, u32 arg) +{ + struct mtk_pin_field pf; + int err = -EINVAL, enable; + + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PULLEN, &pf); + if (err) + goto out; + + if (arg == MTK_DISABLE) + enable = 0; + else if (arg == MTK_ENABLE) + enable = 1; + else + goto out; + + mtk_hw_set_value_no_lookup(hw, desc, enable, &pf); + + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PULLSEL, &pf); + if (err) + goto out; + mtk_hw_set_value_no_lookup(hw, desc, pullup, &pf); + +out: + return err; +} + +int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 pullup, u32 arg) +{ + struct mtk_pin_field pf; + int err = -EINVAL; + int r0, r1; + + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PUPD, &pf); + if (err) + goto out; + + if ((arg == MTK_DISABLE) || (arg == MTK_PUPD_SET_R1R0_00)) { + pullup = 0; + r0 = 0; + r1 = 0; + } else if (arg == MTK_PUPD_SET_R1R0_01) { + r0 = 1; + r1 = 0; + } else if (arg == MTK_PUPD_SET_R1R0_10) { + r0 = 0; + r1 = 1; + } else if (arg == MTK_PUPD_SET_R1R0_11) { + r0 = 1; + r1 = 1; + } else + goto out; + + /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */ + mtk_hw_set_value_no_lookup(hw, desc, !pullup, &pf); + + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_R0, &pf); + if (err) + goto out; + mtk_hw_set_value_no_lookup(hw, desc, r0, &pf); + + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_R1, &pf); + if (err) + goto out; + mtk_hw_set_value_no_lookup(hw, desc, r1, &pf); + +out: + return err; +} + +int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 *pullup, u32 *enable) +{ + struct mtk_pin_field pf; + int err = -EINVAL; + int pu, pd; + + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PU, &pf); + if (err) + goto out; + + mtk_hw_get_value_no_lookup(hw, desc, &pu, &pf); + + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PD, &pf); + if (err) + goto out; + + mtk_hw_get_value_no_lookup(hw, desc, &pd, &pf); + + if (pu == 0 && pd == 0) { + *pullup = 0; + *enable = MTK_DISABLE; + } else if (pu == 1 && pd == 0) { + *pullup = 1; + *enable = MTK_ENABLE; + } else if (pu == 0 && pd == 1) { + *pullup = 0; + *enable = MTK_ENABLE; + } else { + err = -EINVAL; + goto out; + } + +out: + return err; +} + +int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 *pullup, u32 *enable) +{ + struct mtk_pin_field pf; + int err = -EINVAL; + + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PULLSEL, &pf); + if (err) + goto out; + + mtk_hw_get_value_no_lookup(hw, desc, pullup, &pf); + + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PULLEN, &pf); + if (err) + goto out; + + mtk_hw_get_value_no_lookup(hw, desc, enable, &pf); + +out: + return err; +} + +int mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 *pullup, u32 *enable) +{ + struct mtk_pin_field pf; + int err = -EINVAL; + int r0, r1; + + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PUPD, &pf); + if (err) + goto out; + + /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */ + mtk_hw_get_value_no_lookup(hw, desc, pullup, &pf); + *pullup = !(*pullup); + + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_R0, &pf); + if (err) + goto out; + mtk_hw_get_value_no_lookup(hw, desc, &r0, &pf); + + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_R1, &pf); + if (err) + goto out; + mtk_hw_get_value_no_lookup(hw, desc, &r1, &pf); + + if ((r1 == 0) && (r0 == 0)) + *enable = MTK_PUPD_SET_R1R0_00; + else if ((r1 == 0) && (r0 == 1)) + *enable = MTK_PUPD_SET_R1R0_01; + else if ((r1 == 1) && (r0 == 0)) + *enable = MTK_PUPD_SET_R1R0_10; + else if ((r1 == 1) && (r0 == 1)) + *enable = MTK_PUPD_SET_R1R0_11; + else + goto out; + +out: + return err; +} + +int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 pullup, u32 arg) +{ + int err; + + err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg); + if (!err) + goto out; + + err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc, pullup, arg); + if (!err) + goto out; + + err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg); + +out: + return err; +} + +int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 *pullup, u32 *enable) +{ + int err; + + err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable); + if (!err) + goto out; + + err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc, pullup, enable); + if (!err) + goto out; + + err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable); + +out: + return err; +} + /* Revision 0 */ int mtk_pinconf_drive_set(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, u32 arg) diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h index b3bada0..a13dcae 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h @@ -216,6 +216,11 @@ struct mtk_pin_soc { int (*bias_get)(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, bool pullup, int *res); + int (*bias_set_combo)(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 pullup, u32 arg); + int (*bias_get_combo)(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 *pullup, u32 *arg); + int (*drive_set)(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, u32 arg); int (*drive_get)(struct mtk_pinctrl *hw, @@ -277,6 +282,12 @@ int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw, int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, bool pullup, int *res); +int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 pullup, u32 enable); +int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 *pullup, u32 *enable); int mtk_pinconf_drive_set(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, u32 arg); diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c index 9433b72..e847867 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -79,28 +79,38 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev); u32 param = pinconf_to_config_param(*config); int err, reg, ret = 1; + int pullup; const struct mtk_pin_desc *desc; desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin]; switch (param) { case PIN_CONFIG_BIAS_DISABLE: - if (hw->soc->bias_disable_get) - err = hw->soc->bias_disable_get(hw, desc, &ret); - else - err = -ENOTSUPP; - break; case PIN_CONFIG_BIAS_PULL_UP: - if (hw->soc->bias_get) - err = hw->soc->bias_get(hw, desc, 1, &ret); - else - err = -ENOTSUPP; - break; case PIN_CONFIG_BIAS_PULL_DOWN: - if (hw->soc->bias_get) - err = hw->soc->bias_get(hw, desc, 0, &ret); - else + if (hw->soc->bias_get_combo) { + err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret); + if (err) + goto out; + if (param == PIN_CONFIG_BIAS_DISABLE) { + if (ret == MTK_PUPD_SET_R1R0_00) + ret = MTK_DISABLE; + } else if (param == PIN_CONFIG_BIAS_PULL_UP) { + /* When desire to get pull-up value, + * return error if current setting is pull-down + */ + if (!pullup) + err = -EINVAL; + } else if (param == PIN_CONFIG_BIAS_PULL_DOWN) { + /* When desire to get pull-down value, + * return error if current setting is pull-up + */ + if (pullup) + err = -EINVAL; + } + } else { err = -ENOTSUPP; + } break; case PIN_CONFIG_SLEW_RATE: err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret); @@ -188,20 +198,20 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, switch ((u32)param) { case PIN_CONFIG_BIAS_DISABLE: - if (hw->soc->bias_disable_set) - err = hw->soc->bias_disable_set(hw, desc); + if (hw->soc->bias_set_combo) + err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE); else err = -ENOTSUPP; break; case PIN_CONFIG_BIAS_PULL_UP: - if (hw->soc->bias_set) - err = hw->soc->bias_set(hw, desc, 1); + if (hw->soc->bias_set_combo) + err = hw->soc->bias_set_combo(hw, desc, 1, arg); else err = -ENOTSUPP; break; case PIN_CONFIG_BIAS_PULL_DOWN: - if (hw->soc->bias_set) - err = hw->soc->bias_set(hw, desc, 0); + if (hw->soc->bias_set_combo) + err = hw->soc->bias_set_combo(hw, desc, 0, arg); else err = -ENOTSUPP; break; @@ -891,7 +901,6 @@ int mtk_paris_pinctrl_probe(struct platform_device *pdev, return 0; } - static int mtk_paris_pinctrl_suspend(struct device *device) { struct mtk_pinctrl *pctl = dev_get_drvdata(device); From patchwork Wed Sep 18 02:39:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?TGlnaHQgSHNpZWggKOisneaYjueHiCk=?= X-Patchwork-Id: 1163695 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 46Y41l08zlz9sNw for ; Wed, 18 Sep 2019 12:39:23 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727734AbfIRCjT (ORCPT ); Tue, 17 Sep 2019 22:39:19 -0400 Received: from mailgw01.mediatek.com ([210.61.82.183]:9339 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1727413AbfIRCjS (ORCPT ); Tue, 17 Sep 2019 22:39:18 -0400 X-UUID: 29c78a951bc547d5872844b8202129fe-20190918 X-UUID: 29c78a951bc547d5872844b8202129fe-20190918 Received: from mtkexhb01.mediatek.inc [(172.21.101.102)] by mailgw01.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) with ESMTP id 1910691371; Wed, 18 Sep 2019 10:39:11 +0800 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs08n2.mediatek.inc (172.21.101.56) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Wed, 18 Sep 2019 10:39:07 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via Frontend Transport; Wed, 18 Sep 2019 10:39:07 +0800 From: Light Hsieh To: CC: , , , , Light Hsieh Subject: [PATCH v5 5/5] pinctrl: mediatek: Add support for pin configuration dump via debugfs. Date: Wed, 18 Sep 2019 10:39:08 +0800 Message-ID: <1568774348-24363-5-git-send-email-light.hsieh@mediatek.com> X-Mailer: git-send-email 1.8.1.1.dirty In-Reply-To: <1568774348-24363-1-git-send-email-light.hsieh@mediatek.com> References: <1568774348-24363-1-git-send-email-light.hsieh@mediatek.com> MIME-Version: 1.0 X-TM-SNTS-SMTP: 050E9B0BB55236DDC0BA422EE98141F138E6305774B40F2F6E4B8912D0BF1C8B2000:8 X-MTK: N Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Add support for pin configuration dump via catting /sys/kernel/debug/pinctrl/$platform_dependent_path/pinconf-pins. pinctrl framework had already support such dump. This patch implement the operation function pointer to fullfill this dump. --- drivers/pinctrl/mediatek/pinctrl-paris.c | 88 ++++++++++++++++++++++++++++++++ drivers/pinctrl/mediatek/pinctrl-paris.h | 30 +++++++++++ 2 files changed, 118 insertions(+) diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c index e847867..6acbdc3 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -530,12 +530,99 @@ static int mtk_pctrl_get_group_pins(struct pinctrl_dev *pctldev, return 0; } +int mtk_hw_get_value_wrap(struct mtk_pinctrl *hw, unsigned int gpio, int field) +{ + const struct mtk_pin_desc *desc; + int value, err; + + if (gpio > hw->soc->npins) + return -EINVAL; + + desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio]; + + err = mtk_hw_get_value(hw, desc, field, &value); + if (err) + return err; + + return value; +} + +ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw, + unsigned int gpio, char *buf, unsigned int bufLen) +{ + const struct mtk_pin_desc *desc; + int pinmux, pullup, pullen, r1 = -1, r0 = -1, len = 0; + + if (gpio > hw->soc->npins) + return -EINVAL; + + desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio]; + pinmux = mtk_pctrl_get_pinmux(hw, gpio); + if (pinmux >= hw->soc->nfuncs) + pinmux -= hw->soc->nfuncs; + + mtk_pinconf_bias_get_combo(hw, desc, &pullup, &pullen); + if (pullen == MTK_PUPD_SET_R1R0_00) { + pullen = 0; + r1 = 0; + r0 = 0; + } else if (pullen == MTK_PUPD_SET_R1R0_01) { + pullen = 1; + r1 = 0; + r0 = 1; + } else if (pullen == MTK_PUPD_SET_R1R0_10) { + pullen = 1; + r1 = 1; + r0 = 0; + } else if (pullen == MTK_PUPD_SET_R1R0_11) { + pullen = 1; + r1 = 1; + r0 = 1; + } else if (pullen != MTK_DISABLE && pullen != MTK_ENABLE) { + pullen = 0; + } + len += snprintf(buf + len, bufLen - len, + "%03d: %1d%1d%1d%1d%02d%1d%1d%1d%1d", + gpio, + pinmux, + mtk_pctrl_get_direction(hw, gpio), + mtk_pctrl_get_out(hw, gpio), + mtk_pctrl_get_in(hw, gpio), + mtk_pctrl_get_driving(hw, gpio), + mtk_pctrl_get_smt(hw, gpio), + mtk_pctrl_get_ies(hw, gpio), + pullen, + pullup); + + if (r1 != -1) { + len += snprintf(buf + len, bufLen - len, " (%1d %1d)\n", + r1, r0); + } else { + len += snprintf(buf + len, bufLen - len, "\n"); + } + + return len; +} + +#define PIN_DBG_BUF_SZ 96 +static void mtk_pctrl_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, + unsigned int gpio) +{ + struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev); + char buf[PIN_DBG_BUF_SZ]; + + (void)mtk_pctrl_show_one_pin(hw, gpio, buf, PIN_DBG_BUF_SZ); + + seq_printf(s, "%s", buf); +} + static const struct pinctrl_ops mtk_pctlops = { .dt_node_to_map = mtk_pctrl_dt_node_to_map, .dt_free_map = pinctrl_utils_free_map, .get_groups_count = mtk_pctrl_get_groups_count, .get_group_name = mtk_pctrl_get_group_name, .get_group_pins = mtk_pctrl_get_group_pins, + .pin_dbg_show = mtk_pctrl_dbg_show, }; static int mtk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev) @@ -632,6 +719,7 @@ static int mtk_pconf_group_set(struct pinctrl_dev *pctldev, unsigned group, .pin_config_get = mtk_pinconf_get, .pin_config_group_get = mtk_pconf_group_get, .pin_config_group_set = mtk_pconf_group_set, + .is_generic = true, }; static struct pinctrl_desc mtk_desc = { diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.h b/drivers/pinctrl/mediatek/pinctrl-paris.h index 3d43771..d73f4b6 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.h +++ b/drivers/pinctrl/mediatek/pinctrl-paris.h @@ -60,6 +60,36 @@ int mtk_paris_pinctrl_probe(struct platform_device *pdev, const struct mtk_pin_soc *soc); +int mtk_hw_get_value_wrap(struct mtk_pinctrl *hw, unsigned int gpio, int field); + +#define mtk_pctrl_get_pinmux(hw, gpio) \ + mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_MODE) + +/* MTK HW use 0 as input, 1 for output + * This interface is for get direct register value, + * so don't reverse + */ +#define mtk_pctrl_get_direction(hw, gpio) \ + mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DIR) + +#define mtk_pctrl_get_out(hw, gpio) \ + mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DO) + +#define mtk_pctrl_get_in(hw, gpio) \ + mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DI) + +#define mtk_pctrl_get_smt(hw, gpio) \ + mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_SMT) + +#define mtk_pctrl_get_ies(hw, gpio) \ + mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_IES) + +#define mtk_pctrl_get_driving(hw, gpio) \ + mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DRV) + +ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw, + unsigned int gpio, char *buf, unsigned int bufLen); + extern const struct dev_pm_ops mtk_paris_pinctrl_pm_ops; #endif /* __PINCTRL_PARIS_H */