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/mutex.h>
12 #include <linux/spinlock.h>
13 #include <linux/platform_device.h>
14 #include <linux/pinctrl/pinctrl.h>
15 #include <linux/pinctrl/pinconf.h>
16 
17 #include "pinctrl-sophgo.h"
18 
19 enum cv1800_pin_io_type {
20 	IO_TYPE_1V8_ONLY = 0,
21 	IO_TYPE_1V8_OR_3V3 = 1,
22 	IO_TYPE_AUDIO = 2,
23 	IO_TYPE_ETH = 3
24 };
25 
26 #define CV1800_PINCONF_AREA_SYS		0
27 #define CV1800_PINCONF_AREA_RTC		1
28 
29 struct cv1800_pinmux {
30 	u16	offset;
31 	u8	area;
32 	u8	max;
33 };
34 
35 struct cv1800_pinmux2 {
36 	u16	offset;
37 	u8	area;
38 	u8	max;
39 	u8	pfunc;
40 };
41 
42 struct cv1800_pinconf {
43 	u16	offset;
44 	u8	area;
45 };
46 
47 #define	CV1800_PIN_HAVE_MUX2		BIT(0)
48 #define CV1800_PIN_IO_TYPE		GENMASK(2, 1)
49 
50 #define CV1800_PIN_FLAG_IO_TYPE(type)		\
51 	FIELD_PREP_CONST(CV1800_PIN_IO_TYPE, type)
52 struct cv1800_pin {
53 	struct sophgo_pin		pin;
54 	u8				power_domain;
55 	struct cv1800_pinmux		mux;
56 	struct cv1800_pinmux2		mux2;
57 	struct cv1800_pinconf		conf;
58 };
59 
60 #define sophgo_to_cv1800_pin(_pin)		\
61 	container_of((_pin), struct cv1800_pin, pin)
62 
63 #define PIN_POWER_STATE_1V8		1800
64 #define PIN_POWER_STATE_3V3		3300
65 
cv1800_pin_io_type(const struct cv1800_pin * pin)66 static inline enum cv1800_pin_io_type cv1800_pin_io_type(const struct cv1800_pin *pin)
67 {
68 	return FIELD_GET(CV1800_PIN_IO_TYPE, pin->pin.flags);
69 };
70 
71 extern const struct pinctrl_ops cv1800_pctrl_ops;
72 extern const struct pinmux_ops cv1800_pmx_ops;
73 extern const struct pinconf_ops cv1800_pconf_ops;
74 extern const struct sophgo_cfg_ops cv1800_cfg_ops;
75 
76 #define CV1800_FUNC_PIN(_id, _power_domain, _type,			\
77 			_mux_area, _mux_offset, _mux_func_max)		\
78 	{								\
79 		.pin = {						\
80 			.id = (_id),					\
81 			.flags = CV1800_PIN_FLAG_IO_TYPE(_type),	\
82 		},							\
83 		.power_domain = (_power_domain),			\
84 		.mux = {						\
85 			.area = (_mux_area),				\
86 			.offset = (_mux_offset),			\
87 			.max = (_mux_func_max),				\
88 		},							\
89 	}
90 
91 #define CV1800_GENERAL_PIN(_id, _power_domain, _type,			\
92 			   _mux_area, _mux_offset, _mux_func_max,	\
93 			   _conf_area, _conf_offset)			\
94 	{								\
95 		.pin = {						\
96 			.id = (_id),					\
97 			.flags = CV1800_PIN_FLAG_IO_TYPE(_type),	\
98 		},							\
99 		.power_domain = (_power_domain),			\
100 		.mux = {						\
101 			.area = (_mux_area),				\
102 			.offset = (_mux_offset),			\
103 			.max = (_mux_func_max),				\
104 		},							\
105 		.conf = {						\
106 			.area = (_conf_area),				\
107 			.offset = (_conf_offset),			\
108 		},							\
109 	}
110 
111 #define CV1800_GENERATE_PIN_MUX2(_id, _power_domain, _type,		\
112 				 _mux_area, _mux_offset, _mux_func_max,	\
113 				 _mux2_area, _mux2_offset,		\
114 				 _mux2_func_max,			\
115 				 _conf_area, _conf_offset)		\
116 	{								\
117 		.pin = {						\
118 			.id = (_id),					\
119 			.flags = CV1800_PIN_FLAG_IO_TYPE(_type) |	\
120 				 CV1800_PIN_HAVE_MUX2,			\
121 		},							\
122 		.power_domain = (_power_domain),			\
123 		.mux = {						\
124 			.area = (_mux_area),				\
125 			.offset = (_mux_offset),			\
126 			.max = (_mux_func_max),				\
127 		},							\
128 		.mux2 = {						\
129 			.area = (_mux2_area),				\
130 			.offset = (_mux2_offset),			\
131 			.max = (_mux2_func_max),			\
132 		},							\
133 		.conf = {						\
134 			.area = (_conf_area),				\
135 			.offset = (_conf_offset),			\
136 		},							\
137 	}
138 
139 #endif
140