1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Marvell MVEBU pinctrl driver 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Authors: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> 6*4882a593Smuzhiyun * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> 7*4882a593Smuzhiyun */ 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun #ifndef __PINCTRL_MVEBU_H__ 10*4882a593Smuzhiyun #define __PINCTRL_MVEBU_H__ 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun /** 13*4882a593Smuzhiyun * struct mvebu_mpp_ctrl_data - private data for the mpp ctrl operations 14*4882a593Smuzhiyun * @base: base address of pinctrl hardware 15*4882a593Smuzhiyun * @regmap.map: regmap structure 16*4882a593Smuzhiyun * @regmap.offset: regmap offset 17*4882a593Smuzhiyun */ 18*4882a593Smuzhiyun struct mvebu_mpp_ctrl_data { 19*4882a593Smuzhiyun union { 20*4882a593Smuzhiyun void __iomem *base; 21*4882a593Smuzhiyun struct { 22*4882a593Smuzhiyun struct regmap *map; 23*4882a593Smuzhiyun u32 offset; 24*4882a593Smuzhiyun } regmap; 25*4882a593Smuzhiyun }; 26*4882a593Smuzhiyun }; 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun /** 29*4882a593Smuzhiyun * struct mvebu_mpp_ctrl - describe a mpp control 30*4882a593Smuzhiyun * @name: name of the control group 31*4882a593Smuzhiyun * @pid: first pin id handled by this control 32*4882a593Smuzhiyun * @npins: number of pins controlled by this control 33*4882a593Smuzhiyun * @mpp_get: (optional) special function to get mpp setting 34*4882a593Smuzhiyun * @mpp_set: (optional) special function to set mpp setting 35*4882a593Smuzhiyun * @mpp_gpio_req: (optional) special function to request gpio 36*4882a593Smuzhiyun * @mpp_gpio_dir: (optional) special function to set gpio direction 37*4882a593Smuzhiyun * 38*4882a593Smuzhiyun * A mpp_ctrl describes a muxable unit, e.g. pin, group of pins, or 39*4882a593Smuzhiyun * internal function, inside the SoC. Each muxable unit can be switched 40*4882a593Smuzhiyun * between two or more different settings, e.g. assign mpp pin 13 to 41*4882a593Smuzhiyun * uart1 or sata. 42*4882a593Smuzhiyun * 43*4882a593Smuzhiyun * The mpp_get/_set functions are mandatory and are used to get/set a 44*4882a593Smuzhiyun * specific mode. The optional mpp_gpio_req/_dir functions can be used 45*4882a593Smuzhiyun * to allow pin settings with varying gpio pins. 46*4882a593Smuzhiyun */ 47*4882a593Smuzhiyun struct mvebu_mpp_ctrl { 48*4882a593Smuzhiyun const char *name; 49*4882a593Smuzhiyun u8 pid; 50*4882a593Smuzhiyun u8 npins; 51*4882a593Smuzhiyun unsigned *pins; 52*4882a593Smuzhiyun int (*mpp_get)(struct mvebu_mpp_ctrl_data *data, unsigned pid, 53*4882a593Smuzhiyun unsigned long *config); 54*4882a593Smuzhiyun int (*mpp_set)(struct mvebu_mpp_ctrl_data *data, unsigned pid, 55*4882a593Smuzhiyun unsigned long config); 56*4882a593Smuzhiyun int (*mpp_gpio_req)(struct mvebu_mpp_ctrl_data *data, unsigned pid); 57*4882a593Smuzhiyun int (*mpp_gpio_dir)(struct mvebu_mpp_ctrl_data *data, unsigned pid, 58*4882a593Smuzhiyun bool input); 59*4882a593Smuzhiyun }; 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun /** 62*4882a593Smuzhiyun * struct mvebu_mpp_ctrl_setting - describe a mpp ctrl setting 63*4882a593Smuzhiyun * @val: ctrl setting value 64*4882a593Smuzhiyun * @name: ctrl setting name, e.g. uart2, spi0 - unique per mpp_mode 65*4882a593Smuzhiyun * @subname: (optional) additional ctrl setting name, e.g. rts, cts 66*4882a593Smuzhiyun * @variant: (optional) variant identifier mask 67*4882a593Smuzhiyun * @flags: (private) flags to store gpi/gpo/gpio capabilities 68*4882a593Smuzhiyun * 69*4882a593Smuzhiyun * A ctrl_setting describes a specific internal mux function that a mpp pin 70*4882a593Smuzhiyun * can be switched to. The value (val) will be written in the corresponding 71*4882a593Smuzhiyun * register for common mpp pin configuration registers on MVEBU. SoC specific 72*4882a593Smuzhiyun * mpp_get/_set function may use val to distinguish between different settings. 73*4882a593Smuzhiyun * 74*4882a593Smuzhiyun * The name will be used to switch to this setting in DT description, e.g. 75*4882a593Smuzhiyun * marvell,function = "uart2". subname is only for debugging purposes. 76*4882a593Smuzhiyun * 77*4882a593Smuzhiyun * If name is one of "gpi", "gpo", "gpio" gpio capabilities are 78*4882a593Smuzhiyun * parsed during initialization and stored in flags. 79*4882a593Smuzhiyun * 80*4882a593Smuzhiyun * The variant can be used to combine different revisions of one SoC to a 81*4882a593Smuzhiyun * common pinctrl driver. It is matched (AND) with variant of soc_info to 82*4882a593Smuzhiyun * determine if a setting is available on the current SoC revision. 83*4882a593Smuzhiyun */ 84*4882a593Smuzhiyun struct mvebu_mpp_ctrl_setting { 85*4882a593Smuzhiyun u8 val; 86*4882a593Smuzhiyun const char *name; 87*4882a593Smuzhiyun const char *subname; 88*4882a593Smuzhiyun u8 variant; 89*4882a593Smuzhiyun u8 flags; 90*4882a593Smuzhiyun #define MVEBU_SETTING_GPO (1 << 0) 91*4882a593Smuzhiyun #define MVEBU_SETTING_GPI (1 << 1) 92*4882a593Smuzhiyun }; 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun /** 95*4882a593Smuzhiyun * struct mvebu_mpp_mode - link ctrl and settings 96*4882a593Smuzhiyun * @pid: first pin id handled by this mode 97*4882a593Smuzhiyun * @settings: list of settings available for this mode 98*4882a593Smuzhiyun * 99*4882a593Smuzhiyun * A mode connects all available settings with the corresponding mpp_ctrl 100*4882a593Smuzhiyun * given by pid. 101*4882a593Smuzhiyun */ 102*4882a593Smuzhiyun struct mvebu_mpp_mode { 103*4882a593Smuzhiyun u8 pid; 104*4882a593Smuzhiyun struct mvebu_mpp_ctrl_setting *settings; 105*4882a593Smuzhiyun }; 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun /** 108*4882a593Smuzhiyun * struct mvebu_pinctrl_soc_info - SoC specific info passed to pinctrl-mvebu 109*4882a593Smuzhiyun * @variant: variant mask of soc_info 110*4882a593Smuzhiyun * @controls: list of available mvebu_mpp_ctrls 111*4882a593Smuzhiyun * @control_data: optional array, one entry for each control 112*4882a593Smuzhiyun * @ncontrols: number of available mvebu_mpp_ctrls 113*4882a593Smuzhiyun * @modes: list of available mvebu_mpp_modes 114*4882a593Smuzhiyun * @nmodes: number of available mvebu_mpp_modes 115*4882a593Smuzhiyun * @gpioranges: list of pinctrl_gpio_ranges 116*4882a593Smuzhiyun * @ngpioranges: number of available pinctrl_gpio_ranges 117*4882a593Smuzhiyun * 118*4882a593Smuzhiyun * This struct describes all pinctrl related information for a specific SoC. 119*4882a593Smuzhiyun * If variant is unequal 0 it will be matched (AND) with variant of each 120*4882a593Smuzhiyun * setting and allows to distinguish between different revisions of one SoC. 121*4882a593Smuzhiyun */ 122*4882a593Smuzhiyun struct mvebu_pinctrl_soc_info { 123*4882a593Smuzhiyun u8 variant; 124*4882a593Smuzhiyun const struct mvebu_mpp_ctrl *controls; 125*4882a593Smuzhiyun struct mvebu_mpp_ctrl_data *control_data; 126*4882a593Smuzhiyun int ncontrols; 127*4882a593Smuzhiyun struct mvebu_mpp_mode *modes; 128*4882a593Smuzhiyun int nmodes; 129*4882a593Smuzhiyun struct pinctrl_gpio_range *gpioranges; 130*4882a593Smuzhiyun int ngpioranges; 131*4882a593Smuzhiyun }; 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun #define MPP_FUNC_CTRL(_idl, _idh, _name, _func) \ 134*4882a593Smuzhiyun { \ 135*4882a593Smuzhiyun .name = _name, \ 136*4882a593Smuzhiyun .pid = _idl, \ 137*4882a593Smuzhiyun .npins = _idh - _idl + 1, \ 138*4882a593Smuzhiyun .pins = (unsigned[_idh - _idl + 1]) { }, \ 139*4882a593Smuzhiyun .mpp_get = _func ## _get, \ 140*4882a593Smuzhiyun .mpp_set = _func ## _set, \ 141*4882a593Smuzhiyun .mpp_gpio_req = NULL, \ 142*4882a593Smuzhiyun .mpp_gpio_dir = NULL, \ 143*4882a593Smuzhiyun } 144*4882a593Smuzhiyun 145*4882a593Smuzhiyun #define MPP_FUNC_GPIO_CTRL(_idl, _idh, _name, _func) \ 146*4882a593Smuzhiyun { \ 147*4882a593Smuzhiyun .name = _name, \ 148*4882a593Smuzhiyun .pid = _idl, \ 149*4882a593Smuzhiyun .npins = _idh - _idl + 1, \ 150*4882a593Smuzhiyun .pins = (unsigned[_idh - _idl + 1]) { }, \ 151*4882a593Smuzhiyun .mpp_get = _func ## _get, \ 152*4882a593Smuzhiyun .mpp_set = _func ## _set, \ 153*4882a593Smuzhiyun .mpp_gpio_req = _func ## _gpio_req, \ 154*4882a593Smuzhiyun .mpp_gpio_dir = _func ## _gpio_dir, \ 155*4882a593Smuzhiyun } 156*4882a593Smuzhiyun 157*4882a593Smuzhiyun #define _MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \ 158*4882a593Smuzhiyun { \ 159*4882a593Smuzhiyun .val = _val, \ 160*4882a593Smuzhiyun .name = _name, \ 161*4882a593Smuzhiyun .subname = _subname, \ 162*4882a593Smuzhiyun .variant = _mask, \ 163*4882a593Smuzhiyun .flags = 0, \ 164*4882a593Smuzhiyun } 165*4882a593Smuzhiyun 166*4882a593Smuzhiyun #if defined(CONFIG_DEBUG_FS) 167*4882a593Smuzhiyun #define MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \ 168*4882a593Smuzhiyun _MPP_VAR_FUNCTION(_val, _name, _subname, _mask) 169*4882a593Smuzhiyun #else 170*4882a593Smuzhiyun #define MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \ 171*4882a593Smuzhiyun _MPP_VAR_FUNCTION(_val, _name, NULL, _mask) 172*4882a593Smuzhiyun #endif 173*4882a593Smuzhiyun 174*4882a593Smuzhiyun #define MPP_FUNCTION(_val, _name, _subname) \ 175*4882a593Smuzhiyun MPP_VAR_FUNCTION(_val, _name, _subname, (u8)-1) 176*4882a593Smuzhiyun 177*4882a593Smuzhiyun #define MPP_MODE(_id, ...) \ 178*4882a593Smuzhiyun { \ 179*4882a593Smuzhiyun .pid = _id, \ 180*4882a593Smuzhiyun .settings = (struct mvebu_mpp_ctrl_setting[]){ \ 181*4882a593Smuzhiyun __VA_ARGS__, { } }, \ 182*4882a593Smuzhiyun } 183*4882a593Smuzhiyun 184*4882a593Smuzhiyun #define MPP_GPIO_RANGE(_id, _pinbase, _gpiobase, _npins) \ 185*4882a593Smuzhiyun { \ 186*4882a593Smuzhiyun .name = "mvebu-gpio", \ 187*4882a593Smuzhiyun .id = _id, \ 188*4882a593Smuzhiyun .pin_base = _pinbase, \ 189*4882a593Smuzhiyun .base = _gpiobase, \ 190*4882a593Smuzhiyun .npins = _npins, \ 191*4882a593Smuzhiyun } 192*4882a593Smuzhiyun 193*4882a593Smuzhiyun #define MVEBU_MPPS_PER_REG 8 194*4882a593Smuzhiyun #define MVEBU_MPP_BITS 4 195*4882a593Smuzhiyun #define MVEBU_MPP_MASK 0xf 196*4882a593Smuzhiyun 197*4882a593Smuzhiyun int mvebu_mmio_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid, 198*4882a593Smuzhiyun unsigned long *config); 199*4882a593Smuzhiyun int mvebu_mmio_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid, 200*4882a593Smuzhiyun unsigned long config); 201*4882a593Smuzhiyun int mvebu_regmap_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid, 202*4882a593Smuzhiyun unsigned long *config); 203*4882a593Smuzhiyun int mvebu_regmap_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid, 204*4882a593Smuzhiyun unsigned long config); 205*4882a593Smuzhiyun 206*4882a593Smuzhiyun int mvebu_pinctrl_probe(struct platform_device *pdev); 207*4882a593Smuzhiyun int mvebu_pinctrl_simple_mmio_probe(struct platform_device *pdev); 208*4882a593Smuzhiyun int mvebu_pinctrl_simple_regmap_probe(struct platform_device *pdev, 209*4882a593Smuzhiyun struct device *syscon_dev, u32 offset); 210*4882a593Smuzhiyun 211*4882a593Smuzhiyun #endif 212