/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2020-2024 Rockchip Electronics Co., Ltd.
 *
 * Copyright (c) 2013 MundoReader S.L.
 * Author: Heiko Stuebner <heiko@sntech.de>
 *
 * With some ideas taken from pinctrl-samsung:
 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
 *		http://www.samsung.com
 * Copyright (c) 2012 Linaro Ltd
 *		https://www.linaro.org
 *
 * and pinctrl-at91:
 * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
 */

#ifndef _PINCTRL_ROCKCHIP_H
#define _PINCTRL_ROCKCHIP_H

#define RK_GPIO0_A0	0
#define RK_GPIO0_A1	1
#define RK_GPIO0_A2	2
#define RK_GPIO0_A3	3
#define RK_GPIO0_A4	4
#define RK_GPIO0_A5	5
#define RK_GPIO0_A6	6
#define RK_GPIO0_A7	7
#define RK_GPIO0_B0	8
#define RK_GPIO0_B1	9
#define RK_GPIO0_B2	10
#define RK_GPIO0_B3	11
#define RK_GPIO0_B4	12
#define RK_GPIO0_B5	13
#define RK_GPIO0_B6	14
#define RK_GPIO0_B7	15
#define RK_GPIO0_C0	16
#define RK_GPIO0_C1	17
#define RK_GPIO0_C2	18
#define RK_GPIO0_C3	19
#define RK_GPIO0_C4	20
#define RK_GPIO0_C5	21
#define RK_GPIO0_C6	22
#define RK_GPIO0_C7	23
#define RK_GPIO0_D0	24
#define RK_GPIO0_D1	25
#define RK_GPIO0_D2	26
#define RK_GPIO0_D3	27
#define RK_GPIO0_D4	28
#define RK_GPIO0_D5	29
#define RK_GPIO0_D6	30
#define RK_GPIO0_D7	31

#define RK_GPIO1_A0	32
#define RK_GPIO1_A1	33
#define RK_GPIO1_A2	34
#define RK_GPIO1_A3	35
#define RK_GPIO1_A4	36
#define RK_GPIO1_A5	37
#define RK_GPIO1_A6	38
#define RK_GPIO1_A7	39
#define RK_GPIO1_B0	40
#define RK_GPIO1_B1	41
#define RK_GPIO1_B2	42
#define RK_GPIO1_B3	43
#define RK_GPIO1_B4	44
#define RK_GPIO1_B5	45
#define RK_GPIO1_B6	46
#define RK_GPIO1_B7	47
#define RK_GPIO1_C0	48
#define RK_GPIO1_C1	49
#define RK_GPIO1_C2	50
#define RK_GPIO1_C3	51
#define RK_GPIO1_C4	52
#define RK_GPIO1_C5	53
#define RK_GPIO1_C6	54
#define RK_GPIO1_C7	55
#define RK_GPIO1_D0	56
#define RK_GPIO1_D1	57
#define RK_GPIO1_D2	58
#define RK_GPIO1_D3	59
#define RK_GPIO1_D4	60
#define RK_GPIO1_D5	61
#define RK_GPIO1_D6	62
#define RK_GPIO1_D7	63

#define RK_GPIO2_A0	64
#define RK_GPIO2_A1	65
#define RK_GPIO2_A2	66
#define RK_GPIO2_A3	67
#define RK_GPIO2_A4	68
#define RK_GPIO2_A5	69
#define RK_GPIO2_A6	70
#define RK_GPIO2_A7	71
#define RK_GPIO2_B0	72
#define RK_GPIO2_B1	73
#define RK_GPIO2_B2	74
#define RK_GPIO2_B3	75
#define RK_GPIO2_B4	76
#define RK_GPIO2_B5	77
#define RK_GPIO2_B6	78
#define RK_GPIO2_B7	79
#define RK_GPIO2_C0	80
#define RK_GPIO2_C1	81
#define RK_GPIO2_C2	82
#define RK_GPIO2_C3	83
#define RK_GPIO2_C4	84
#define RK_GPIO2_C5	85
#define RK_GPIO2_C6	86
#define RK_GPIO2_C7	87
#define RK_GPIO2_D0	88
#define RK_GPIO2_D1	89
#define RK_GPIO2_D2	90
#define RK_GPIO2_D3	91
#define RK_GPIO2_D4	92
#define RK_GPIO2_D5	93
#define RK_GPIO2_D6	94
#define RK_GPIO2_D7	95

#define RK_GPIO3_A0	96
#define RK_GPIO3_A1	97
#define RK_GPIO3_A2	98
#define RK_GPIO3_A3	99
#define RK_GPIO3_A4	100
#define RK_GPIO3_A5	101
#define RK_GPIO3_A6	102
#define RK_GPIO3_A7	103
#define RK_GPIO3_B0	104
#define RK_GPIO3_B1	105
#define RK_GPIO3_B2	106
#define RK_GPIO3_B3	107
#define RK_GPIO3_B4	108
#define RK_GPIO3_B5	109
#define RK_GPIO3_B6	110
#define RK_GPIO3_B7	111
#define RK_GPIO3_C0	112
#define RK_GPIO3_C1	113
#define RK_GPIO3_C2	114
#define RK_GPIO3_C3	115
#define RK_GPIO3_C4	116
#define RK_GPIO3_C5	117
#define RK_GPIO3_C6	118
#define RK_GPIO3_C7	119
#define RK_GPIO3_D0	120
#define RK_GPIO3_D1	121
#define RK_GPIO3_D2	122
#define RK_GPIO3_D3	123
#define RK_GPIO3_D4	124
#define RK_GPIO3_D5	125
#define RK_GPIO3_D6	126
#define RK_GPIO3_D7	127

#define RK_GPIO4_A0	128
#define RK_GPIO4_A1	129
#define RK_GPIO4_A2	130
#define RK_GPIO4_A3	131
#define RK_GPIO4_A4	132
#define RK_GPIO4_A5	133
#define RK_GPIO4_A6	134
#define RK_GPIO4_A7	135
#define RK_GPIO4_B0	136
#define RK_GPIO4_B1	137
#define RK_GPIO4_B2	138
#define RK_GPIO4_B3	139
#define RK_GPIO4_B4	140
#define RK_GPIO4_B5	141
#define RK_GPIO4_B6	142
#define RK_GPIO4_B7	143
#define RK_GPIO4_C0	144
#define RK_GPIO4_C1	145
#define RK_GPIO4_C2	146
#define RK_GPIO4_C3	147
#define RK_GPIO4_C4	148
#define RK_GPIO4_C5	149
#define RK_GPIO4_C6	150
#define RK_GPIO4_C7	151
#define RK_GPIO4_D0	152
#define RK_GPIO4_D1	153
#define RK_GPIO4_D2	154
#define RK_GPIO4_D3	155
#define RK_GPIO4_D4	156
#define RK_GPIO4_D5	157
#define RK_GPIO4_D6	158
#define RK_GPIO4_D7	159

enum rockchip_pinctrl_type {
	PX30,
	RV1108,
	RV1126,
	RK2928,
	RK3066B,
	RK3128,
	RK3188,
	RK3288,
	RK3308,
	RK3328,
	RK3368,
	RK3399,
	RK3506,
	RK3528,
	RK3562,
	RK3568,
	RK3576,
	RK3588,
};

/**
 * struct rockchip_gpio_regs
 * @port_dr: data register
 * @port_ddr: data direction register
 * @int_en: interrupt enable
 * @int_mask: interrupt mask
 * @int_type: interrupt trigger type, such as high, low, edge trriger type.
 * @int_polarity: interrupt polarity enable register
 * @int_bothedge: interrupt bothedge enable register
 * @int_status: interrupt status register
 * @int_rawstatus: int_status = int_rawstatus & int_mask
 * @debounce: enable debounce for interrupt signal
 * @dbclk_div_en: enable divider for debounce clock
 * @dbclk_div_con: setting for divider of debounce clock
 * @port_eoi: end of interrupt of the port
 * @ext_port: port data from external
 * @version_id: controller version register
 */
struct rockchip_gpio_regs {
	u32 port_dr;
	u32 port_ddr;
	u32 int_en;
	u32 int_mask;
	u32 int_type;
	u32 int_polarity;
	u32 int_bothedge;
	u32 int_status;
	u32 int_rawstatus;
	u32 debounce;
	u32 dbclk_div_en;
	u32 dbclk_div_con;
	u32 port_eoi;
	u32 ext_port;
	u32 version_id;
};

/**
 * struct rockchip_iomux
 * @type: iomux variant using IOMUX_* constants
 * @offset: if initialized to -1 it will be autocalculated, by specifying
 *	    an initial offset value the relevant source offset can be reset
 *	    to a new value for autocalculating the following iomux registers.
 */
struct rockchip_iomux {
	int type;
	int offset;
};

/*
 * enum type index corresponding to rockchip_perpin_drv_list arrays index.
 */
enum rockchip_pin_drv_type {
	DRV_TYPE_IO_DEFAULT = 0,
	DRV_TYPE_IO_1V8_OR_3V0,
	DRV_TYPE_IO_1V8_ONLY,
	DRV_TYPE_IO_1V8_3V0_AUTO,
	DRV_TYPE_IO_3V3_ONLY,
	DRV_TYPE_IO_LEVEL_2_BIT,
	DRV_TYPE_IO_LEVEL_8_BIT,
	DRV_TYPE_MAX
};

/*
 * enum type index corresponding to rockchip_pull_list arrays index.
 */
enum rockchip_pin_pull_type {
	PULL_TYPE_IO_DEFAULT = 0,
	PULL_TYPE_IO_1V8_ONLY,
	PULL_TYPE_MAX
};

/**
 * struct rockchip_drv
 * @drv_type: drive strength variant using rockchip_perpin_drv_type
 * @offset: if initialized to -1 it will be autocalculated, by specifying
 *	    an initial offset value the relevant source offset can be reset
 *	    to a new value for autocalculating the following drive strength
 *	    registers. if used chips own cal_drv func instead to calculate
 *	    registers offset, the variant could be ignored.
 */
struct rockchip_drv {
	enum rockchip_pin_drv_type	drv_type;
	int				offset;
};

/**
 * struct rockchip_pin_bank
 * @dev: the pinctrl device bind to the bank
 * @reg_base: register base of the gpio bank
 * @regmap_pull: optional separate register for additional pull settings
 * @clk: clock of the gpio bank
 * @db_clk: clock of the gpio debounce
 * @irq: interrupt of the gpio bank
 * @saved_masks: Saved content of GPIO_INTEN at suspend time.
 * @pin_base: first pin number
 * @nr_pins: number of pins in this bank
 * @name: name of the bank
 * @bank_num: number of the bank, to account for holes
 * @iomux: array describing the 4 iomux sources of the bank
 * @drv: array describing the 4 drive strength sources of the bank
 * @pull_type: array describing the 4 pull type sources of the bank
 * @valid: is all necessary information present
 * @of_node: dt node of this bank
 * @drvdata: common pinctrl basedata
 * @domain: irqdomain of the gpio bank
 * @gpio_chip: gpiolib chip
 * @grange: gpio range
 * @slock: spinlock for the gpio bank
 * @toggle_edge_mode: bit mask to toggle (falling/rising) edge mode
 * @recalced_mask: bit mask to indicate a need to recalulate the mask
 * @route_mask: bits describing the routing pins of per bank
 * @deferred_output: gpio output settings to be done after gpio bank probed
 * @deferred_lock: mutex for the deferred_output shared btw gpio and pinctrl
 */
struct rockchip_pin_bank {
	struct device			*dev;
	void __iomem			*reg_base;
	struct regmap			*regmap_pull;
	struct clk			*clk;
	struct clk			*db_clk;
	int				irq;
	u32				saved_masks;
	u32				pin_base;
	u8				nr_pins;
	char				*name;
	u8				bank_num;
	struct rockchip_iomux		iomux[4];
	struct rockchip_drv		drv[4];
	enum rockchip_pin_pull_type	pull_type[4];
	bool				valid;
	struct device_node		*of_node;
	struct rockchip_pinctrl		*drvdata;
	struct irq_domain		*domain;
	struct gpio_chip		gpio_chip;
	struct pinctrl_gpio_range	grange;
	raw_spinlock_t			slock;
	const struct rockchip_gpio_regs	*gpio_regs;
	u32				gpio_type;
	u32				toggle_edge_mode;
	u32				recalced_mask;
	u32				route_mask;
	struct list_head		deferred_pins;
	struct mutex			deferred_lock;
};

/**
 * struct rockchip_mux_recalced_data: represent a pin iomux data.
 * @num: bank number.
 * @pin: pin number.
 * @bit: index at register.
 * @reg: register offset.
 * @mask: mask bit
 */
struct rockchip_mux_recalced_data {
	u8 num;
	u8 pin;
	u32 reg;
	u8 bit;
	u8 mask;
};

enum rockchip_mux_route_location {
	ROCKCHIP_ROUTE_SAME = 0,
	ROCKCHIP_ROUTE_PMU,
	ROCKCHIP_ROUTE_GRF,
};

/**
 * struct rockchip_mux_recalced_data: represent a pin iomux data.
 * @bank_num: bank number.
 * @pin: index at register or used to calc index.
 * @func: the min pin.
 * @route_location: the mux route location (same, pmu, grf).
 * @route_offset: the max pin.
 * @route_val: the register offset.
 */
struct rockchip_mux_route_data {
	u8 bank_num;
	u8 pin;
	u8 func;
	enum rockchip_mux_route_location route_location;
	u32 route_offset;
	u32 route_val;
};

struct rockchip_pin_ctrl {
	struct rockchip_pin_bank	*pin_banks;
	u32				nr_banks;
	u32				nr_pins;
	char				*label;
	enum rockchip_pinctrl_type	type;
	int				grf_mux_offset;
	int				pmu_mux_offset;
	int				grf_drv_offset;
	int				pmu_drv_offset;
	struct rockchip_mux_recalced_data *iomux_recalced;
	u32				niomux_recalced;
	struct rockchip_mux_route_data *iomux_routes;
	u32				niomux_routes;

	int	(*pull_calc_reg)(struct rockchip_pin_bank *bank,
				    int pin_num, struct regmap **regmap,
				    int *reg, u8 *bit);
	int	(*drv_calc_reg)(struct rockchip_pin_bank *bank,
				    int pin_num, struct regmap **regmap,
				    int *reg, u8 *bit);
	int	(*schmitt_calc_reg)(struct rockchip_pin_bank *bank,
				    int pin_num, struct regmap **regmap,
				    int *reg, u8 *bit);
};

struct rockchip_pin_config {
	unsigned int		func;
	unsigned long		*configs;
	unsigned int		nconfigs;
};

enum pin_config_param;

struct rockchip_pin_deferred {
	struct list_head head;
	unsigned int pin;
	enum pin_config_param param;
	u32 arg;
};

/**
 * struct rockchip_pin_group: represent group of pins of a pinmux function.
 * @name: name of the pin group, used to lookup the group.
 * @pins: the pins included in this group.
 * @npins: number of pins included in this group.
 * @data: local pin configuration
 */
struct rockchip_pin_group {
	const char			*name;
	unsigned int			npins;
	unsigned int			*pins;
	struct rockchip_pin_config	*data;
};

/**
 * struct rockchip_pmx_func: represent a pin function.
 * @name: name of the pin function, used to lookup the function.
 * @groups: one or more names of pin groups that provide this function.
 * @ngroups: number of groups included in @groups.
 */
struct rockchip_pmx_func {
	const char		*name;
	const char		**groups;
	u8			ngroups;
};

struct rockchip_pinctrl {
	struct regmap			*regmap_base;
	int				reg_size;
	struct regmap			*regmap_pull;
	struct regmap			*regmap_pmu;
	struct regmap			*regmap_ioc1;
	struct device			*dev;
	struct rockchip_pin_ctrl	*ctrl;
	struct pinctrl_desc		pctl;
	struct pinctrl_dev		*pctl_dev;
	struct rockchip_pin_group	*groups;
	unsigned int			ngroups;
	struct rockchip_pmx_func	*functions;
	unsigned int			nfunctions;
};

#endif
