diff options
Diffstat (limited to 'drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h')
-rw-r--r-- | drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 372 |
1 files changed, 372 insertions, 0 deletions
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h new file mode 100644 index 000000000..23688ca6d --- /dev/null +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h @@ -0,0 +1,372 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018 MediaTek Inc. + * + * Author: Sean Wang <sean.wang@mediatek.com> + * + */ + +#ifndef __PINCTRL_MTK_COMMON_V2_H +#define __PINCTRL_MTK_COMMON_V2_H + +#include <linux/gpio/driver.h> + +#define MTK_INPUT 0 +#define MTK_OUTPUT 1 +#define MTK_DISABLE 0 +#define MTK_ENABLE 1 +#define MTK_PULLDOWN 0 +#define MTK_PULLUP 1 +#define MTK_PULL_PU_PD_TYPE BIT(0) +#define MTK_PULL_PULLSEL_TYPE BIT(1) +#define MTK_PULL_PUPD_R1R0_TYPE BIT(2) +/* MTK_PULL_RSEL_TYPE can select resistance and can be + * turned on/off itself. But it can't be selected pull up/down + */ +#define MTK_PULL_RSEL_TYPE BIT(3) +/* MTK_PULL_PU_PD_RSEL_TYPE is a type which is controlled by + * MTK_PULL_PU_PD_TYPE and MTK_PULL_RSEL_TYPE. + */ +#define MTK_PULL_PU_PD_RSEL_TYPE (MTK_PULL_PU_PD_TYPE \ + | MTK_PULL_RSEL_TYPE) +#define MTK_PULL_TYPE_MASK (MTK_PULL_PU_PD_TYPE |\ + MTK_PULL_PULLSEL_TYPE |\ + MTK_PULL_PUPD_R1R0_TYPE |\ + MTK_PULL_RSEL_TYPE) + +#define EINT_NA U16_MAX +#define NO_EINT_SUPPORT EINT_NA + +#define PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, \ + _s_bit, _x_bits, _sz_reg, _fixed) { \ + .s_pin = _s_pin, \ + .e_pin = _e_pin, \ + .i_base = _i_base, \ + .s_addr = _s_addr, \ + .x_addrs = _x_addrs, \ + .s_bit = _s_bit, \ + .x_bits = _x_bits, \ + .sz_reg = _sz_reg, \ + .fixed = _fixed, \ + } + +#define PIN_FIELD(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits) \ + PIN_FIELD_CALC(_s_pin, _e_pin, 0, _s_addr, _x_addrs, _s_bit, \ + _x_bits, 32, 0) + +#define PINS_FIELD(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits) \ + PIN_FIELD_CALC(_s_pin, _e_pin, 0, _s_addr, _x_addrs, _s_bit, \ + _x_bits, 32, 1) + +#define PIN_RSEL(_s_pin, _e_pin, _rsel_index, _up_resl, _down_rsel) { \ + .s_pin = _s_pin, \ + .e_pin = _e_pin, \ + .rsel_index = _rsel_index, \ + .up_rsel = _up_resl, \ + .down_rsel = _down_rsel, \ + } + +/* List these attributes which could be modified for the pin */ +enum { + PINCTRL_PIN_REG_MODE, + PINCTRL_PIN_REG_DIR, + PINCTRL_PIN_REG_DI, + PINCTRL_PIN_REG_DO, + PINCTRL_PIN_REG_SR, + PINCTRL_PIN_REG_SMT, + PINCTRL_PIN_REG_PD, + PINCTRL_PIN_REG_PU, + PINCTRL_PIN_REG_E4, + PINCTRL_PIN_REG_E8, + PINCTRL_PIN_REG_TDSEL, + PINCTRL_PIN_REG_RDSEL, + PINCTRL_PIN_REG_DRV, + PINCTRL_PIN_REG_PUPD, + PINCTRL_PIN_REG_R0, + PINCTRL_PIN_REG_R1, + PINCTRL_PIN_REG_IES, + PINCTRL_PIN_REG_PULLEN, + PINCTRL_PIN_REG_PULLSEL, + PINCTRL_PIN_REG_DRV_EN, + PINCTRL_PIN_REG_DRV_E0, + PINCTRL_PIN_REG_DRV_E1, + PINCTRL_PIN_REG_DRV_ADV, + PINCTRL_PIN_REG_RSEL, + PINCTRL_PIN_REG_MAX, +}; + +/* Group the pins by the driving current */ +enum { + DRV_FIXED, + DRV_GRP0, + DRV_GRP1, + DRV_GRP2, + DRV_GRP3, + DRV_GRP4, + DRV_GRP_MAX, +}; + +static const char * const mtk_default_register_base_names[] __maybe_unused = { + "base", +}; + +/* struct mtk_pin_field - the structure that holds the information of the field + * used to describe the attribute for the pin + * @base: the index pointing to the entry in base address list + * @offset: the register offset relative to the base address + * @mask: the mask used to filter out the field from the register + * @bitpos: the start bit relative to the register + * @next: the indication that the field would be extended to the + next register + */ +struct mtk_pin_field { + u8 index; + u32 offset; + u32 mask; + u8 bitpos; + u8 next; +}; + +/* struct mtk_pin_field_calc - the structure that holds the range providing + * the guide used to look up the relevant field + * @s_pin: the start pin within the range + * @e_pin: the end pin within the range + * @i_base: the index pointing to the entry in base address list + * @s_addr: the start address for the range + * @x_addrs: the address distance between two consecutive registers + * within the range + * @s_bit: the start bit for the first register within the range + * @x_bits: the bit distance between two consecutive pins within + * the range + * @sz_reg: the size of bits in a register + * @fixed: the consecutive pins share the same bits with the 1st + * pin + */ +struct mtk_pin_field_calc { + u16 s_pin; + u16 e_pin; + u8 i_base; + u32 s_addr; + u8 x_addrs; + u8 s_bit; + u8 x_bits; + u8 sz_reg; + u8 fixed; +}; + +/** + * struct mtk_pin_rsel - the structure that provides bias resistance selection. + * @s_pin: the start pin within the rsel range + * @e_pin: the end pin within the rsel range + * @rsel_index: the rsel bias resistance index + * @up_rsel: the pullup rsel bias resistance value + * @down_rsel: the pulldown rsel bias resistance value + */ +struct mtk_pin_rsel { + u16 s_pin; + u16 e_pin; + u16 rsel_index; + u32 up_rsel; + u32 down_rsel; +}; + +/* struct mtk_pin_reg_calc - the structure that holds all ranges used to + * determine which register the pin would make use of + * for certain pin attribute. + * @range: the start address for the range + * @nranges: the number of items in the range + */ +struct mtk_pin_reg_calc { + const struct mtk_pin_field_calc *range; + unsigned int nranges; +}; + +/** + * struct mtk_func_desc - the structure that providing information + * all the funcs for this pin + * @name: the name of function + * @muxval: the mux to the function + */ +struct mtk_func_desc { + const char *name; + u8 muxval; +}; + +/** + * struct mtk_eint_desc - the structure that providing information + * for eint data per pin + * @eint_m: the eint mux for this pin + * @eitn_n: the eint number for this pin + */ +struct mtk_eint_desc { + u16 eint_m; + u16 eint_n; +}; + +/** + * struct mtk_pin_desc - the structure that providing information + * for each pin of chips + * @number: unique pin number from the global pin number space + * @name: name for this pin + * @eint: the eint data for this pin + * @drv_n: the index with the driving group + * @funcs: all available functions for this pins (only used in + * those drivers compatible to pinctrl-mtk-common.c-like + * ones) + */ +struct mtk_pin_desc { + unsigned int number; + const char *name; + struct mtk_eint_desc eint; + u8 drv_n; + struct mtk_func_desc *funcs; +}; + +struct mtk_pinctrl_group { + const char *name; + unsigned long config; + unsigned pin; +}; + +struct mtk_pinctrl; + +/* struct mtk_pin_soc - the structure that holds SoC-specific data */ +struct mtk_pin_soc { + const struct mtk_pin_reg_calc *reg_cal; + const struct mtk_pin_desc *pins; + unsigned int npins; + const struct group_desc *grps; + unsigned int ngrps; + const struct function_desc *funcs; + unsigned int nfuncs; + const struct mtk_eint_regs *eint_regs; + const struct mtk_eint_hw *eint_hw; + + /* Specific parameters per SoC */ + u8 gpio_m; + bool ies_present; + const char * const *base_names; + unsigned int nbase_names; + const unsigned int *pull_type; + const struct mtk_pin_rsel *pin_rsel; + unsigned int npin_rsel; + + /* Specific pinconfig operations */ + int (*bias_disable_set)(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc); + int (*bias_disable_get)(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, int *res); + int (*bias_set)(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, bool pullup); + int (*bias_get)(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, bool pullup, int *res); + + int (*bias_set_combo)(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 pullup, u32 arg); + int (*bias_get_combo)(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 *pullup, u32 *arg); + + int (*drive_set)(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 arg); + int (*drive_get)(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, int *val); + + int (*adv_pull_set)(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, bool pullup, + u32 arg); + int (*adv_pull_get)(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, bool pullup, + u32 *val); + int (*adv_drive_set)(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 arg); + int (*adv_drive_get)(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 *val); + + /* Specific driver data */ + void *driver_data; +}; + +struct mtk_pinctrl { + struct pinctrl_dev *pctrl; + void __iomem **base; + u8 nbase; + struct device *dev; + struct gpio_chip chip; + const struct mtk_pin_soc *soc; + struct mtk_eint *eint; + struct mtk_pinctrl_group *groups; + const char **grp_names; + /* lock pin's register resource to avoid multiple threads issue*/ + spinlock_t lock; + /* identify rsel setting by si unit or rsel define in dts node */ + bool rsel_si_unit; +}; + +void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set); + +int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, + int field, int value); +int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, + int field, int *value); + +int mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev); + +int mtk_pinconf_bias_disable_set(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc); +int mtk_pinconf_bias_disable_get(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, int *res); +int mtk_pinconf_bias_set(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, bool pullup); +int mtk_pinconf_bias_get(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, bool pullup, + int *res); + +int mtk_pinconf_bias_disable_set_rev1(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc); +int mtk_pinconf_bias_disable_get_rev1(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + int *res); +int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, bool pullup); +int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, bool pullup, + int *res); +int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 pullup, u32 enable); +int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 *pullup, u32 *enable); + +int mtk_pinconf_drive_set(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 arg); +int mtk_pinconf_drive_get(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, int *val); + +int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 arg); +int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, int *val); + +int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 arg); +int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, int *val); + +int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, bool pullup, + u32 arg); +int mtk_pinconf_adv_pull_get(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, bool pullup, + u32 *val); +int mtk_pinconf_adv_drive_set(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 arg); +int mtk_pinconf_adv_drive_get(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 *val); +int mtk_pinconf_adv_drive_set_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 arg); +int mtk_pinconf_adv_drive_get_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 *val); + +bool mtk_is_virt_gpio(struct mtk_pinctrl *hw, unsigned int gpio_n); +#endif /* __PINCTRL_MTK_COMMON_V2_H */ |