From patchwork Tue Jan 21 05:52:30 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Marek Roszko X-Patchwork-Id: 312783 Return-Path: X-Original-To: incoming-imx@patchwork.ozlabs.org Delivered-To: patchwork-incoming-imx@bilbo.ozlabs.org Received: from casper.infradead.org (unknown [IPv6:2001:770:15f::2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 68B0E2C009F for ; Tue, 21 Jan 2014 16:53:15 +1100 (EST) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1W5UGl-0003Fs-J6; Tue, 21 Jan 2014 05:53:03 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1W5UGj-00030G-3l; Tue, 21 Jan 2014 05:53:01 +0000 Received: from mail-qe0-f54.google.com ([209.85.128.54]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1W5UGg-0002yq-BW for linux-arm-kernel@lists.infradead.org; Tue, 21 Jan 2014 05:52:59 +0000 Received: by mail-qe0-f54.google.com with SMTP id df13so6761347qeb.27 for ; Mon, 20 Jan 2014 21:52:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type:content-transfer-encoding; bh=dOQwu1/+FNEQUvn9kExNbQRpiwaXtws+Gm1OcRz9Zuc=; b=BYbsGI3jlyMt/WolYVjIJ94NLPEQG0JadOM1/fK9QxrFamuv/MjJbHHR8+2fXyMJhj ugDt1T9J3DmdiAvfrDKLoBa+S/sJ8fH124y0ksg/tQwI+7uIxHv2VkinhDAb5mz6E5BV oQJjK8mxl2FPnKdkkA7//OucDAkLWqdXJsg+9Zl0VW5uSs2fbobTnirmwfPyQEya7Kqt KUcMxVdqjkKO44uyfd5UBeB/bZSs7f6ixj3mZQaVaDbaWmS3EsIMpVGt9hwNZxEeA+Ze hkzJhVQNjynmx9sZB6XkBdnnD1KHS1dNBOmpAy/11s/F/x63ynGM8g7QefsIXpDJgzt9 bXOA== X-Received: by 10.224.7.10 with SMTP id b10mr34561156qab.50.1390283551679; Mon, 20 Jan 2014 21:52:31 -0800 (PST) Received: from [192.168.1.8] (ool-18e4a8f6.dyn.optonline.net. [24.228.168.246]) by mx.google.com with ESMTPSA id f5sm5157125qas.11.2014.01.20.21.52.30 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 20 Jan 2014 21:52:30 -0800 (PST) Message-ID: <52DE0B1E.90106@gmail.com> Date: Tue, 21 Jan 2014 00:52:30 -0500 From: Marek Roszko User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20130509 Thunderbird/17.0.6 MIME-Version: 1.0 To: Jean-Christophe PLAGNIOL-VILLARD Subject: Re: pinctrl: at91: drive strength control References: <1390266470.26159.1.camel@bb> <20140121021925.GM9558@ns203013.ovh.net> <20140121040922.GN9558@ns203013.ovh.net> In-Reply-To: <20140121040922.GN9558@ns203013.ovh.net> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140121_005258_498076_1853C152 X-CRM114-Status: GOOD ( 18.82 ) X-Spam-Score: -2.7 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.128.54 listed in list.dnswl.org] 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (mark.roszko[at]gmail.com) -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature Cc: Nicolas Ferre , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org List-Id: linux-imx-kernel.lists.patchwork.ozlabs.org Alright, added a SAMA5D3 compatible type and gave it's own drive strength ops. Moved the defines to inline funcs. Made the bindings independent of soc. Hopefully tabs appear this time, I haven't figured out the whole mailing list - email client thing and finding a client that doesn't convert spaces/tabs is hard. Acked-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/mach-at91/include/mach/at91sam9x5.h | 3 + arch/arm/mach-at91/include/mach/sama5d3.h | 3 + drivers/pinctrl/pinctrl-at91.c | 123 +++++++++++++++++++++++++- include/dt-bindings/pinctrl/at91.h | 5 ++ 4 files changed, 133 insertions(+), 1 deletion(-) #define AT91_PIOC 2 diff --git a/arch/arm/mach-at91/include/mach/at91sam9x5.h b/arch/arm/mach-at91/include/mach/at91sam9x5.h index 2fc76c4..2efeb0a 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9x5.h +++ b/arch/arm/mach-at91/include/mach/at91sam9x5.h @@ -59,6 +59,9 @@ */ #define AT91SAM9X5_BASE_RTC 0xfffffeb0 +#define AT91SAM9X5_PIO_DRIVER1 0x114 /*PIO Driver 1 register offset*/ +#define AT91SAM9X5_PIO_DRIVER2 0x118 /*PIO Driver 2 register offset*/ + /* * Internal Memory. */ diff --git a/arch/arm/mach-at91/include/mach/sama5d3.h b/arch/arm/mach-at91/include/mach/sama5d3.h index 25613d8..5d434f9 100644 --- a/arch/arm/mach-at91/include/mach/sama5d3.h +++ b/arch/arm/mach-at91/include/mach/sama5d3.h @@ -77,6 +77,9 @@ */ #define SAMA5D3_BASE_RTC 0xfffffeb0 +#define SAMA5D3_PIO_DRIVER1 0x118 /*PIO Driver 1 register offset*/ +#define SAMA5D3_PIO_DRIVER2 0x11C /*PIO Driver 2 register offset*/ + /* * Internal Memory */ diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index a7549c4..984c3be 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -62,10 +62,21 @@ static int gpio_banks; #define DEGLITCH (1 << 2) #define PULL_DOWN (1 << 3) #define DIS_SCHMIT (1 << 4) +#define DRIVE_STRENGTH_SHIFT 5 +#define DRIVE_STRENGTH (0x3 << DRIVE_STRENGTH_SHIFT) #define DEBOUNCE (1 << 16) #define DEBOUNCE_VAL_SHIFT 17 #define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT) +#define DRIVE_STRENGTH_DEFAULT (0x0 << 5) +#define DRIVE_STRENGTH_LOW (0x1 << 5) +#define DRIVE_STRENGTH_MED (0x2 << 5) +#define DRIVE_STRENGTH_HI (0x3 << 5) + + +#define DRIVE_STRENGTH_MASK 0x3 +#define NUM_PINS_PER_DIVIDED_REGS 16 + /** * struct at91_pmx_func - describes AT91 pinmux functions * @name: the name of this specific function @@ -148,6 +159,8 @@ struct at91_pinctrl_mux_ops { void (*set_deglitch)(void __iomem *pio, unsigned mask, bool is_on); bool (*get_debounce)(void __iomem *pio, unsigned pin, u32 *div); void (*set_debounce)(void __iomem *pio, unsigned mask, bool is_on, u32 div); + unsigned (*get_drivestrength)(void __iomem *pio, unsigned pin); + void (*set_drivestrength)(void __iomem *pio, unsigned pin, u32 strength); bool (*get_pulldown)(void __iomem *pio, unsigned pin); void (*set_pulldown)(void __iomem *pio, unsigned mask, bool is_on); bool (*get_schmitt_trig)(void __iomem *pio, unsigned pin); @@ -319,6 +332,22 @@ static unsigned pin_to_mask(unsigned int pin) return 1 << pin; }​ +static inline int two_bit_pin_value_shift(unsigned pin) +{ + return 2*((pin >= NUM_PINS_PER_DIVIDED_REGS) ? pin - NUM_PINS_PER_DIVIDED_REGS : pin); +} + + +static unsigned sama5d3_get_drive_register(unsigned int pin) +{ + return (pin > NUM_PINS_PER_DIVIDED_REGS-1) ? SAMA5D3_PIO_DRIVER2 : SAMA5D3_PIO_DRIVER1; +} + +static unsigned at91sam9x5_get_drive_register(unsigned int pin) +{ + return (pin > NUM_PINS_PER_DIVIDED_REGS-1) ? AT91SAM9X5_PIO_DRIVER2 : AT91SAM9X5_PIO_DRIVER1; +} + static void at91_mux_disable_interrupt(void __iomem *pio, unsigned mask) { writel_relaxed(mask, pio + PIO_IDR); @@ -462,6 +491,67 @@ static void at91_mux_pio3_set_pulldown(void __iomem *pio, unsigned mask, bool is __raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR)); }​ +static inline u32 read_drive_strength(void __iomem *reg, unsigned pin) +{ + return (__raw_readl(reg) + >> two_bit_pin_value_shift(pin)) & DRIVE_STRENGTH_MASK; +} + +static unsigned at91_mux_sama5d3_get_drivestrength(void __iomem *pio, unsigned pin) +{ + unsigned tmp = read_drive_strength(pio + sama5d3_get_drive_register(pin), pin); + + if (!tmp) + tmp = DRIVE_STRENGTH_LOW; + + return tmp; +} + +static unsigned at91_mux_sam9x5_get_drivestrength(void __iomem *pio, unsigned pin) +{ + unsigned tmp = read_drive_strength(pio + at91sam9x5_get_drive_register(pin), pin); + + /*inverse settings*/ + tmp = DRIVE_STRENGTH_HI - tmp; + + return tmp; +} + +static void set_drive_strength(void __iomem *reg, unsigned pin, u32 strength) +{ + unsigned tmp = __raw_readl(reg); + + tmp &= ~(DRIVE_STRENGTH_MASK << two_bit_pin_value_shift(pin)); + tmp |= strength << two_bit_pin_value_shift(pin); + + __raw_writel(tmp, reg); +} + +static void at91_mux_sama5d3_set_drivestrength(void __iomem *pio, unsigned pin, + u32 setting) +{ + /* do nothing if setting is zero */ + if (!setting) + return; + + /* strength is 1 to 1 with setting for SAMA5 */ + set_drive_strength(pio + sama5d3_get_drive_register(pin), pin, setting); +} + +static void at91_mux_sam9x5_set_drivestrength(void __iomem *pio, unsigned pin, + u32 setting) +{ + /* do nothing if setting is zero */ + if (!setting) + return; + + /* strength is inverse on SAM9s, 0 = hi, 1 = med, 2 = low, 3 = rsvd */ + setting = DRIVE_STRENGTH_HI - setting; + + set_drive_strength(pio + at91sam9x5_get_drive_register(pin), pin, setting); +} + + static void at91_mux_pio3_disable_schmitt_trig(void __iomem *pio, unsigned mask) { __raw_writel(__raw_readl(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT); @@ -491,6 +581,8 @@ static struct at91_pinctrl_mux_ops at91sam9x5_ops = { .set_deglitch = at91_mux_pio3_set_deglitch, .get_debounce = at91_mux_pio3_get_debounce, .set_debounce = at91_mux_pio3_set_debounce, + .get_drivestrength = at91_mux_sam9x5_get_drivestrength, + .set_drivestrength = at91_mux_sam9x5_set_drivestrength, .get_pulldown = at91_mux_pio3_get_pulldown, .set_pulldown = at91_mux_pio3_set_pulldown, .get_schmitt_trig = at91_mux_pio3_get_schmitt_trig, @@ -498,6 +590,26 @@ static struct at91_pinctrl_mux_ops at91sam9x5_ops = { .irq_type = alt_gpio_irq_type, }; +static struct at91_pinctrl_mux_ops sama5d3_ops = { + .get_periph = at91_mux_pio3_get_periph, + .mux_A_periph = at91_mux_pio3_set_A_periph, + .mux_B_periph = at91_mux_pio3_set_B_periph, + .mux_C_periph = at91_mux_pio3_set_C_periph, + .mux_D_periph = at91_mux_pio3_set_D_periph, + .get_deglitch = at91_mux_pio3_get_deglitch, + .set_deglitch = at91_mux_pio3_set_deglitch, + .get_debounce = at91_mux_pio3_get_debounce, + .set_debounce = at91_mux_pio3_set_debounce, + .get_drivestrength = at91_mux_sama5d3_get_drivestrength, + .set_drivestrength = at91_mux_sama5d3_set_drivestrength, + .get_pulldown = at91_mux_pio3_get_pulldown, + .set_pulldown = at91_mux_pio3_set_pulldown, + .get_schmitt_trig = at91_mux_pio3_get_schmitt_trig, + .disable_schmitt_trig = at91_mux_pio3_disable_schmitt_trig, + .irq_type = alt_gpio_irq_type, +}; + + static void at91_pin_dbg(const struct device *dev, const struct at91_pmx_pin *pin) { if (pin->mux) { @@ -736,6 +848,9 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev, *config |= DEGLITCH; if (info->ops->get_debounce && info->ops->get_debounce(pio, pin, &div)) *config |= DEBOUNCE | (div << DEBOUNCE_VAL_SHIFT); + if (info->ops->get_drivestrength) + *config |= DRIVE_STRENGTH | (info->ops->get_drivestrength(pio, pin) + << DRIVE_STRENGTH_SHIFT); if (info->ops->get_pulldown && info->ops->get_pulldown(pio, pin)) *config |= PULL_DOWN; if (info->ops->get_schmitt_trig && info->ops->get_schmitt_trig(pio, pin)) @@ -753,6 +868,7 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev, void __iomem *pio; int i; unsigned long config; + unsigned pin; for (i = 0; i < num_configs; i++) { config = configs[i]; @@ -761,7 +877,8 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev, "%s:%d, pin_id=%d, config=0x%lx", __func__, __LINE__, pin_id, config); pio = pin_to_controller(info, pin_to_bank(pin_id)); - mask = pin_to_mask(pin_id % MAX_NB_GPIO_PER_BANK); + pin = pin_id % MAX_NB_GPIO_PER_BANK; + mask = pin_to_mask(pin); if (config & PULL_UP && config & PULL_DOWN) return -EINVAL; @@ -773,6 +890,9 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev, if (info->ops->set_debounce) info->ops->set_debounce(pio, mask, config & DEBOUNCE, (config & DEBOUNCE_VAL) >> DEBOUNCE_VAL_SHIFT); + if (info->ops->set_drivestrength) + info->ops->set_drivestrength(pio, pin, + (config & DRIVE_STRENGTH) >> DRIVE_STRENGTH_SHIFT); if (info->ops->set_pulldown) info->ops->set_pulldown(pio, mask, config & PULL_DOWN); if (info->ops->disable_schmitt_trig && config & DIS_SCHMIT) @@ -1551,6 +1671,7 @@ static void at91_gpio_probe_fixup(void) static struct of_device_id at91_gpio_of_match[] = { { .compatible = "atmel,at91sam9x5-gpio", .data = &at91sam9x5_ops, }, + { .compatible = "atmel,sama5d3-gpio", .data = &sama5d3_ops, }, { .compatible = "atmel,at91rm9200-gpio", .data = &at91rm9200_ops }, { /* sentinel */ } }; diff --git a/include/dt-bindings/pinctrl/at91.h b/include/dt-bindings/pinctrl/at91.h index 0fee6ff..af71ebb 100644 --- a/include/dt-bindings/pinctrl/at91.h +++ b/include/dt-bindings/pinctrl/at91.h @@ -20,6 +20,11 @@ #define AT91_PINCTRL_PULL_UP_DEGLITCH (AT91_PINCTRL_PULL_UP | AT91_PINCTRL_DEGLITCH) +#define AT91_PINCTRL_DRIVE_STRENGTH_DEFAULT (0x0 << 5) +#define AT91_PINCTRL_DRIVE_STRENGTH_LOW (0x1 << 5) +#define AT91_PINCTRL_DRIVE_STRENGTH_MED (0x2 << 5) +#define AT91_PINCTRL_DRIVE_STRENGTH_HI (0x3 << 5) + #define AT91_PIOA 0 #define AT91_PIOB 1