/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2015-2016 Socionext Inc. * Author: Masahiro Yamada */ #ifndef __PINCTRL_UNIPHIER_H__ #define __PINCTRL_UNIPHIER_H__ #include #include #include #include #include /* drive strength control register number */ #define UNIPHIER_PIN_DRVCTRL_SHIFT 0 #define UNIPHIER_PIN_DRVCTRL_BITS 9 #define UNIPHIER_PIN_DRVCTRL_MASK ((1U << (UNIPHIER_PIN_DRVCTRL_BITS)) \ - 1) /* drive control type */ #define UNIPHIER_PIN_DRV_TYPE_SHIFT ((UNIPHIER_PIN_DRVCTRL_SHIFT) + \ (UNIPHIER_PIN_DRVCTRL_BITS)) #define UNIPHIER_PIN_DRV_TYPE_BITS 2 #define UNIPHIER_PIN_DRV_TYPE_MASK ((1U << (UNIPHIER_PIN_DRV_TYPE_BITS)) \ - 1) /* drive control type */ enum uniphier_pin_drv_type { UNIPHIER_PIN_DRV_1BIT, /* 2 level control: 4/8 mA */ UNIPHIER_PIN_DRV_2BIT, /* 4 level control: 8/12/16/20 mA */ UNIPHIER_PIN_DRV_3BIT, /* 8 level control: 4/5/7/9/11/12/14/16 mA */ }; #define UNIPHIER_PIN_DRVCTRL(x) \ (((x) & (UNIPHIER_PIN_DRVCTRL_MASK)) << (UNIPHIER_PIN_DRVCTRL_SHIFT)) #define UNIPHIER_PIN_DRV_TYPE(x) \ (((x) & (UNIPHIER_PIN_DRV_TYPE_MASK)) << (UNIPHIER_PIN_DRV_TYPE_SHIFT)) #define UNIPHIER_PIN_ATTR_PACKED(drvctrl, drv_type) \ UNIPHIER_PIN_DRVCTRL(drvctrl) | \ UNIPHIER_PIN_DRV_TYPE(drv_type) static inline unsigned int uniphier_pin_get_drvctrl(unsigned int data) { return (data >> UNIPHIER_PIN_DRVCTRL_SHIFT) & UNIPHIER_PIN_DRVCTRL_MASK; } static inline unsigned int uniphier_pin_get_drv_type(unsigned int data) { return (data >> UNIPHIER_PIN_DRV_TYPE_SHIFT) & UNIPHIER_PIN_DRV_TYPE_MASK; } /** * struct uniphier_pinctrl_pin - pin data for UniPhier SoC * * @number: pin number * @data: additional per-pin data */ struct uniphier_pinctrl_pin { unsigned number; const char *name; unsigned int data; }; /** * struct uniphier_pinctrl_group - pin group data for UniPhier SoC * * @name: pin group name * @pins: array of pins that belong to the group * @num_pins: number of pins in the group * @muxvals: array of values to be set to pinmux registers */ struct uniphier_pinctrl_group { const char *name; const unsigned *pins; unsigned num_pins; const int *muxvals; }; /** * struct uniphier_pinctrl_socdata - SoC data for UniPhier pin controller * * @pins: array of pin data * @pins_count: number of pin data * @groups: array of pin group data * @groups_count: number of pin group data * @functions: array of pinmux function names * @functions_count: number of pinmux functions * @mux_bits: bit width of each pinmux register * @reg_stride: stride of pinmux register address * @caps: SoC-specific capability flag */ struct uniphier_pinctrl_socdata { const struct uniphier_pinctrl_pin *pins; int pins_count; const struct uniphier_pinctrl_group *groups; int groups_count; const char * const *functions; int functions_count; unsigned caps; #define UNIPHIER_PINCTRL_CAPS_PUPD_SIMPLE BIT(3) #define UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL BIT(2) #define UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE BIT(1) #define UNIPHIER_PINCTRL_CAPS_MUX_4BIT BIT(0) }; #define UNIPHIER_PINCTRL_PIN(a, b, c, d) \ { \ .number = a, \ .name = b, \ .data = UNIPHIER_PIN_ATTR_PACKED(c, d), \ } #define __UNIPHIER_PINCTRL_GROUP(grp) \ { \ .name = #grp, \ .pins = grp##_pins, \ .num_pins = ARRAY_SIZE(grp##_pins), \ .muxvals = grp##_muxvals + \ BUILD_BUG_ON_ZERO(ARRAY_SIZE(grp##_pins) != \ ARRAY_SIZE(grp##_muxvals)), \ } #define __UNIPHIER_PINMUX_FUNCTION(func) #func #ifdef CONFIG_SPL_BUILD /* * a tricky way to drop unneeded *_pins and *_muxvals arrays from SPL, * suppressing "defined but not used" warnings. */ #define UNIPHIER_PINCTRL_GROUP(grp) \ { .num_pins = ARRAY_SIZE(grp##_pins) + ARRAY_SIZE(grp##_muxvals) } #define UNIPHIER_PINMUX_FUNCTION(func) NULL #else #define UNIPHIER_PINCTRL_GROUP(grp) __UNIPHIER_PINCTRL_GROUP(grp) #define UNIPHIER_PINMUX_FUNCTION(func) __UNIPHIER_PINMUX_FUNCTION(func) #endif #define UNIPHIER_PINCTRL_GROUP_SPL(grp) __UNIPHIER_PINCTRL_GROUP(grp) #define UNIPHIER_PINMUX_FUNCTION_SPL(func) __UNIPHIER_PINMUX_FUNCTION(func) /** * struct uniphier_pinctrl_priv - private data for UniPhier pinctrl driver * * @base: base address of the pinctrl device * @socdata: SoC specific data */ struct uniphier_pinctrl_priv { void __iomem *base; struct uniphier_pinctrl_socdata *socdata; }; extern const struct pinctrl_ops uniphier_pinctrl_ops; int uniphier_pinctrl_probe(struct udevice *dev, struct uniphier_pinctrl_socdata *socdata); #endif /* __PINCTRL_UNIPHIER_H__ */