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