summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/freescale
diff options
context:
space:
mode:
authorDong Aisheng <aisheng.dong@nxp.com>2017-05-19 03:05:42 -0400
committerLinus Walleij <linus.walleij@linaro.org>2017-05-22 05:03:47 -0400
commita5cadbbb081cb84a9fdb14391fb461a41f089a0a (patch)
treee9999bdde75f877b3bdf0e2ac36438851a7c78ef /drivers/pinctrl/freescale
parent66b54e3a5a64925d9819eae86b8f36e90e60037f (diff)
pinctrl: imx: add generic pin config core support
The design is based on the exist architecture that the core will provide a uniformed way to decode the generic pin config into platform config register raw data according to the imx_cfg_params_decode maps registered by platform. Two useful macros, IMX_CFG_PARAMS_DECODE and IMX_CFG_PARAMS_DECODE_INVERT, are created for platform to register decode map conveniently. In order to cope with some special case, a platform specific fixup() function is also available to use. Note that rather than fully utilizing the generic pinconf support provided by pinctrl core, IMX only adopts the device tree bindings of generic pinconf. The config used in .pin_config_get[set] are raw register data instead of generic one which makes us align the exist using. And that's also why we cannot set pinconf_ops.is_generic. Cc: Bai Ping <ping.bai@nxp.com> Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com> Acked-by: Shawn Guo <shawnguo@kernel.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/freescale')
-rw-r--r--drivers/pinctrl/freescale/Kconfig2
-rw-r--r--drivers/pinctrl/freescale/pinctrl-imx.c108
-rw-r--r--drivers/pinctrl/freescale/pinctrl-imx.h25
3 files changed, 124 insertions, 11 deletions
diff --git a/drivers/pinctrl/freescale/Kconfig b/drivers/pinctrl/freescale/Kconfig
index cae05e76c111..0b266b2aecd4 100644
--- a/drivers/pinctrl/freescale/Kconfig
+++ b/drivers/pinctrl/freescale/Kconfig
@@ -2,7 +2,7 @@ config PINCTRL_IMX
2 bool 2 bool
3 select GENERIC_PINCTRL_GROUPS 3 select GENERIC_PINCTRL_GROUPS
4 select GENERIC_PINMUX_FUNCTIONS 4 select GENERIC_PINMUX_FUNCTIONS
5 select PINCONF 5 select GENERIC_PINCONF
6 select REGMAP 6 select REGMAP
7 7
8config PINCTRL_IMX1_CORE 8config PINCTRL_IMX1_CORE
diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c
index 89421f532726..328d079b237e 100644
--- a/drivers/pinctrl/freescale/pinctrl-imx.c
+++ b/drivers/pinctrl/freescale/pinctrl-imx.c
@@ -27,6 +27,7 @@
27#include <linux/regmap.h> 27#include <linux/regmap.h>
28 28
29#include "../core.h" 29#include "../core.h"
30#include "../pinconf.h"
30#include "../pinmux.h" 31#include "../pinmux.h"
31#include "pinctrl-imx.h" 32#include "pinctrl-imx.h"
32 33
@@ -361,6 +362,62 @@ static const struct pinmux_ops imx_pmx_ops = {
361 .gpio_set_direction = imx_pmx_gpio_set_direction, 362 .gpio_set_direction = imx_pmx_gpio_set_direction,
362}; 363};
363 364
365/* decode generic config into raw register values */
366static u32 imx_pinconf_decode_generic_config(struct imx_pinctrl *ipctl,
367 unsigned long *configs,
368 unsigned int num_configs)
369{
370 struct imx_pinctrl_soc_info *info = ipctl->info;
371 struct imx_cfg_params_decode *decode;
372 enum pin_config_param param;
373 u32 raw_config = 0;
374 u32 param_val;
375 int i, j;
376
377 WARN_ON(num_configs > info->num_decodes);
378
379 for (i = 0; i < num_configs; i++) {
380 param = pinconf_to_config_param(configs[i]);
381 param_val = pinconf_to_config_argument(configs[i]);
382 decode = info->decodes;
383 for (j = 0; j < info->num_decodes; j++) {
384 if (param == decode->param) {
385 if (decode->invert)
386 param_val = !param_val;
387 raw_config |= (param_val << decode->shift)
388 & decode->mask;
389 break;
390 }
391 decode++;
392 }
393 }
394
395 if (info->fixup)
396 info->fixup(configs, num_configs, &raw_config);
397
398 return raw_config;
399}
400
401static u32 imx_pinconf_parse_generic_config(struct device_node *np,
402 struct imx_pinctrl *ipctl)
403{
404 struct imx_pinctrl_soc_info *info = ipctl->info;
405 struct pinctrl_dev *pctl = ipctl->pctl;
406 unsigned int num_configs;
407 unsigned long *configs;
408 int ret;
409
410 if (!info->generic_pinconf)
411 return 0;
412
413 ret = pinconf_generic_parse_dt_config(np, pctl, &configs,
414 &num_configs);
415 if (ret)
416 return 0;
417
418 return imx_pinconf_decode_generic_config(ipctl, configs, num_configs);
419}
420
364static int imx_pinconf_get(struct pinctrl_dev *pctldev, 421static int imx_pinconf_get(struct pinctrl_dev *pctldev,
365 unsigned pin_id, unsigned long *config) 422 unsigned pin_id, unsigned long *config)
366{ 423{
@@ -479,9 +536,10 @@ static const struct pinconf_ops imx_pinconf_ops = {
479 536
480static int imx_pinctrl_parse_groups(struct device_node *np, 537static int imx_pinctrl_parse_groups(struct device_node *np,
481 struct group_desc *grp, 538 struct group_desc *grp,
482 struct imx_pinctrl_soc_info *info, 539 struct imx_pinctrl *ipctl,
483 u32 index) 540 u32 index)
484{ 541{
542 struct imx_pinctrl_soc_info *info = ipctl->info;
485 int size, pin_size; 543 int size, pin_size;
486 const __be32 *list; 544 const __be32 *list;
487 int i; 545 int i;
@@ -493,25 +551,44 @@ static int imx_pinctrl_parse_groups(struct device_node *np,
493 pin_size = SHARE_FSL_PIN_SIZE; 551 pin_size = SHARE_FSL_PIN_SIZE;
494 else 552 else
495 pin_size = FSL_PIN_SIZE; 553 pin_size = FSL_PIN_SIZE;
554
555 if (info->generic_pinconf)
556 pin_size -= 4;
557
496 /* Initialise group */ 558 /* Initialise group */
497 grp->name = np->name; 559 grp->name = np->name;
498 560
499 /* 561 /*
500 * the binding format is fsl,pins = <PIN_FUNC_ID CONFIG ...>, 562 * the binding format is fsl,pins = <PIN_FUNC_ID CONFIG ...>,
501 * do sanity check and calculate pins number 563 * do sanity check and calculate pins number
564 *
565 * First try legacy 'fsl,pins' property, then fall back to the
566 * generic 'pins'.
567 *
568 * Note: for generic 'pins' case, there's no CONFIG part in
569 * the binding format.
502 */ 570 */
503 list = of_get_property(np, "fsl,pins", &size); 571 list = of_get_property(np, "fsl,pins", &size);
504 if (!list) { 572 if (!list) {
505 dev_err(info->dev, "no fsl,pins property in node %s\n", np->full_name); 573 list = of_get_property(np, "pins", &size);
506 return -EINVAL; 574 if (!list) {
575 dev_err(info->dev,
576 "no fsl,pins and pins property in node %s\n",
577 np->full_name);
578 return -EINVAL;
579 }
507 } 580 }
508 581
509 /* we do not check return since it's safe node passed down */ 582 /* we do not check return since it's safe node passed down */
510 if (!size || size % pin_size) { 583 if (!size || size % pin_size) {
511 dev_err(info->dev, "Invalid fsl,pins property in node %s\n", np->full_name); 584 dev_err(info->dev, "Invalid fsl,pins or pins property in node %s\n",
585 np->full_name);
512 return -EINVAL; 586 return -EINVAL;
513 } 587 }
514 588
589 /* first try to parse the generic pin config */
590 config = imx_pinconf_parse_generic_config(np, ipctl);
591
515 grp->num_pins = size / pin_size; 592 grp->num_pins = size / pin_size;
516 grp->data = devm_kzalloc(info->dev, grp->num_pins * 593 grp->data = devm_kzalloc(info->dev, grp->num_pins *
517 sizeof(struct imx_pin), GFP_KERNEL); 594 sizeof(struct imx_pin), GFP_KERNEL);
@@ -548,11 +625,18 @@ static int imx_pinctrl_parse_groups(struct device_node *np,
548 pin->mux_mode = be32_to_cpu(*list++); 625 pin->mux_mode = be32_to_cpu(*list++);
549 pin->input_val = be32_to_cpu(*list++); 626 pin->input_val = be32_to_cpu(*list++);
550 627
551 /* SION bit is in mux register */ 628 if (info->generic_pinconf) {
552 config = be32_to_cpu(*list++); 629 /* generic pin config decoded */
553 if (config & IMX_PAD_SION) 630 pin->config = config;
554 pin->mux_mode |= IOMUXC_CONFIG_SION; 631 } else {
555 pin->config = config & ~IMX_PAD_SION; 632 /* legacy pin config read from devicetree */
633 config = be32_to_cpu(*list++);
634
635 /* SION bit is in mux register */
636 if (config & IMX_PAD_SION)
637 pin->mux_mode |= IOMUXC_CONFIG_SION;
638 pin->config = config & ~IMX_PAD_SION;
639 }
556 640
557 dev_dbg(info->dev, "%s: 0x%x 0x%08lx", info->pins[pin_id].name, 641 dev_dbg(info->dev, "%s: 0x%x 0x%08lx", info->pins[pin_id].name,
558 pin->mux_mode, pin->config); 642 pin->mux_mode, pin->config);
@@ -603,7 +687,7 @@ static int imx_pinctrl_parse_functions(struct device_node *np,
603 info->group_index++, grp); 687 info->group_index++, grp);
604 mutex_unlock(&info->mutex); 688 mutex_unlock(&info->mutex);
605 689
606 imx_pinctrl_parse_groups(child, grp, info, i++); 690 imx_pinctrl_parse_groups(child, grp, ipctl, i++);
607 } 691 }
608 692
609 return 0; 693 return 0;
@@ -774,6 +858,10 @@ int imx_pinctrl_probe(struct platform_device *pdev,
774 imx_pinctrl_desc->confops = &imx_pinconf_ops; 858 imx_pinctrl_desc->confops = &imx_pinconf_ops;
775 imx_pinctrl_desc->owner = THIS_MODULE; 859 imx_pinctrl_desc->owner = THIS_MODULE;
776 860
861 /* for generic pinconf */
862 imx_pinctrl_desc->custom_params = info->custom_params;
863 imx_pinctrl_desc->num_custom_params = info->num_custom_params;
864
777 mutex_init(&info->mutex); 865 mutex_init(&info->mutex);
778 866
779 ipctl->info = info; 867 ipctl->info = info;
diff --git a/drivers/pinctrl/freescale/pinctrl-imx.h b/drivers/pinctrl/freescale/pinctrl-imx.h
index ff2d3e56b7c5..38aa53c671ed 100644
--- a/drivers/pinctrl/freescale/pinctrl-imx.h
+++ b/drivers/pinctrl/freescale/pinctrl-imx.h
@@ -15,6 +15,8 @@
15#ifndef __DRIVERS_PINCTRL_IMX_H 15#ifndef __DRIVERS_PINCTRL_IMX_H
16#define __DRIVERS_PINCTRL_IMX_H 16#define __DRIVERS_PINCTRL_IMX_H
17 17
18#include <linux/pinctrl/pinconf-generic.h>
19
18struct platform_device; 20struct platform_device;
19 21
20/** 22/**
@@ -44,6 +46,14 @@ struct imx_pin_reg {
44 s16 conf_reg; 46 s16 conf_reg;
45}; 47};
46 48
49/* decode a generic config into raw register value */
50struct imx_cfg_params_decode {
51 enum pin_config_param param;
52 u32 mask;
53 u8 shift;
54 bool invert;
55};
56
47struct imx_pinctrl_soc_info { 57struct imx_pinctrl_soc_info {
48 struct device *dev; 58 struct device *dev;
49 const struct pinctrl_pin_desc *pins; 59 const struct pinctrl_pin_desc *pins;
@@ -53,8 +63,23 @@ struct imx_pinctrl_soc_info {
53 unsigned int flags; 63 unsigned int flags;
54 const char *gpr_compatible; 64 const char *gpr_compatible;
55 struct mutex mutex; 65 struct mutex mutex;
66
67 /* generic pinconf */
68 bool generic_pinconf;
69 const struct pinconf_generic_params *custom_params;
70 unsigned int num_custom_params;
71 struct imx_cfg_params_decode *decodes;
72 unsigned int num_decodes;
73 void (*fixup)(unsigned long *configs, unsigned int num_configs,
74 u32 *raw_config);
56}; 75};
57 76
77#define IMX_CFG_PARAMS_DECODE(p, m, o) \
78 { .param = p, .mask = m, .shift = o, .invert = false, }
79
80#define IMX_CFG_PARAMS_DECODE_INVERT(p, m, o) \
81 { .param = p, .mask = m, .shift = o, .invert = true, }
82
58#define SHARE_MUX_CONF_REG 0x1 83#define SHARE_MUX_CONF_REG 0x1
59#define ZERO_OFFSET_VALID 0x2 84#define ZERO_OFFSET_VALID 0x2
60 85