aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorStefan Agner <stefan@agner.ch>2014-10-16 15:47:57 -0400
committerLinus Walleij <linus.walleij@linaro.org>2014-10-28 11:59:30 -0400
commit1f2b045205ce9f54babf912c9d875d7b013e4660 (patch)
tree9003cc359a89da81414621481917d59047941ffc /drivers/pinctrl
parent2e53727658f1cfd23d4bc4a91967b7d9170d0a74 (diff)
pinctrl: imx: add gpio pinmux support for vf610
Add pinmux support for GPIO for Vybrid (vf610) IOMUX controller. This is needed since direction configuration is not part of the GPIO module in Vybrid. Signed-off-by: Stefan Agner <stefan@agner.ch> Acked-by: Shawn Guo <shawn.guo@freescale.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/freescale/pinctrl-imx.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c
index f2446769247f..52f2b9404fe0 100644
--- a/drivers/pinctrl/freescale/pinctrl-imx.c
+++ b/drivers/pinctrl/freescale/pinctrl-imx.c
@@ -294,11 +294,83 @@ static int imx_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector,
294 return 0; 294 return 0;
295} 295}
296 296
297static int imx_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
298 struct pinctrl_gpio_range *range, unsigned offset)
299{
300 struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
301 const struct imx_pinctrl_soc_info *info = ipctl->info;
302 const struct imx_pin_reg *pin_reg;
303 struct imx_pin_group *grp;
304 struct imx_pin *imx_pin;
305 unsigned int pin, group;
306 u32 reg;
307
308 /* Currently implementation only for shared mux/conf register */
309 if (!(info->flags & SHARE_MUX_CONF_REG))
310 return -EINVAL;
311
312 pin_reg = &info->pin_regs[offset];
313 if (pin_reg->mux_reg == -1)
314 return -EINVAL;
315
316 /* Find the pinctrl config with GPIO mux mode for the requested pin */
317 for (group = 0; group < info->ngroups; group++) {
318 grp = &info->groups[group];
319 for (pin = 0; pin < grp->npins; pin++) {
320 imx_pin = &grp->pins[pin];
321 if (imx_pin->pin == offset && !imx_pin->mux_mode)
322 goto mux_pin;
323 }
324 }
325
326 return -EINVAL;
327
328mux_pin:
329 reg = readl(ipctl->base + pin_reg->mux_reg);
330 reg &= ~(0x7 << 20);
331 reg |= imx_pin->config;
332 writel(reg, ipctl->base + pin_reg->mux_reg);
333
334 return 0;
335}
336
337static int imx_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
338 struct pinctrl_gpio_range *range, unsigned offset, bool input)
339{
340 struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
341 const struct imx_pinctrl_soc_info *info = ipctl->info;
342 const struct imx_pin_reg *pin_reg;
343 u32 reg;
344
345 /*
346 * Only Vybrid has the input/output buffer enable flags (IBE/OBE)
347 * They are part of the shared mux/conf register.
348 */
349 if (!(info->flags & SHARE_MUX_CONF_REG))
350 return -EINVAL;
351
352 pin_reg = &info->pin_regs[offset];
353 if (pin_reg->mux_reg == -1)
354 return -EINVAL;
355
356 /* IBE always enabled allows us to read the value "on the wire" */
357 reg = readl(ipctl->base + pin_reg->mux_reg);
358 if (input)
359 reg &= ~0x2;
360 else
361 reg |= 0x2;
362 writel(reg, ipctl->base + pin_reg->mux_reg);
363
364 return 0;
365}
366
297static const struct pinmux_ops imx_pmx_ops = { 367static const struct pinmux_ops imx_pmx_ops = {
298 .get_functions_count = imx_pmx_get_funcs_count, 368 .get_functions_count = imx_pmx_get_funcs_count,
299 .get_function_name = imx_pmx_get_func_name, 369 .get_function_name = imx_pmx_get_func_name,
300 .get_function_groups = imx_pmx_get_groups, 370 .get_function_groups = imx_pmx_get_groups,
301 .set_mux = imx_pmx_set, 371 .set_mux = imx_pmx_set,
372 .gpio_request_enable = imx_pmx_gpio_request_enable,
373 .gpio_set_direction = imx_pmx_gpio_set_direction,
302}; 374};
303 375
304static int imx_pinconf_get(struct pinctrl_dev *pctldev, 376static int imx_pinconf_get(struct pinctrl_dev *pctldev,