Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pinctrl: pxa: pxa2xx: add pin configuration support

Add pin configuration for pxa2xx architectures. PXA doesn't provide any
bias, push, pull capabilities. The only capability is to set a state for
the pins when the platform enter sleep or deep sleep mode.

The state of a pin is set by :
- whether the GPIO direction was input or output
- if it is output, a register set programs whether the pin should be
held to ground or VccIO

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Robert Jarzmik and committed by
Linus Walleij
aedf08b6 d530ef9b

+63
+63
drivers/pinctrl/pxa/pinctrl-pxa2xx.c
··· 184 184 .gpio_set_direction = pxa2xx_pmx_gpio_set_direction, 185 185 }; 186 186 187 + static int pxa2xx_pconf_group_get(struct pinctrl_dev *pctldev, 188 + unsigned group, 189 + unsigned long *config) 190 + { 191 + struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); 192 + struct pxa_pinctrl_group *g = pctl->groups + group; 193 + unsigned long flags; 194 + unsigned pin = g->pin; 195 + void __iomem *pgsr = pctl->base_pgsr[pin / 32]; 196 + u32 val; 197 + 198 + spin_lock_irqsave(&pctl->lock, flags); 199 + val = readl_relaxed(pgsr) & BIT(pin % 32); 200 + *config = val ? PIN_CONFIG_LOW_POWER_MODE : 0; 201 + spin_unlock_irqrestore(&pctl->lock, flags); 202 + 203 + dev_dbg(pctl->dev, "get sleep gpio state(pin=%d) %d\n", 204 + pin, !!val); 205 + return 0; 206 + } 207 + 208 + static int pxa2xx_pconf_group_set(struct pinctrl_dev *pctldev, 209 + unsigned group, 210 + unsigned long *configs, 211 + unsigned num_configs) 212 + { 213 + struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); 214 + struct pxa_pinctrl_group *g = pctl->groups + group; 215 + unsigned long flags; 216 + unsigned pin = g->pin; 217 + void __iomem *pgsr = pctl->base_pgsr[pin / 32]; 218 + int i, is_set = 0; 219 + u32 val; 220 + 221 + for (i = 0; i < num_configs; i++) { 222 + switch (pinconf_to_config_param(configs[i])) { 223 + case PIN_CONFIG_LOW_POWER_MODE: 224 + is_set = pinconf_to_config_argument(configs[i]); 225 + break; 226 + default: 227 + return -EINVAL; 228 + } 229 + } 230 + 231 + dev_dbg(pctl->dev, "set sleep gpio state(pin=%d) %d\n", 232 + pin, is_set); 233 + 234 + spin_lock_irqsave(&pctl->lock, flags); 235 + val = readl_relaxed(pgsr); 236 + val = (val & ~BIT(pin % 32)) | (is_set ? BIT(pin % 32) : 0); 237 + writel_relaxed(val, pgsr); 238 + spin_unlock_irqrestore(&pctl->lock, flags); 239 + 240 + return 0; 241 + } 242 + 243 + static const struct pinconf_ops pxa2xx_pconf_ops = { 244 + .pin_config_group_get = pxa2xx_pconf_group_get, 245 + .pin_config_group_set = pxa2xx_pconf_group_set, 246 + .is_generic = true, 247 + }; 248 + 187 249 static struct pinctrl_desc pxa2xx_pinctrl_desc = { 250 + .confops = &pxa2xx_pconf_ops, 188 251 .pctlops = &pxa2xx_pctl_ops, 189 252 .pmxops = &pxa2xx_pinmux_ops, 190 253 };