From patchwork Mon Mar 12 21:14:31 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 7241 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 2F15723E29 for ; Mon, 12 Mar 2012 21:15:00 +0000 (UTC) Received: from mail-wi0-f182.google.com (mail-wi0-f182.google.com [209.85.212.182]) by fiordland.canonical.com (Postfix) with ESMTP id 247EEA18475 for ; Mon, 12 Mar 2012 21:15:00 +0000 (UTC) Received: by wibhr14 with SMTP id hr14so4180425wib.17 for ; Mon, 12 Mar 2012 14:15:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:mime-version:content-type :x-gm-message-state; bh=eBgHk2kC4ScA6WbudA9Quo6DmcVmSAzfQKQ+cNN7HGw=; b=jKgBsPvnPe0b4KTcZ9BL6LPxw+g6bzQcacYV4Aq/gqnroQUWdNV4xhT5o7JS6EzOZ/ ueuApzVbbaKVFkLbh0MsN2PUezJ9Egf7fQf1XIyOA/lQWD6nQ8HCXM4PTyFnPhLnP/a5 +hqLdP1jrX9BnwvRnSGlzmAMDo+m5Oa31gMm6hNUQU9RvGslxMEBZP0JzCpJU5ZL3iLL sdsTlZhBPSYKEM2LfZhndScu+qbtrFxf1YBrNekovD7YAbsWmi+fIVuJ9gbhu241+9AG dKu1oK0ID8GCNFru3iUiO83xXhQ0+tnl7PzP5UZ6rRtMfxBqVA4Iaky2DurTJc9TopGr wUrg== Received: by 10.50.222.233 with SMTP id qp9mr695884igc.58.1331586899285; Mon, 12 Mar 2012 14:14:59 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.53.18 with SMTP id k18csp51567ibg; Mon, 12 Mar 2012 14:14:56 -0700 (PDT) Received: by 10.213.8.138 with SMTP id h10mr1064015ebh.197.1331586895412; Mon, 12 Mar 2012 14:14:55 -0700 (PDT) Received: from eu1sys200aog120.obsmtp.com (eu1sys200aog120.obsmtp.com. [207.126.144.149]) by mx.google.com with SMTP id n59si816825eea.150.2012.03.12.14.14.42 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 12 Mar 2012 14:14:55 -0700 (PDT) Received-SPF: neutral (google.com: 207.126.144.149 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) client-ip=207.126.144.149; Authentication-Results: mx.google.com; spf=neutral (google.com: 207.126.144.149 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) smtp.mail=linus.walleij@stericsson.com Received: from beta.dmz-ap.st.com ([138.198.100.35]) (using TLSv1) by eu1sys200aob120.postini.com ([207.126.147.11]) with SMTP ID DSNKT15nQMEZvZmc+hEU4imv6rC29jI5Fp+h@postini.com; Mon, 12 Mar 2012 21:14:54 UTC Received: from zeta.dmz-ap.st.com (ns6.st.com [138.198.234.13]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 840C3B0; Mon, 12 Mar 2012 21:06:13 +0000 (GMT) Received: from relay2.stm.gmessaging.net (unknown [10.230.100.18]) by zeta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 612C3F90; Mon, 12 Mar 2012 21:14:36 +0000 (GMT) Received: from exdcvycastm003.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm003", Issuer "exdcvycastm003" (not verified)) by relay2.stm.gmessaging.net (Postfix) with ESMTPS id B1C11A8088; Mon, 12 Mar 2012 22:14:27 +0100 (CET) Received: from steludxu4075.lud.stericsson.com (10.230.100.153) by smtp.stericsson.com (10.230.100.1) with Microsoft SMTP Server (TLS) id 8.3.83.0; Mon, 12 Mar 2012 22:14:35 +0100 From: Linus Walleij To: , Cc: Stephen Warren , Shawn Guo , Thomas Abraham , Dong Aisheng , Rajendra Nayak , Haojian Zhuang , Linus Walleij Subject: [PATCH 3/4 v3] pinctrl: support pinconfig on the U300 Date: Mon, 12 Mar 2012 22:14:31 +0100 Message-ID: <1331586871-15655-1-git-send-email-linus.walleij@stericsson.com> X-Mailer: git-send-email 1.7.8 MIME-Version: 1.0 X-Gm-Message-State: ALoCoQmnN4oURiY7tosznucCs80ZpAEHN6OoJ5aVrJ3wmYz42URiZQ8WigjCUcLhpbK+kYf+wGtO From: Linus Walleij This adds pin configuration support for the U300 driver pair, we can now read out the biasing and drive mode in debugfs and configure it using the new configuration API. ChangeLog v1->v2: - Migrate to pin config and generic pin config changes. ChangeLog v2->v3: - Adjust to generic pin config changes in v7 patch set. Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/pinctrl-coh901.c | 77 ++++++++++++++++++++++++++++++++++---- drivers/pinctrl/pinctrl-coh901.h | 5 ++ drivers/pinctrl/pinctrl-u300.c | 60 +++++++++++++++++++++++++++++ 4 files changed, 135 insertions(+), 8 deletions(-) create mode 100644 drivers/pinctrl/pinctrl-coh901.h diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 07f3d8d..abfb964 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -73,6 +73,7 @@ config PINCTRL_U300 bool "U300 pin controller driver" depends on ARCH_U300 select PINMUX + select GENERIC_PINCONF config PINCTRL_COH901 bool "ST-Ericsson U300 COH 901 335/571 GPIO" diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index 724234c..0797eba 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c @@ -23,7 +23,9 @@ #include #include #include +#include #include +#include "pinctrl-coh901.h" /* * Register definitions for COH 901 335 variant @@ -418,8 +420,68 @@ static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset) return retirq; } -static int u300_gpio_config(struct gpio_chip *chip, unsigned offset, - enum pin_config_param param, unsigned long data) +/* Returning -EINVAL means "supported but not available" */ +int u300_gpio_config_get(struct gpio_chip *chip, + unsigned offset, + unsigned long *config) +{ + struct u300_gpio *gpio = to_u300_gpio(chip); + enum pin_config_param param = (enum pin_config_param) *config; + bool biasmode; + u32 drmode; + + /* One bit per pin, clamp to bool range */ + biasmode = !!(readl(U300_PIN_REG(offset, per)) & U300_PIN_BIT(offset)); + + /* Mask out the two bits for this pin and shift to bits 0,1 */ + drmode = readl(U300_PIN_REG(offset, pcr)); + drmode &= (U300_GPIO_PXPCR_PIN_MODE_MASK << ((offset & 0x07) << 1)); + drmode >>= ((offset & 0x07) << 1); + + switch(param) { + case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: + *config = 0; + if (biasmode) + return 0; + else + return -EINVAL; + break; + case PIN_CONFIG_BIAS_PULL_UP: + *config = 0; + if (!biasmode) + return 0; + else + return -EINVAL; + break; + case PIN_CONFIG_DRIVE_PUSH_PULL: + *config = 0; + if (drmode == U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL) + return 0; + else + return -EINVAL; + break; + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + *config = 0; + if (drmode == U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN) + return 0; + else + return -EINVAL; + break; + case PIN_CONFIG_DRIVE_OPEN_SOURCE: + *config = 0; + if (drmode == U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE) + return 0; + else + return -EINVAL; + break; + default: + break; + } + return -ENOTSUPP; +} + +int u300_gpio_config_set(struct gpio_chip *chip, unsigned offset, + enum pin_config_param param) { struct u300_gpio *gpio = to_u300_gpio(chip); unsigned long flags; @@ -620,13 +682,12 @@ static void __init u300_gpio_init_pin(struct u300_gpio *gpio, u300_gpio_direction_output(&gpio->chip, offset, conf->outval); /* Deactivate bias mode for output */ - u300_gpio_config(&gpio->chip, offset, - PIN_CONFIG_BIAS_HIGH_IMPEDANCE, - 0); + u300_gpio_config_set(&gpio->chip, offset, + PIN_CONFIG_BIAS_HIGH_IMPEDANCE); /* Set drive mode for output */ - u300_gpio_config(&gpio->chip, offset, - PIN_CONFIG_DRIVE_PUSH_PULL, 0); + u300_gpio_config_set(&gpio->chip, offset, + PIN_CONFIG_DRIVE_PUSH_PULL); dev_dbg(gpio->dev, "set up pin %d as output, value: %d\n", offset, conf->outval); @@ -637,7 +698,7 @@ static void __init u300_gpio_init_pin(struct u300_gpio *gpio, u300_gpio_set(&gpio->chip, offset, 0); /* Set bias mode for input */ - u300_gpio_config(&gpio->chip, offset, conf->bias_mode, 0); + u300_gpio_config_set(&gpio->chip, offset, conf->bias_mode); dev_dbg(gpio->dev, "set up pin %d as input, bias: %04x\n", offset, conf->bias_mode); diff --git a/drivers/pinctrl/pinctrl-coh901.h b/drivers/pinctrl/pinctrl-coh901.h new file mode 100644 index 0000000..8729422 --- /dev/null +++ b/drivers/pinctrl/pinctrl-coh901.h @@ -0,0 +1,5 @@ +int u300_gpio_config_get(struct gpio_chip *chip, + unsigned offset, + unsigned long *config); +int u300_gpio_config_set(struct gpio_chip *chip, unsigned offset, + enum pin_config_param param); diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c index fc4a281..26eb8cc 100644 --- a/drivers/pinctrl/pinctrl-u300.c +++ b/drivers/pinctrl/pinctrl-u300.c @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include "pinctrl-coh901.h" /* * Register definitions for the U300 Padmux control registers in the @@ -1044,12 +1047,69 @@ static struct pinctrl_gpio_range u300_gpio_ranges[] = { U300_GPIO_RANGE(25, 181, 1), }; +static struct pinctrl_gpio_range *u300_match_gpio_range(unsigned pin) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) { + struct pinctrl_gpio_range *range; + + range = &u300_gpio_ranges[i]; + if (pin >= range->pin_base && + pin <= (range->pin_base + range->npins - 1)) + return range; + } + return NULL; +} + +int u300_pin_config_get(struct pinctrl_dev *pctldev, + unsigned pin, + unsigned long *config) +{ + struct pinctrl_gpio_range *range = u300_match_gpio_range(pin); + + /* We get config for those pins we CAN get it for and that's it */ + if (!range) + return -ENOTSUPP; + + return u300_gpio_config_get(range->gc, + (pin - range->pin_base + range->base), + config); +} + +int u300_pin_config_set(struct pinctrl_dev *pctldev, + unsigned pin, + unsigned long config) +{ + struct pinctrl_gpio_range *range = u300_match_gpio_range(pin); + int ret; + + if (!range) + return -EINVAL; + + /* Note: none of these configurations take any argument */ + ret = u300_gpio_config_set(range->gc, + (pin - range->pin_base + range->base), + pinconf_to_config_param(config)); + if (ret) + return ret; + + return 0; +} + +static struct pinconf_ops u300_pconf_ops = { + .is_generic = true, + .pin_config_get = u300_pin_config_get, + .pin_config_set = u300_pin_config_set, +}; + static struct pinctrl_desc u300_pmx_desc = { .name = DRIVER_NAME, .pins = u300_pads, .npins = ARRAY_SIZE(u300_pads), .pctlops = &u300_pctrl_ops, .pmxops = &u300_pmx_ops, + .confops = &u300_pconf_ops, .owner = THIS_MODULE, };