xref: /linux/drivers/pinctrl/sophgo/pinctrl-cv18xx.h (revision a29d8e93e710e97863d5bb4e4b6079d6c7daab81)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2024 Inochi Amaoto <inochiama@outlook.com>
4  */
5 
6 #ifndef _PINCTRL_SOPHGO_CV18XX_H
7 #define _PINCTRL_SOPHGO_CV18XX_H
8 
9 #include <linux/bits.h>
10 #include <linux/bitfield.h>
11 #include <linux/device.h>
12 #include <linux/mutex.h>
13 #include <linux/spinlock.h>
14 #include <linux/platform_device.h>
15 #include <linux/pinctrl/pinctrl.h>
16 #include <linux/pinctrl/pinconf.h>
17 
18 enum cv1800_pin_io_type {
19 	IO_TYPE_1V8_ONLY = 0,
20 	IO_TYPE_1V8_OR_3V3 = 1,
21 	IO_TYPE_AUDIO = 2,
22 	IO_TYPE_ETH = 3
23 };
24 
25 #define CV1800_PINCONF_AREA_SYS		0
26 #define CV1800_PINCONF_AREA_RTC		1
27 
28 struct cv1800_pinmux {
29 	u16	offset;
30 	u8	area;
31 	u8	max;
32 };
33 
34 struct cv1800_pinmux2 {
35 	u16	offset;
36 	u8	area;
37 	u8	max;
38 	u8	pfunc;
39 };
40 
41 struct cv1800_pinconf {
42 	u16	offset;
43 	u8	area;
44 };
45 
46 #define	CV1800_PIN_HAVE_MUX2		BIT(0)
47 #define CV1800_PIN_IO_TYPE		GENMASK(2, 1)
48 
49 #define CV1800_PIN_FLAG_IO_TYPE(type)		\
50 	FIELD_PREP_CONST(CV1800_PIN_IO_TYPE, type)
51 struct cv1800_pin {
52 	u16				pin;
53 	u16				flags;
54 	u8				power_domain;
55 	struct cv1800_pinmux		mux;
56 	struct cv1800_pinmux2		mux2;
57 	struct cv1800_pinconf		conf;
58 };
59 
60 #define PIN_POWER_STATE_1V8		1800
61 #define PIN_POWER_STATE_3V3		3300
62 
63 /**
64  * struct cv1800_vddio_cfg_ops - pin vddio operations
65  *
66  * @get_pull_up: get resistor for pull up;
67  * @get_pull_down: get resistor for pull down.
68  * @get_oc_map: get mapping for typical low level output current value to
69  *	register value map.
70  * @get_schmitt_map: get mapping for register value to typical schmitt
71  *	threshold.
72  */
73 struct cv1800_vddio_cfg_ops {
74 	int (*get_pull_up)(struct cv1800_pin *pin, const u32 *psmap);
75 	int (*get_pull_down)(struct cv1800_pin *pin, const u32 *psmap);
76 	int (*get_oc_map)(struct cv1800_pin *pin, const u32 *psmap,
77 			  const u32 **map);
78 	int (*get_schmitt_map)(struct cv1800_pin *pin, const u32 *psmap,
79 			       const u32 **map);
80 };
81 
82 struct cv1800_pinctrl_data {
83 	const struct pinctrl_pin_desc		*pins;
84 	const struct cv1800_pin			*pindata;
85 	const char				* const *pdnames;
86 	const struct cv1800_vddio_cfg_ops	*vddio_ops;
87 	u16					npins;
88 	u16					npd;
89 };
90 
91 static inline enum cv1800_pin_io_type cv1800_pin_io_type(struct cv1800_pin *pin)
92 {
93 	return FIELD_GET(CV1800_PIN_IO_TYPE, pin->flags);
94 };
95 
96 int cv1800_pinctrl_probe(struct platform_device *pdev);
97 
98 #define CV1800_FUNC_PIN(_id, _power_domain, _type,			\
99 			_mux_area, _mux_offset, _mux_func_max)		\
100 	{								\
101 		.pin = (_id),						\
102 		.power_domain = (_power_domain),			\
103 		.flags = CV1800_PIN_FLAG_IO_TYPE(_type),		\
104 		.mux = {						\
105 			.area = (_mux_area),				\
106 			.offset = (_mux_offset),			\
107 			.max = (_mux_func_max),				\
108 		},							\
109 	}
110 
111 #define CV1800_GENERAL_PIN(_id, _power_domain, _type,			\
112 			   _mux_area, _mux_offset, _mux_func_max,	\
113 			   _conf_area, _conf_offset)			\
114 	{								\
115 		.pin = (_id),						\
116 		.power_domain = (_power_domain),			\
117 		.flags = CV1800_PIN_FLAG_IO_TYPE(_type),		\
118 		.mux = {						\
119 			.area = (_mux_area),				\
120 			.offset = (_mux_offset),			\
121 			.max = (_mux_func_max),				\
122 		},							\
123 		.conf = {						\
124 			.area = (_conf_area),				\
125 			.offset = (_conf_offset),			\
126 		},							\
127 	}
128 
129 #define CV1800_GENERATE_PIN_MUX2(_id, _power_domain, _type,		\
130 				 _mux_area, _mux_offset, _mux_func_max,	\
131 				 _mux2_area, _mux2_offset,		\
132 				 _mux2_func_max,			\
133 				 _conf_area, _conf_offset)		\
134 	{								\
135 		.pin = (_id),						\
136 		.power_domain = (_power_domain),			\
137 		.flags = CV1800_PIN_FLAG_IO_TYPE(_type) |		\
138 				CV1800_PIN_HAVE_MUX2,			\
139 		.mux = {						\
140 			.area = (_mux_area),				\
141 			.offset = (_mux_offset),			\
142 			.max = (_mux_func_max),				\
143 		},							\
144 		.mux2 = {						\
145 			.area = (_mux2_area),				\
146 			.offset = (_mux2_offset),			\
147 			.max = (_mux2_func_max),			\
148 		},							\
149 		.conf = {						\
150 			.area = (_conf_area),				\
151 			.offset = (_conf_offset),			\
152 		},							\
153 	}
154 
155 #endif
156