aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
blob: 1b7da42aa1d53e4cfd5b7eefadd1f8b2ee13abea (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
/* 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 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)

/* 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_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[] = {
	"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_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;

	/* 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 (*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;
};

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_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_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);

#endif /* __PINCTRL_MTK_COMMON_V2_H */