mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
211 lines
6.7 KiB
211 lines
6.7 KiB
/* SPDX-License-Identifier: GPL-2.0-or-later */ |
|
/* |
|
* Marvell MVEBU pinctrl driver |
|
* |
|
* Authors: Sebastian Hesselbarth <[email protected]> |
|
* Thomas Petazzoni <[email protected]> |
|
*/ |
|
|
|
#ifndef __PINCTRL_MVEBU_H__ |
|
#define __PINCTRL_MVEBU_H__ |
|
|
|
/** |
|
* struct mvebu_mpp_ctrl_data - private data for the mpp ctrl operations |
|
* @base: base address of pinctrl hardware |
|
* @regmap.map: regmap structure |
|
* @regmap.offset: regmap offset |
|
*/ |
|
struct mvebu_mpp_ctrl_data { |
|
union { |
|
void __iomem *base; |
|
struct { |
|
struct regmap *map; |
|
u32 offset; |
|
} regmap; |
|
}; |
|
}; |
|
|
|
/** |
|
* struct mvebu_mpp_ctrl - describe a mpp control |
|
* @name: name of the control group |
|
* @pid: first pin id handled by this control |
|
* @npins: number of pins controlled by this control |
|
* @mpp_get: (optional) special function to get mpp setting |
|
* @mpp_set: (optional) special function to set mpp setting |
|
* @mpp_gpio_req: (optional) special function to request gpio |
|
* @mpp_gpio_dir: (optional) special function to set gpio direction |
|
* |
|
* A mpp_ctrl describes a muxable unit, e.g. pin, group of pins, or |
|
* internal function, inside the SoC. Each muxable unit can be switched |
|
* between two or more different settings, e.g. assign mpp pin 13 to |
|
* uart1 or sata. |
|
* |
|
* The mpp_get/_set functions are mandatory and are used to get/set a |
|
* specific mode. The optional mpp_gpio_req/_dir functions can be used |
|
* to allow pin settings with varying gpio pins. |
|
*/ |
|
struct mvebu_mpp_ctrl { |
|
const char *name; |
|
u8 pid; |
|
u8 npins; |
|
unsigned *pins; |
|
int (*mpp_get)(struct mvebu_mpp_ctrl_data *data, unsigned pid, |
|
unsigned long *config); |
|
int (*mpp_set)(struct mvebu_mpp_ctrl_data *data, unsigned pid, |
|
unsigned long config); |
|
int (*mpp_gpio_req)(struct mvebu_mpp_ctrl_data *data, unsigned pid); |
|
int (*mpp_gpio_dir)(struct mvebu_mpp_ctrl_data *data, unsigned pid, |
|
bool input); |
|
}; |
|
|
|
/** |
|
* struct mvebu_mpp_ctrl_setting - describe a mpp ctrl setting |
|
* @val: ctrl setting value |
|
* @name: ctrl setting name, e.g. uart2, spi0 - unique per mpp_mode |
|
* @subname: (optional) additional ctrl setting name, e.g. rts, cts |
|
* @variant: (optional) variant identifier mask |
|
* @flags: (private) flags to store gpi/gpo/gpio capabilities |
|
* |
|
* A ctrl_setting describes a specific internal mux function that a mpp pin |
|
* can be switched to. The value (val) will be written in the corresponding |
|
* register for common mpp pin configuration registers on MVEBU. SoC specific |
|
* mpp_get/_set function may use val to distinguish between different settings. |
|
* |
|
* The name will be used to switch to this setting in DT description, e.g. |
|
* marvell,function = "uart2". subname is only for debugging purposes. |
|
* |
|
* If name is one of "gpi", "gpo", "gpio" gpio capabilities are |
|
* parsed during initialization and stored in flags. |
|
* |
|
* The variant can be used to combine different revisions of one SoC to a |
|
* common pinctrl driver. It is matched (AND) with variant of soc_info to |
|
* determine if a setting is available on the current SoC revision. |
|
*/ |
|
struct mvebu_mpp_ctrl_setting { |
|
u8 val; |
|
const char *name; |
|
const char *subname; |
|
u8 variant; |
|
u8 flags; |
|
#define MVEBU_SETTING_GPO (1 << 0) |
|
#define MVEBU_SETTING_GPI (1 << 1) |
|
}; |
|
|
|
/** |
|
* struct mvebu_mpp_mode - link ctrl and settings |
|
* @pid: first pin id handled by this mode |
|
* @settings: list of settings available for this mode |
|
* |
|
* A mode connects all available settings with the corresponding mpp_ctrl |
|
* given by pid. |
|
*/ |
|
struct mvebu_mpp_mode { |
|
u8 pid; |
|
struct mvebu_mpp_ctrl_setting *settings; |
|
}; |
|
|
|
/** |
|
* struct mvebu_pinctrl_soc_info - SoC specific info passed to pinctrl-mvebu |
|
* @variant: variant mask of soc_info |
|
* @controls: list of available mvebu_mpp_ctrls |
|
* @control_data: optional array, one entry for each control |
|
* @ncontrols: number of available mvebu_mpp_ctrls |
|
* @modes: list of available mvebu_mpp_modes |
|
* @nmodes: number of available mvebu_mpp_modes |
|
* @gpioranges: list of pinctrl_gpio_ranges |
|
* @ngpioranges: number of available pinctrl_gpio_ranges |
|
* |
|
* This struct describes all pinctrl related information for a specific SoC. |
|
* If variant is unequal 0 it will be matched (AND) with variant of each |
|
* setting and allows to distinguish between different revisions of one SoC. |
|
*/ |
|
struct mvebu_pinctrl_soc_info { |
|
u8 variant; |
|
const struct mvebu_mpp_ctrl *controls; |
|
struct mvebu_mpp_ctrl_data *control_data; |
|
int ncontrols; |
|
struct mvebu_mpp_mode *modes; |
|
int nmodes; |
|
struct pinctrl_gpio_range *gpioranges; |
|
int ngpioranges; |
|
}; |
|
|
|
#define MPP_FUNC_CTRL(_idl, _idh, _name, _func) \ |
|
{ \ |
|
.name = _name, \ |
|
.pid = _idl, \ |
|
.npins = _idh - _idl + 1, \ |
|
.pins = (unsigned[_idh - _idl + 1]) { }, \ |
|
.mpp_get = _func ## _get, \ |
|
.mpp_set = _func ## _set, \ |
|
.mpp_gpio_req = NULL, \ |
|
.mpp_gpio_dir = NULL, \ |
|
} |
|
|
|
#define MPP_FUNC_GPIO_CTRL(_idl, _idh, _name, _func) \ |
|
{ \ |
|
.name = _name, \ |
|
.pid = _idl, \ |
|
.npins = _idh - _idl + 1, \ |
|
.pins = (unsigned[_idh - _idl + 1]) { }, \ |
|
.mpp_get = _func ## _get, \ |
|
.mpp_set = _func ## _set, \ |
|
.mpp_gpio_req = _func ## _gpio_req, \ |
|
.mpp_gpio_dir = _func ## _gpio_dir, \ |
|
} |
|
|
|
#define _MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \ |
|
{ \ |
|
.val = _val, \ |
|
.name = _name, \ |
|
.subname = _subname, \ |
|
.variant = _mask, \ |
|
.flags = 0, \ |
|
} |
|
|
|
#if defined(CONFIG_DEBUG_FS) |
|
#define MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \ |
|
_MPP_VAR_FUNCTION(_val, _name, _subname, _mask) |
|
#else |
|
#define MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \ |
|
_MPP_VAR_FUNCTION(_val, _name, NULL, _mask) |
|
#endif |
|
|
|
#define MPP_FUNCTION(_val, _name, _subname) \ |
|
MPP_VAR_FUNCTION(_val, _name, _subname, (u8)-1) |
|
|
|
#define MPP_MODE(_id, ...) \ |
|
{ \ |
|
.pid = _id, \ |
|
.settings = (struct mvebu_mpp_ctrl_setting[]){ \ |
|
__VA_ARGS__, { } }, \ |
|
} |
|
|
|
#define MPP_GPIO_RANGE(_id, _pinbase, _gpiobase, _npins) \ |
|
{ \ |
|
.name = "mvebu-gpio", \ |
|
.id = _id, \ |
|
.pin_base = _pinbase, \ |
|
.base = _gpiobase, \ |
|
.npins = _npins, \ |
|
} |
|
|
|
#define MVEBU_MPPS_PER_REG 8 |
|
#define MVEBU_MPP_BITS 4 |
|
#define MVEBU_MPP_MASK 0xf |
|
|
|
int mvebu_mmio_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid, |
|
unsigned long *config); |
|
int mvebu_mmio_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid, |
|
unsigned long config); |
|
int mvebu_regmap_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid, |
|
unsigned long *config); |
|
int mvebu_regmap_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid, |
|
unsigned long config); |
|
|
|
int mvebu_pinctrl_probe(struct platform_device *pdev); |
|
int mvebu_pinctrl_simple_mmio_probe(struct platform_device *pdev); |
|
int mvebu_pinctrl_simple_regmap_probe(struct platform_device *pdev, |
|
struct device *syscon_dev, u32 offset); |
|
|
|
#endif
|
|
|